I'm creating a linkButton Dynamically on ASP.net. I need help on when I click the linkButton, it will store the linkbutton name to my Label1 (for example only).
Here is the code:
protected void Page_Load(object sender, EventArgs e)
{
for (int ctr = 0; ctr <= 2; ctr++)
{
LinkButton link = new LinkButton();
link.ID = "lnk" + ctr.ToString();
link.Text = "lnkName" + ctr.ToString();
link.Click += new EventHandler(DynamicClick);
this.form1.Controls.Add(link);
}
}
//when I click the buttonLink
public void DynamicClick(object sender, EventArgs e)
{
//label1.text will get the .text of the button that i pressed
Label1.Text = "";
}
I would do it in that way
public void DynamicClick(object sender, EventArgs e)
{
LinkButton linkButton = sender as LinkButton;
if (linkButton != null)
{
Label1.Text = linkButton.Text;
}
}
protected void Page_Load(object sender, EventArgs e)
{
for (int ctr = 0; ctr <= 2; ctr++)
{
LinkButton link = new LinkButton();
link.ID = "lnk" + ctr.ToString();
link.Text = "lnkName" + ctr.ToString();
link.Click += delegate { Label1.Text = link.ID; };
this.form1.Controls.Add(link);
}
}
I would do this with a slight variation to Valeh's answer.
protected void Page_Load(object sender, EventArgs e)
{
for (int ctr = 0; ctr <= 2; ctr++)
{
LinkButton link = new LinkButton();
link.ID = "lnk" + ctr.ToString();
link.Text = "lnkName" + ctr.ToString();
link.Click += (s, ea) =>
{
Label1.Text = link.Text;
};
this.form1.Controls.Add(link);
}
}
Creating a separate method public void DynamicClick(object sender, EventArgs e) - especially one that is public - is a bad thing when it is not necessary as it breaks encapsulation. It's perfectly understandable to do so when we're working with a designer, but when we're writing the code ourselves it's a bad idea.
Related
I have a scenario. following is the code:
Home.aspx.cs
protected void Button1_Click(object sender, EventArgs e)
{
try
{
if (!String.IsNullOrEmpty(txtbox_query.Text.Trim()))
{
if (isTrue)
{
// To do statements
}
else
{
List<RequestAndResponse.Parameter> parameters = request.getParameter(txtbox_query.Text.Trim(), sourcePath, parameterValue);
Session["Data"] = parameters;
Response.Redirect("Result.aspx",false);
}
}
}
catch (Exception error)
{
Response.Write(error.Message);
}
}
Result.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
parameters = (List<RequestAndResponse.Parameter>)Session["Data"];
ContentPlaceHolder content = (ContentPlaceHolder)this.Form.FindControl("MainContent");
for (int j = 1; j <= _arrViewState; j++)
{
string _id = j.ToString();
TextBox txtfname = new TextBox();
txtfname.ID = "TextBox_" + _id + "_";
txtfname.Width = 160;
txtfname.Text = parameters[(j - 1)].Value.ToUpper();
txtfname.Attributes.Add("style", "color:#015D84;font-weight:bold;font-size:12px;padding:10px;");
txtfname.EnableViewState = true;
content.Controls.Add(txtfname);
content.Controls.Add(new LiteralControl("<br/>"));
}
Button btnSubmit = new Button();
btnSubmit.ID = "btnSubmit";
btnSubmit.Text = "Submit";
btnSubmit.Click += new System.EventHandler(btnSubmit_click);
btnSubmit.Enabled = false;
content.Controls.Add(btnSubmit);
}
protected void btnSubmit_click(object sender, EventArgs e)
{
// How to find the dynamically created textbox
}
Now How to find the dynamically created controls
I know the basic like:
Form.FindControl("TextBox ID");
But here i dont know the textbox id and also i even dont know how many textbox will be their as it totally depends on user input i.e. from 2 TO N textboxes
What i want is on bttn_Click i will fetch the text from all the textboxes
How will i achieve this.
Also i want to check if all Textbox is empty or not on bttn_Click
Enumerate controls as follows
protected void btnSubmit_click(object sender, EventArgs e)
{
ContentPlaceHolder content = (ContentPlaceHolder)this.Form.FindControl("MainContent");
foreach (Control c in content.Controls)
{
if (c is TextBox)
{
TextBox txt = (TextBox)c;
// do something, e.g. Response.Write(txt.Text);
}
}
}
private void button1_Click(object sender, EventArgs e)
{
string a = textBox1.Text;
int h = Convert.ToInt32(a);
for (int i = 0; i <= h; i++)
{
buttonArray[i] = new Button();
buttonArray[i].Size = new Size(60, 23);
buttonArray[i].Location = new Point(40,20);
panel1.Controls.Add(buttonArray[i]);
}
}
my task is if user enter 3 in text box. 3 buttons should be created dynamically and added to panel how to do that?????? i am using button array please suggest me
For example you can use this.
private void button1_Click(object sender, EventArgs e)
{
panel1.Controls.Clear();
string a = textBox1.Text;
int h = Convert.ToInt32(a);
for (int i = 0; i <= h; i++)
{
var btn = new Button {Size = new Size(60, 23), Dock=DockStyle.Left, Text=h.ToString() };
btn.Click+= delegate(object sender, EventArgs e) { //your commands };
panel1.Controls.Add(btn);
}
}
In this post already answered a similar question:
private void button1_Click(object sender, EventArgs e)
{
string a = textBox1.Text;
int h = Convert.ToInt32(a);
for (int i = 0; i <= h; i++)
{
var b = new Button { Size = new Size(60, 23), Location = new Point(4 + i * 57, 20), Text = string.Format("button{0}", i) };
b.Click += b_Click;
panel1.Controls.Add(b);
}
}
void b_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
it is desirable to test the validator to always have been a number
string a = textBox1.Text;
May be using a List is more situable?
List<Button>Buttons=new List<Buttons>();
private void button1_Click(object sender, EventArgs e)
{
Buttons.Clear();
string a = textBox1.Text;
//here should be checking if "a" is digit and is not empty
int h = Convert.ToInt32(a);
for (int i = 0; i <= h; i++)
{
Button btn=new Button();
btn.Parent=panel1;
btn.Size=new Size(60, 23);
btn.Location = new Point(40,5+25*i); //arrange verically
btn.Text = "Button "+i.ToString();
btn.Click+=btn_Click;
btn.Tag="Some Value you want to restore after button click";
Buttons.Add(btn)
}
}
I want to add buttons to my page dynamically. It will depend on the number of results from a SELECT statement. I
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
for (int i = 0; i < Query.length; i++)
{
Button btn = new Button();
btn.ID = "Button" + i;
btn.Click += new EventHandler(btn_Click());
btn.Text = i.ToString();
pagingPanel.Controls.Add(btn);
}
}
}
But I want each button to have it's own custom event handler. If I click one button, I want it do have a different result than if I click another. I would like to do something like this where I can pass an aditional parameter:
protected void btn_Click(object sender, EventArgs e, string test)
{
System.Diagnostics.Debug.WriteLine(test);
}
Perhaps I don't know which objects to pass? Or maybe I am approaching this the wrong way.
How do I achieve the desired results?
Try this:
protected void Page_Load(object sender, EventArgs e)
{
// you do not use !IsPostBack here
//count of func must be equal with 'Query.Length'
string[,] arr ={
{"func1","hello world"},
{"func2","Hello ASP.NET"}
};
for (int i = 0; i < Query.Length; i++)//I assume length is 2
{
Button btn = new Button();
btn.ID = arr[i, 0];
btn.CommandArgument = arr[i, 1];
btn.Click += new EventHandler(btn_Click);
btn.Text = i.ToString();
pagingPanel.Controls.Add(btn);
}
}
protected void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
System.Reflection.MethodInfo methodInfo = typeof(_Default2).GetMethod(btn.ID); //_Default2 is class name of code behind
if (methodInfo != null)
{
object[] parameters = new object[] { btn.CommandArgument};
methodInfo.Invoke(this,parameters);
}
}
public void func1(object args)
{
string test = args.ToString();
Response.Write(test);
}
public void func2(object args)
{
string test = args.ToString();
Response.Write(test);
}
First and foremost - you have to create buttons whether it is postback or not. The button click is the reason for the postback, if you don't have buttons - what will be clicking?
Second, add to your page class:
Dictionary<Button, ButtonInfo> fButtonLookup = new Dictionary<Button, ButtonInfo>();
Then, where you create buttons:
fButtonLookup.Clear();
for (int i = 0; i < Query.length; i++)
{
Button btn = new Button();
fButtonLookup.Add(btn, new ButtonInfo() { whatever information about this button you want to keep});
...
}
Then, in your button click:
protected void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
if (fButtonLookup.ContainsKey(btn))
{
ButtonInfo info = fButtonLookup[btn];
// do waht you need with button information
}
}
You could just check sender to see which button was clicked:
protected void btn_Click(object sender, EventArgs e)
{
if (sender == btnOne)
performBtnOne("foo");
else if (sender == btnTwo)
performButtonTwo("bar");
}
To expand on itsme86...
protected void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender; //Now you have an instantiated version of the button pressed.
switch (btn.Name)
{
case "foo":
performBtnOne();
break;
case "bar":
performBtnTwo();
break;
default:
performUnexpectedButton();
break;
}
}
How can I get the name of the object last clicked on a panel? The trick is there is a big array of buttons on the panel (btn[1] ... btn [200]). How can I check if I clicked on button b[180], or b[11] or even outside the panel (no button)? Also the buttons are generated at page load via coding.
Thank you. Anna
EDIT:
Thank you! Another issue that arose (this generated a NULL object reference):
I have a method on the same level as buttonHandler(), it is named HowManyClicked() and it's called from within buttonHandler(). Inside HowManyClicked() I want to identify Button btn1 = Panel2.FindControl(x) as Button; where x is, for example, buttonArray[2,3]. But I always get NULL. Is the button array buttonArray not identifiable by name once out of the method that generated it??
public void buttonHandler(object sender, EventArgs e)
{
Button btn = sender as Button;
//string tt = btn.ToolTip.ToString();
btn.BackColor = Color.Red;
statusL.Text = HowManyClicked().ToString();
}
public int HowManyClicked()
{
int sum=0;
for (int a = 0; a < 10; a++)
for (int b = 0; b < 14; b++)
{
string x = "buttonArray[" + a + ", " + b + "]";
statusL.Text = x;
Button btn1 = Panel2.FindControl(x) as Button;
if (btn1.BackColor == Color.Red) sum += 1;
}
return sum;
}
As #AVD commented you can get the button originating the postback casting the sender object, you can also use the CommandName and CommandArgument properties from the button object (they are usually used when the button is inside a Grid, DataList etc but you can use them in this context if you need):
protected void Page_Init(object sender, EventArgs e)
{
var s = Enumerable.Range(1, 10);
foreach (var item in s)
{
var b = new Button();
b.Text = "My Button " + item.ToString();
b.CommandName = "custom command";
b.CommandArgument = item.ToString();
b.Click += new EventHandler(b_Click);
this.myPanel.Controls.Add(b);
}
}
void b_Click(object sender, EventArgs e)
{
var current = sender as Button;
this.lblMessage2.Text = "Clicked from array buttons: <br/>Command Name: " + current.CommandName + "<br/>Args: " + current.CommandArgument + "<br/>Button Unique ID: " + current.UniqueID + "<br/>Client ID: " + current.ClientID;
}
Page:
<asp:Panel runat="server" ID="myPanel">
</asp:Panel>
<asp:Label ID="lblMessage2" runat="server" />
This code generates something like:
As an additional note, Microsoft recommends to create dynamic controls in the PreInit event or in case you are using a master page, in the Init event
source
Edited
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.ViewState["count"] = 0;
}
}
protected void Page_Init(object sender, EventArgs e)
{
var s = Enumerable.Range(1, 10);
foreach (var item in s)
{
var b = new Button();
b.Text = "My Button " + item.ToString();
b.Click += new EventHandler(buttonHandler);
this.myPanel.Controls.Add(b);
}
}
void buttonHandler(object sender, EventArgs e)
{
// update here your control
var b = sender as Button;
b.BackColor = Color.Red;
HowManyClicked();
}
private void HowManyClicked()
{
var c = (int)this.ViewState["count"];
c++;
this.ViewState["count"] = c;
this.lblMessage2.Text = "Clicked controls: " + this.ViewState["count"].ToString();
}
This produced:
How can I get the name of the object last clicked on a panel?
The first parameter of click handler returns the reference of control/object has raised the event.
public void buttonHandler(object sender, EventArgs e)
{
Button btn=sender as Button;
....
}
I just figured out another fix by just redefining HowManyClicked() so I am adding it here below. Not sure still why the first method (the one in my question) didn't work also. Here goes:
public int HowManyClicked()
{
int sum=0;
foreach (Control cnt in this.Panel2.Controls)
if (cnt is Button)
{
Button btn = (Button)cnt;
if (btn.BackColor == Color.Red)
sum += 1;
}
return sum;
}
}
Thanks everyone!
my method is :
private void button1_Click(object sender, EventArgs e)
{
for (int i = 1; i < 10; i++)
{
Button btn = new Button();
btn.Name = "btn" + i.ToString();
btn.Text = "btn" + i.ToString();
btn.Click += new EventHandler(this.btn_Click);
this.flowLayoutPanel1.Controls.Add(btn);
}
}
void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
if (btn.Name == "btn1")
{
this.Text = "stack";
}
}
There is a better approach ?
The code you used:
btn.Click += new EventHandler(this.btn_Click);
Is the correct code to add the handler. Creating the buttons and adding them to their container looks good.
The only thing I would add is just make sure you are creating the controls on postback too, prior to viewstate being restored, so that the events can actually be called.
Or maybe:
private void button1_Click(object sender, EventArgs e)
{
for (int i = 1; i < 10; i++)
{
Button btn = new Button();
btn.Text = "btn" + i.ToString();
btn.Tag = i;
btn.Click += delegate
{
if ((int)btn.Tag == 1)
this.Text = "stack";
};
this.flowLayoutPanel1.Controls.Add(btn);
}
}