How to handle Windows Forms controls created at runtime? - c#

I have a Form on which there are two controls, a Button and a TextBox.
These controls are created at runtime.
When I click the Button, I want to do some operations with the TextBox.Text property.
But, with this code I can't:
private void Form1_Load(object sender, EventArgs e)
{
TextBox txb = new TextBox();
this.Controls.Add(txb);
Button btn = new Button();
this.Controls.Add(btn);
btn.Click += new EventHandler(btn_Click);
}
Here I'm trying to find it:
public void btn_Click(object sender, EventArgs e)
{
foreach (var item in this.Controls)
{
if (item is TextBox)
{
if (((TextBox)item).Name=="txb")
{
MessageBox.Show("xxx");
}
}
}
}

You don't have a Textbox with Name "txb". so, this expression will always be false: if(((TextBox)item).Name=="txb")
try this codes:
private void Form1_Load(object sender, EventArgs e)
{
TextBox txb = new TextBox();
txb.Name = "txb";
this.Controls.Add(txb);
Button btn = new Button();
this.Controls.Add(btn);
btn.Click += new EventHandler(btn_Click);
}

I would save off a reference to your TextBox.
TextBox txb;
private void Form1_Load(object sender, EventArgs e)
{
txb = new TextBox();
this.Controls.Add(txb);
Button btn = new Button();
this.Controls.Add(btn);
btn.Click += new EventHandler(btn_Click);
}

Related

I want to create new form programmatically then add controls, and events upon them C#

I want to create a form programmatically, then add controls to that for and handle click events on those controls,
such as click on button should show impact on text box
namespace formwizard
{
public partial class Form1 : Form
{
Form form = new Form();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
form.Text = formtitle.Text;
int count = Convert.ToInt32(FormName.Text);
int i=1;
while (i<= count)
{
TextBox tb = new TextBox();
tb.Text = "Text box"+ i.ToString();
Button bt = new Button();
bt.Text = "Button" + i.ToString();
tb.Location = new Point(15, i*20);
bt.Location = new Point(120, i*20);
bt.Name = "Button" + i.ToString();
form.Controls.Add(tb);
form.Controls.Add(bt);
bt.Click +=new EventHandler(bt_Click);
i++;
}
// form.Controls.Add(...);
form.ShowDialog();
}
void bt_Click(object sender, EventArgs e)
{
Button btn = (Button) sender;
string a=btn.Text.Substring(6,btn.Text.Length-6);
MessageBox.Show("You clicked Button "+a);
}
}
}
Your code is correct, the only problem I see is you haven't initialized a new instance of Form:
Form form2 = new Form();
//now add your controls to this form
//show form using "form2.ShowDialog()"

C#- Get Control text that created at runtime

How I can get text of a control that was created at runtime?
private void button1_Click(object sender, EventArgs e)
{
Button btn = new Button();
btn.Top = 50;
btn.Left = 50;
btn.Name = "mybtn";
btn.Text = "My button";
this.Controls.Add(btn);
}
private void button2_Click(object sender, EventArgs e)
{
Console.WriteLine(mybtn.text); // error
}
var b = this.Controls.OfType<Button>().FirstOrDefault(b => b.Name == "mybtn");
if (b == null) { return; }
Console.WriteLine(b.Text);
private void button2_Click(object sender, EventArgs e)
{
// find mybtn
Button mybtn = this.Controls.FirstOrDefault(i => i.Name == "mybtn") as Button;
if (mybtn != null)
{
Console.WriteLine(mybtn.Text);
}
}
Either declare newly created control as a class member(property or field):
Button btn ;
private void button1_Click(object sender, EventArgs e)
{
btn = new Button();
btn.Top = 50;
btn.Left = 50;
btn.Name = "mybtn";
btn.Text = "My button";
this.Controls.Add(btn);
}
OR
search it through the form controls:
private void button2_Click(object sender, EventArgs e)
{
Console.WriteLine(this.Controls.Cast<Control>().Single(p=>p.Name == "mybtn").Text);
}
private void button2_Click(object sender, EventArgs e)
{
Console.WriteLine(this.Controls.Find("myBtn", false).FirstOrDefault().Text);
}

Creating unique event handlers for dynamically created buttons

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 to Use Dynamically Created Button/textBox in C# Windows Forms?

