I have a gridview in which textbox is generated dynamically on RowDataBound event.I want to generate 3 more textbox below gridview on button click.
Here is my gridview
Here is my code behind:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
string s = Session["num"].ToString();
int num = Int32.Parse(s);
if (e.Row.RowType == DataControlRowType.DataRow)
{
for (int i = 0; i <num; i++)
{
TextBox txt = new TextBox();
txt.Height = 25;
txt.Width = 150;
txt.Font.Size = 10;
txt.ID = "txt" + i;
txt.Text = e.Row.Cells[i].Text.Replace(" ", "");
e.Row.Cells[i].Controls.Add(txt);
}
}
}
Not sure what your exact problem is, but this Link might help you. Anyway, you can simply generate TextBox dynamically using Button Click Event.
The example shown below generates three TextBox Control on a Click Event:
TextBox txt;
static int i = 0;
protected void Button1_Click(object sender, EventArgs e)
{
if(i%2==0)
{
for (int j = 0; j < 3; j++)
{
txt= new TextBox();
txt.Height = 25;
txt.Width = 150;
txt.Font.Size = 10;
txt.ID = j.ToString();
PlaceHolder1.Controls.Add(txt);
}
}
i++;
}
Note: When you dynamically add controls to an ASP.NET page at runtime the object references are lost at postback because they have no object reference variable in the codebehind.
Related
I have created Label controls dynamically on button click:
protected void createDynamicLabels_Click(object sender, EventArgs e)
{
int n = 5;
for (int i = 0; i < n; i++)
{
Label MyLabel = new Label();
MyLabel.ID = "lb" + i.ToString();
MyLabel.Text = "Labell: " + i.ToString();
MyLabel.Style["Clear"] = "Both";
MyLabel.Style["Float"] = "Left";
MyLabel.Style["margin-left"] = "100px";
Panel1.Controls.Add(MyLabel);
}
}
When I tried to read back fro another button I see Label Control returned null
Label str = (Label)Panel1.FindControl("lb" + i.ToString());
not sure what went wrong here
protected void bReadDynValue_Click(object sender, EventArgs e)
{
int n = 5;
for (int i = 0; i < n; i++)
{
Label str = (Label)Panel1.FindControl("lb" + i.ToString());
lbGetText.Text = str.Text;
}
}
this is the issue of every time page load event. ASP.net fire every time page load event when any button is click.
suppose in this example..
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
createDynamicLabels();
}
private void createDynamicLabels()
{
int n = 5;
for (int i = 0; i < n; i++)
{
Label MyLabel = new Label();
MyLabel.ID = "lb" + i.ToString();
MyLabel.Text = "Labell: " + i.ToString();
MyLabel.Style["Clear"] = "Both";
MyLabel.Style["Float"] = "Left";
MyLabel.Style["margin-left"] = "100px";
Panel1.Controls.Add(MyLabel);
}
}
protected void bReadDynValue_Click(object sender, EventArgs e)
{
int n = 5;
for (int i = 0; i < n; i++)
{
Label str = (Label)Panel1.FindControl("lb" + i.ToString());
lbGetText.Text = str.Text;
}
}
when Button trigger Page doesn't have any label because it is made on runtime. and Page doesn't find particular label. if you tried above code it is run properly.
protected void Page_Load(object sender, EventArgs e)
{
createDynamicLabels();
}
private void createDynamicLabels()
{
int n = 5;
for (int i = 0; i < n; i++)
{
Label MyLabel = new Label();
MyLabel.ID = "lb" + i.ToString();
MyLabel.Text = "Labell: " + i.ToString();
MyLabel.Style["Clear"] = "Both";
MyLabel.Style["Float"] = "Left";
MyLabel.Style["margin-left"] = "100px";
Panel1.Controls.Add(MyLabel);
}
}
protected void bReadDynValue_Click(object sender, EventArgs e)
{
int n = 5;
for (int i = 0; i < n; i++)
{
Label str = (Label)Panel1.FindControl("lb" + i.ToString());
lbGetText.Text = str.Text;
}
}
in this Example code find label every time because every time it can make labels for this page.
Dynamically created labels exists only until the next postback occurs. When you click on another button to retrieve their values a postback occurs and values become null.
For saving labels state after postback you have to use some hidden field.
If the text / value of the labes does not change it is enough to generate them on every postback (as mck already mentioned). If you need to retrieve changes made on the client side, you should create the controls in the OnInit event instead of the PageLoad and use inputs / texboxes instead of labels.
Another option (which I would recommend) would be to use a asp:Repeater to generate the Labels.
NET 4.5 C# to create a windows form. I want to dynamically create & add buttons & also assign them click events but want them to be dynamically placed in a particular fashion just like the image.
My question is how do I place the buttons dynamically in the above fashion i.e. 4x4 format (4 buttons in a row, 4 columns but unlimited rows). Is it possible to do so in win forms?
Presently I'm trying the below mentioned code but have no clear idea as to how I can place the buttons as shown above.
public Form1()
{
InitializeComponent();
for (int i = 0; i < 5; i++)
{
Button button = new Button();
button.Location = new Point(160, 30 * i + 10);
button.Click += new EventHandler(ButtonClickCommonEvent);
button.Tag = i;
this.Controls.Add(button);
}
}
void ButtonClickCommonEvent(object sender, EventArgs e)
{
Button button = sender as Button;
if (button != null)
{
switch ((int)button.Tag)
{
case 0:
// First Button Clicked
break;
case 1:
// Second Button Clicked
break;
// ...
}
}
}
Please advise solution with codes.
You can use a TableLayoutPanel and create your buttons dynamically and add them to the panel.
For example:
private void Form1_Load(object sender, EventArgs e)
{
var rowCount = 3;
var columnCount = 4;
this.tableLayoutPanel1.ColumnCount = columnCount;
this.tableLayoutPanel1.RowCount = rowCount;
this.tableLayoutPanel1.ColumnStyles.Clear();
this.tableLayoutPanel1.RowStyles.Clear();
for (int i = 0; i < columnCount; i++)
{
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100 / columnCount));
}
for (int i = 0; i < rowCount; i++)
{
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100 / rowCount));
}
for (int i = 0; i < rowCount* columnCount; i++)
{
var b = new Button();
b.Text = (i+1).ToString();
b.Name = string.Format("b_{0}", i + 1);
b.Click += b_Click;
b.Dock = DockStyle.Fill;
this.tableLayoutPanel1.Controls.Add(b);
}
}
void b_Click(object sender, EventArgs e)
{
var b = sender as Button;
if (b != null)
MessageBox.Show(string.Format("{0} Clicked", b.Text));
}
Note:
Using TableLayoutPanel.Controls.Add(control) we can add controls sequentially to the panel.
Using TableLayoutPanel.Controls.Add(control, columnIndex, rowIndex) we can add controls at specific cells.
I have a problem. I'm trying to make some panels, and in these panels I would like to have some linkbuttons, when the user click a linkbutton of a panel a textbox will appear in that panel, when I click in another linkbutton the textboxes of that panel also appear without problem but when I click in the other linkbutton the texboxes created in the previous panel disappears.
Here is my code:
public partial class _Default : Page
{
Label myLabel1;
Label myLabel2;
protected void Page_Load(object sender, EventArgs e)
{
myLabel1 = new Label();
myLabel2 = new Label();
Panel1.Controls.Add(myLabel1);
Panel2.Controls.Add(myLabel2);
if (!Page.IsPostBack)
{
//Remove the session when first time page loads.
Session.Remove("clicks");
Session.Remove("clicks2");
}
}
protected void LinkButton1_Click(object sender, EventArgs e)
{
int rowCount = 0;
//initialize a session.
rowCount = Convert.ToInt32(Session["clicks"]);
rowCount++;
//In each button clic save the numbers into the session.
Session["clicks"] = rowCount;
//Create the textboxes and labels each time the button is clicked.
for (int i = 0; i < rowCount; i++)
{
TextBox TxtBoxU = new TextBox();
TxtBoxU.ID = "TextBoxU" + i.ToString();
//Add the labels and textboxes to the Panel.
Panel1.Controls.Add(TxtBoxU);
}
myLabel1.Text = rowCount + "";
}
protected void LinkButton2_Click(object sender, EventArgs e)
{
int rowCount2 = 0;
//initialize a session.
rowCount2 = Convert.ToInt32(Session["clicks2"]);
rowCount2++;
//In each button clic save the numbers into the session.
Session["clicks2"] = rowCount2;
//Create the textboxes and labels each time the button is clicked.
for (int i = 0; i < rowCount2; i++)
{
TextBox TxtBoxU = new TextBox();
TxtBoxU.ID = "TextBoxU" + i.ToString();
//Add the labels and textboxes to the Panel.
Panel2.Controls.Add(TxtBoxU);
}
myLabel2.Text = rowCount2 + "";
}
}
And here is the other part:
<form id="form1" runat="server">
<p>
Part I</p>
<asp:Panel ID="Panel1" runat="server" Height="53px">
<asp:LinkButton ID="LinkButton1" runat="server" OnClick="LinkButton1_Click">Add to 1</asp:LinkButton>
<br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</asp:Panel>
<asp:Panel ID="Panel2" runat="server" Height="51px">
<asp:LinkButton ID="LinkButton2" runat="server" OnClick="LinkButton2_Click">Add to 2</asp:LinkButton>
<br />
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
</asp:Panel>
</form>
Since the text boxes are dynamically created, when the page loads everything needs to be re-built, but the code you posted only re-builds the text boxes for one of the panels when the particular link button for that panel is being clicked. However, your code is just building the one panel again, because that is all that your click event handlers for the link buttons are telling it to do.
I suggest combining the logic into a single method that does the building and then each link button click event handler can update its own count and pass it to the method, like this:
private void BuildTextBoxes(int rowCount1, int rowCount2)
{
for (int i = 0; i < rowCount; i++)
{
TextBox TxtBoxU = new TextBox();
TxtBoxU.ID = "TextBoxU" + i.ToString();
//Add the labels and textboxes to the Panel.
Panel1.Controls.Add(TxtBoxU);
}
myLabel1.Text = rowCount + "";
for (int i = 0; i < rowCount2; i++)
{
TextBox TxtBoxU = new TextBox();
TxtBoxU.ID = "TextBoxU" + i.ToString();
//Add the labels and textboxes to the Panel.
Panel2.Controls.Add(TxtBoxU);
}
myLabel2.Text = rowCount2 + "";
}
Now in your link button click event handlers, you will need to update the one count, but pass both to the method, like this:
protected void LinkButton1_Click(object sender, EventArgs e)
{
int rowCount = 0;
//initialize a session.
rowCount = Convert.ToInt32(Session["clicks"]);
rowCount++;
//In each button clic save the numbers into the session.
Session["clicks"] = rowCount;
BuildTextBoxes(rowCount, Convert.ToInt32(Session["clicks2"]));
}
protected void LinkButton2_Click(object sender, EventArgs e)
{
int rowCount2 = 0;
//initialize a session.
rowCount2 = Convert.ToInt32(Session["clicks2"]);
rowCount2++;
//In each button clic save the numbers into the session.
Session["clicks2"] = rowCount2;
BuildTextBoxes(Convert.ToInt32(Session["clicks1"]), rowCount2));
}
Now, whether you click the first or second link button, all of the text boxes will be recreated; with only the particular link button incrementing the number of rows.
When there is a post-back to the server following the click on the link an entirely new HTML page is generated and returned to the client. In the click event handler in your code you are adding additional controls to the ones in your aspx markup. These are then included in the HTML returned to the client. But the server is state-less and will not remember that you added these the next time there is a request from the client. You will need to add them again every time there is a post-back.
Maybe try to move your logic to add the text boxes into a separate method and then call it with the appropriate values in your click.
Something like this:
protected void LinkButton1_Click(object sender, EventArgs e)
{
int rowCount = Convert.ToInt32(Session["clicks"]) + 1;
Session["clicks"] = rowCount;
int rowCount2 = Convert.ToInt32(Session["clicks2"]) + 1;
Session["clicks2"] = rowCount2;
AddTextBoxes(rowCount, Panel1, myLabel1);
AddTextBoxes(rowCount2, Panel2, myLabel2);
}
protected void LinkButton2_Click(object sender, EventArgs e)
{
int rowCount = Convert.ToInt32(Session["clicks"]) + 1;
Session["clicks"] = rowCount;
int rowCount2 = Convert.ToInt32(Session["clicks2"]) + 1;
Session["clicks2"] = rowCount2;
AddTextBoxes(rowCount, Panel1, myLabel1);
AddTextBoxes(rowCount2, Panel2, myLabel2);
}
protected void AddTextBoxes(int numberToAdd, Panel panel, Label label)
{
//In each button clic save the numbers into the session.
numberToAdd = rowCount;
//Create the textboxes and labels each time the button is clicked.
for (int i = 0; i < rowCount; i++)
{
TextBox TxtBoxU = new TextBox();
TxtBoxU.ID = "TextBoxU" + i.ToString();
//Add the labels and textboxes to the Panel.
panel.Controls.Add(TxtBoxU);
}
label.Text = rowCount + "";
}
I created dynamically some textboxes. They are created after click on one button(number of the textboxes depends on the user).
protected void Button1_Click(object sender, EventArgs e)
{
int i = Convert.ToInt32(TextBox2.Text);
Table tbl = new Table();
tbl.Width = Unit.Percentage(80);
TableRow tr;
TableCell tc;
TextBox txt;
CheckBox cbk;
DropDownList ddl;
Label lbl;
Button btn;
for (int j = 1; j <= i; j++)
{
tr = new TableRow();
tc = new TableCell();
tc.Width = Unit.Percentage(25);
lbl = new Label();
lbl.Text = "Pitanje:";
tc.Controls.Add(lbl);
tr.Cells.Add(tc);
tc.Width = Unit.Percentage(25);
txt = new TextBox();
txt.ID = "txt_p_" + j;
tc.Controls.Add(txt);
tr.Cells.Add(tc);
tc.Width = Unit.Percentage(25);
lbl = new Label();
lbl.Text = "Odgovori:";
tc.Controls.Add(lbl);
tr.Cells.Add(tc);
tc.Width = Unit.Percentage(25);
txt = new TextBox();
txt.ID = "txt_o_" + j;
tc.Controls.Add(txt);
tr.Cells.Add(tc);
tbl.Rows.Add(tr);
}
Panel1.Controls.Add(tbl);
}
now I need to get the text that is typed into that textboxes. I tried with something that I found on the internet but can't get it to work.
protected void SpremiPitanja(object sender, EventArgs e)
{
int i = Convert.ToInt32(TextBox2.Text);
for (int j = 1; j <= i; j++)
{
***************************************
}
}
any kind of help is welcome. if you need more information I will give them
A variable declared in a function is only visible in a function. You need to store the TextBoxes in a variable, that exists even when the code in the function has "finished". For more information search for scopes.
Here is a small sample that stores TextBoxes in a List that is visible in your class.
Another option would be to use eventhandlers. It depends on your scenario, which solution would be suited better. If you store the TextBoxes in a List, you can easily perform clean up code (for instance remove EventHandlers if required). You can obviously combine Approach 1 and 2. In that case you would store the created TextBox in a List (or any other collection), but you would still use the sender in the eventhandler to get a reference to the sending TextBox.
public partial class Form1 : Form
{
List<TextBox> textBoxes = new List<TextBox>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//Approach 1: create and add textbox to list
TextBox createdTextbox = new TextBox();
textBoxes.Add(createdTextbox);
}
private void button2_Click(object sender, EventArgs e)
{
//use the textboxes from the list
foreach(TextBox t in textBoxes)
{
//do something with t
}
}
private void button3_Click(object sender, EventArgs e)
{
//Approach 2: use eventhandlers and don't store textbox in a list
TextBox createdTextbox = new TextBox();
createdTextbox.TextChanged += createdTextbox_TextChanged;
listBox1.Items.Add(createdTextbox);
}
void createdTextbox_TextChanged(object sender, EventArgs e)
{
TextBox t = sender as TextBox;
if (t == null)
throw new ArgumentException("sender not of type TextBox", "sender");
//do something with t
}
}
You add textboxes the same way you do, this is my example (sorry it's vb.net):
Dim t As New TextBox With {.ID = "txt_123", .Text = "Vpiši"}
PlaceHolder1.Controls.Add(t)
t = New TextBox With {.ID = "txt_456", .Text = "Briši"}
PlaceHolder1.Controls.Add(t)
And then you iterate through controls in Placeholder (in my example):
Dim tItem As TextBox
Dim tValue As String = String.Empty
For Each c As Control In PlaceHolder1.Controls
If TypeOf c Is TextBox Then
tItem = c
tValue = tItem.Text.ToString
End If
Next
C# example added
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
TextBox t = new TextBox();
t.Text = "Vpiši";
t.ID = "txt_123";
PlaceHolder1.Controls.Add(t);
t = new TextBox();
t.Text = "Briši";
t.ID = "txt_456";
PlaceHolder1.Controls.Add(t);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
TextBox tItem;
String tValue;
foreach (Control c in PlaceHolder1.Controls)
{
if (c.GetType() == typeof(TextBox))
{
tItem = (TextBox)c;
tValue = tItem.Text;
}
}
}
I created some TextBox dynamically using the code below and I entered some text in this TextBox. Now I want to read this control's ID while adding the text into a database. How can I get the ID of this TextBox on the click of a Button.
for (int i = 0; i < dv_count; i++)
{
TextBox txt_box = new TextBox();
txt_box.Text = "";
txt_box.ID = "s" + i;
placeholder1.Controls.Add(txt_box);
}
protected void btn_act_proceed_Click(object sender, EventArgs e)
{
int count = placeholder1.Controls.Count; //always return 0
if (count > 0)
{
int dv_count = count / 2;
for (int i = 0; i < dv_count; i++)
{
TextBox lbl_type = (TextBox )placeholder1.FindControl("s" + i);
}
}
}
Try this
In your Aspx Page
<div runat="server" id="plcholder">
</div>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
now in code behind
protected void Page_Load(object sender, EventArgs e)
{
populate();
}
public void populate()
{
for (int i = 0; i < 3; i++)
{
TextBox tb = new TextBox();
tb.ID = "s" + i;
tb.Text = "Hello" + i;
plcholder.Controls.Add(tb);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
int cont = plcholder.Controls.Count;
for (int i = 0; i < cont-1; i++)
{
TextBox tx = (TextBox)plcholder.FindControl("s" + i);
Response.Write(tx.Text);
}
}
Control will be lost during postback. So on preinit you need to create the controls again.
Or you can keep your controls in session and get it back from postback.
A good link http://www.codeproject.com/Articles/3684/Retaining-State-for-Dynamically-Created-Controls-i
http://www.codeproject.com/Articles/502251/How-to-create-controls-dynamically-in-ASP-NET-and
I don't see you adding controls to the placeholder in first place. try this
for (int i = 0; i < dv_count; i++)
{
TextBox txt_box = new TextBox();
txt_box.Text = "";
txt_box.ID = "s" + i;
placeholder1.Controls.Add(txt_box);
}
TextBox lbl_type = (TextBox)placeholder1.FindControl("s" + i);