private void createButton()
{
flowLayoutPanel1.Controls.Clear();
for (int i = 0; i < 4; i++)
{
Button b = new Button();
b.Name = i.ToString();
b.Text = "Button" + i.ToString();
flowLayoutPanel1.Controls.Add(b);
}
}
private void button1_Click(object sender, EventArgs e)
{
createButton();
}
I Used this code to create some buttons on runtime , now how can i use those created buttons to perform diffrent actions? Im kindz new to this so please help me , very much appreciated :)
You can assign an event handler to the click event:
b.Click += SomeMethod;
SomeMethod must have the following signature:
void SomeMethod(object sender, EventArgs e)
b.Click += delegate(object sender, EventArgs e) {
Button clickedButton = (Button)sender; //gets the clicked button
});
When you create your button, you need to subscribe to the Click event like this :
Button b = new Button();
b.Click += new EventHandler(b_Click);
// or
b.Click += b_Click;
// or
b.Click += delegate(object sender, EventArgs e) {/* any action */});
// or
b.Click += (s, e) => { /* any action */ };
void b_Click(object sender, EventArgs e)
{
// any action
}
This is something that is automatically done when your are is the designer in Visual Studio, and you click on a button to create the method button1_Click.
You can search in the Designer.cs of your form, you will find an equivalent line:
button1.Click += new EventHandler(button1_Click);
Related question:
How can i create dynamic button click event on dynamic button

Problem with programmatically generated controls

public partial class Default2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
GenerateButtons generate = new GenerateButtons();
generate.Generate5Controls(PlaceHolder1);
}
}
class GenerateButtons
{
PlaceHolder placeHolder;
public void Generate5Controls(PlaceHolder placeH)
{
placeHolder = placeH;
for (int i = 0; i < 5; i++)
{
Button newBtn = new Button();
newBtn.Click += btn_Click;
newBtn.Text = "PageLoadButton Created. Number: "+i;
placeHolder.Controls.Add(newBtn);
}
}
public void btn_Click(object sender, EventArgs e)
{
Button newBTN = new Button();
newBTN.Text = "A New Button was added by the button event btn_click";
newBTN.Click += btn2_Click;
placeHolder.Controls.Add(newBTN);
}
public void btn2_Click(object sender, EventArgs e)
{
Button newBTN = new Button();
newBTN.Text = "A New Button was added by the button event btn2_click";
placeHolder.Controls.Add(newBTN);
}
}
I want the events btn_click & btn2_click to fire every post back.. When i click the button that was programmatically created it disappears after each postback and its event doesnt fire (btn2_click). I know i could generate the button at the postback.. But I dont want to do that!! I want to know how I could update the state of the placeholder... so that the only button will appear and the 5 buttons generated in Generate5Controls(PlaceHolder placeH) to disappear.
I could use a bool Viewstate to prevent this generate.Generate5Controls(PlaceHolder1); from being execute..
But the question is how do I make the programmatically generated button to appear!?
You should generate controls on every PostBack or you can generate controls once, save in session and add generated controls from session on page_load event.
protected void Page_Load(object sender, EventArgs e)
{
if(Session["GeneratedButtons"] == null)
{
GenerateButtons generate = new GenerateButtons();
generate.Generate5Controls(PlaceHolder1);
}
else
{
List<Control> generatedControls = Session["GeneratedButtons"] as List<Control>;
foreach(Control oneControl in generatedControls)
{
PlaceHolder1.Controls.Add(oneControl);
}
}
}
class GenerateButtons
{
PlaceHolder placeHolder;
public void Generate5Controls(PlaceHolder placeH)
{
placeHolder = placeH;
List<Control> generatedControls = new List<Control>();
for (int i = 0; i < 5; i++)
{
Button newBtn = new Button();
newBtn.Click += btn_Click;
newBtn.Text = "PageLoadButton Created. Number: "+i;
placeHolder.Controls.Add(newBtn);
AddControlToSession(newBtn);
}
}
public void btn_Click(object sender, EventArgs e)
{
Button newBTN = new Button();
newBTN.Text = "A New Button was added by the button event btn_click";
newBTN.Click += btn2_Click;
placeHolder.Controls.Add(newBTN);
AddControlToSession(newBtn);
}
public void btn2_Click(object sender, EventArgs e)
{
Button newBTN = new Button();
newBTN.Text = "A New Button was added by the button event btn2_click";
placeHolder.Controls.Add(newBTN);
AddControlToSession(newBtn);
}
private void AddControlToSession(Control ctrl)
{
List<Control> generatedControls = Session["GeneratedButtons"] as List<Control>;
if(generatedControls == null)
{
generatedControls = new List<Control>();
}
generatedControls.Add(ctrl);
Session["GeneratedButtons"] = generatedControls;
}
}

Categories