This is the new control add code part:
for (int i = 0; i < 1; i++)
{
var newLabel = new Label();
newLabel.Location = new Point(x, y);
newLabel.Size = new System.Drawing.Size(25, 25);
newLabel.Name = "lbl" + realpocsed.ToString();
if (value2== "Value2")
{
newLabel.MouseMove += new MouseEventHandler(this.MyControl_MouseMove);
newLabel.MouseDown += new MouseEventHandler(this.MyControl_MouseDown);
}
if (value== "Value1")
{
newLabel.MouseDown += new MouseEventHandler(this.MyControl_MouseHover);
}
panel1.Controls.Add(newLabel);
The MouseHover event look like this:
private void MyControl_MouseHover(object sender, MouseEventArgs e)
{
ToolTip ToolTip1 = new ToolTip();
ToolTip1.ShowAlways = true;
ToolTip1.Show("t", X); // X should be name of the newly created label
}
May I ask if is there any way to assign the newly created with name "lbl" + realpocsed.ToString() instead of X?
Thank you for your time.
You're assigning a MouseDown event to your MouseHover code, not sure you want that.
It should look like this:
newLabel.MouseHover += MyControl_MouseHover;
For your X, you would have to cast the sender:
ToolTip1.Show("Hover Message Here", (Label)sender);
You can't access any object by creating its name in string. The simple way to do that is to pass the object reference:
ToolTip1.Show("t", (sender as Label));
Inside for:
newLabel.MouseHover += delegate (object sender, EventArgs e)
{
ToolTip ToolTip1 = new ToolTip();
ToolTip1.ShowAlways = true;
ToolTip1.Show("t", newLabel);
};
Update:
if (value == "Value1")
{
newLabel.MouseHover += delegate (object sender, EventArgs e)
{
ToolTip ToolTip1 = new ToolTip();
ToolTip1.ShowAlways = true;
ToolTip1.Show("t", newLabel);
};
}
Related
Label[] l1 = new Label[30];
DataTable dt = ConsoleApp2.CitiesDB.getCities(this.region);
foreach(DataRow row in dt.Rows)
{
count++;
string city = row.Field<string>("city");
l1[count] = new Label();
l1[count].Location = new System.Drawing.Point(x,y);
l1[count].Size = new Size(140, 80);
l1[count].Font = new System.Drawing.Font("Century Gothic", 8.5F);
l1[count].Text = city;
x = x + 260;
this.Controls.Add(l1[count]);
this.Refresh();
if(count == 4 || count %4 ==0)
{
y = y + 150;
x = 40;
}
//l1[count].Click += new EventHandler(l1_click);
}
So i made a dynamic labels (each label is a city name). how can i make each label clickable? i have a register form - what i want is if user clicks on "new york" then in the "city" textbox it will appear. the way with the EventHandler doesnt works for me);. what can i do?
what i mean in code that doesnt work:
protected void l1_click(object sender, EventArgs e)
{
RegisterForm register = new RegisterForm(username,email,password,address,phone);
register.state.Text = region;
register.city.Text = l1[count].Text;
register.Show();
}
thanks (:
Assign one click event for each label (dynamically created):
l1[count].Click += l1_click;
In the one click event use the sender argument to see which label was clicked on:
protected void l1_click(object sender, EventArgs e)
{
Label lbl = (Label)sender;
MessageBox.Show(lbl.Text);
}
I have array of buttons, and array of labels:
Label[] labels = new Label[10];
Button[] but = new Button[10];
While clicking the other button I want to dynamically create new button and new label from the array, i also want the but[i] to change the tex of labels[i]:
private void button1_Click(object sender, EventArgs e)
{
labels[i] = new Label();
labels[i].Location = new System.Drawing.Point(0, 15+a);
labels[i].Parent = panel1;
labels[i].Text = "Sample text";
labels[i].Size = new System.Drawing.Size(155, 51);
labels[i].BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
a = labels[i].Height + labels[i].Top;
but[i] = new Button();
but[i].Text = "-";
but[i].Location = new System.Drawing.Point(0, labels[i].Height + labels[i].Top);
but[i].Parent = panel1;
but[i].Size = new System.Drawing.Size(155, 10);
but[i].Click += new System.EventHandler(but_Click);
i++;
}
private void but[i]_Click(object sender, EventArgs e)
{
labels[i].Text = "Changed Text";
}
But apparently I can't put an array in an event handler, how should I do it then?
One way to do this is to make your method return a handler instead of being a handler:
private EventHandler but_Click(int i)
{
return (s, e) => labels[i].Text = "Changed Text";
}
And use it like:
but[i].Click += but_Click(i);
Or do it inline:
but[i].Click += (s, ea) => labels[i].Text = "Changed Text";
What's happening in either of these is some compiler magic to capture the i variable. It's equivalent to this (which is also a valid, if verbose, way to do it):
class MyWrapper {
private int i;
public MyWrapper(int i) {
this.i = i;
}
public void TheHandler(object sender, EventArgs e) {
// TODO: capture the object that owns `labels` also, or this won't work.
labels[i].Text = "Changed Text";
}
}
//call with
but[i].Click += new EventHandler(new MyWrapper(i).TheHandler);
You could add the array index to the button as Tag property, and then pull it back out in but_Click.
So, add
but[i].Tag = i;
to the button creation. And then change the event handler:
private void but_Click(object sender, EventArgs e)
{
int buttonIndex = (int)((Button)sender).Tag;
labels[buttonIndex].Text = "Changed Text";
}
Or put the event handler inline:
but[i].Click += (s,e) => { label[i].Text = "Changed Text"; }
Or another option using the Tag property, add:
but[i].Tag = label[i];
...
private void but_Click(object sender, EventArgs e)
{
Label label = (Label)((Button)sender).Tag;
label.Text = "Changed Text";
}
Advantage of this approach is you're not relying on keeping arrays in synch after the initial creation of the controls.
I guess this is self-explaining:
public void SomeMehthod()
{
Button btn1 = new Button();
Button btn2 = new Button();
Button btn3 = new Button();
// Your button-array
Button[] btns = new Button[]
{
btn1,
btn2,
btn3
};
foreach(Button btn in btns)
{
// For each button setup the same method to fire on click
btn.Click += new EventHandler(ButtonClicked);
}
}
private void ButtonClicked(Object sender, EventArgs e)
{
// This will fire on any button from the array
// You can switch on the name, or location or anything else
switch((sender as Button).Name)
{
case "btn1":
// Do something
break;
case "btn2":
// Do something
break;
case "btn3":
// Do something
break;
}
}
Or if your array is accessible globaly:
Button[] btns = new Button[5];
Label[] lbls = new Label[5];
private void ButtonClicked(Object sender, EventArgs e)
{
Button clicked = sender as Button;
int indexOfButton = btns.ToList().IndexOf(clicked);
// ..IndexOf() returns -1 if nothign is found
if(indexOfButton > 0)
{
lbls[indexOfButton].DoWhatYouWant...
}
}
I want to add buttons and textboxes dynamically on runtime with each
button react differently.
ie newbutton1 linked with texbox1 ,newbutton2linked withtextbox2`
Right now any button just prints from the first to the last textbox
one after the other.
Also consider that I have a button1 & textbox1 already on the form for guides
Here is my code :
List<Button> buttons = new List<Button>();
List<TextBox> textboxes = new List<TextBox>();
int NumTextBox = 0;
void click(object sender, EventArgs e)
{
MessageBox.Show(textboxes[NumTextBox].Text);
NumTextBox++;
}
int x = 0;
int y = 0;
void AddClick(object sender, EventArgs e)
{
Button newButton = new Button();
buttons.Add(newButton);
newButton.Click += click;//
// newButton.Location.Y = button1.Location.Y + 20;
newButton.Location = new Point(button1.Location.X, button1.Location.Y+25+x);
x += 25;
this.Controls.Add(newButton);
TextBox newTextBox = new TextBox();
textboxes.Add(newTextBox);
// newTextBox.Click += click;
newTextBox.Location = new Point(textBox1.Location.X, textBox1.Location.Y+25+y);
y += 25;
this.Controls.Add(newTextBox);
}
you can have a class like mybutton that inherits from button class, in this new class you can have a property with textbox type . just like following code . and in your code when you want to Instantiated Button you can use list<mybutton> and set linkedTextbox property with a textbox.
public class myButton:Button
{
...
public TextBox linkedTextBox{set;get;}
}
and in your code you should write some thing like this :
list<myButton> buttons=new list<myButton>();
Textbox someTextBox=new TextBox();
buttons[0].linkedTextbox=someTextBox;
and in your event you can use:
((myButton)sender).linkedTextBox.text="Some thing";
Thank you everyone , I followed #Franck's answer .So WHAT CHANGED :
I've deleted the pre-made button1 & textbox1 and add them
programatically on the Form_load so that I can add them in the
Lists
A proof screenshot : http://prntscr.com/aprqxz
CODE:
List<Button> buttons = new List<Button>();
List<TextBox> textboxes = new List<TextBox>();
Button button1 = new Button();
TextBox textBox1 = new TextBox();
int x = 0;
int y = 0;
void click(object sender, EventArgs e)
{
var txt = textboxes[Convert.ToInt32(((Button)sender).Tag)].Text;
MessageBox.Show(txt.ToString());
}
void AddClick(object sender, EventArgs e)
{
Button newButton = new Button();
newButton.Click += click;
newButton.Location = new Point(button1.Location.X, button1.Location.Y+25+x);
x += 25;
newButton.Tag = buttons.Count;
this.Controls.Add(newButton);
buttons.Add(newButton);
//
TextBox newTextBox = new TextBox();
newTextBox.Location = new Point(textBox1.Location.X, textBox1.Location.Y+25+y);
y += 25;
this.Controls.Add(newTextBox);
textboxes.Add(newTextBox);
}
void MainFormLoad(object sender, EventArgs e)
{
button1.Click += click;
button1.Location = new Point(55, 48);
button1.Tag = buttons.Count;
this.Controls.Add(button1);
buttons.Add(button1);
//
textBox1.Location = new Point(137, 50);
this.Controls.Add(textBox1);
textboxes.Add(textBox1);
}
EDIT 1: As the counting starts from 0 I didn't added newButton.Tag = buttons.count+1; I added just newButton.Tag = buttons.count;
I have added check boxes dynamically to a panel. now how can i get a alert message with "you have checked 1 or 2 or 3....". when check boxes get selected??
CheckBox[] premiumticket = new CheckBox[50];
private void Form1_Load(object sender, EventArgs e)
{
var panel1 = new Panel()
{
Size = new Size(600, 70),
Location = new Point(20, 130),
BorderStyle = BorderStyle.FixedSingle
};
for (int i = 0; i < 20; i++)
{
premiumticket[i]=new CheckBox();
premiumticket[i].Text=(i+1).ToString();
premiumticket[i].Name=(i+1).ToString();
premiumticket[i].Location=new Point(x,y);
panel1.Controls.Add(premiumticket[i]);
x = x - 55;
if (x < 55)
{
y = y + 20;
x = 550;
}
}
x = 550; y = 10;
Controls.Add(panel1);
}
Add an event-handler to each CheckBox:
public void Checkbox_CheckedChanged(Object sender, EventArgs e) {
CheckBox cb = (CheckBox)sender;
MessageBox.Show( cb.Name + " was clicked!");
}
for (int i = 0; i < 20; i++) {
premiumticket[i] = new CheckBox();
premiumticket[i].OnCheckChanged += new EventHandler( Checkbox_CheckedChange );
...
}
Dynamically Create events for Each Checkbox and put ur alert code on it
var checkBox = new CheckBox { ID = "WCCheckBox" + item.ItemID.ToString(), ItemID = item.ItemID, Checked = item.UserValue == "1", CssClass = "wounditem" };
Your implementation may be another.
Add this to your for loop:
premiumticket[i].OnCheckChanged += new EventHandler( premiumTicketChanged );
Checkbox toggled handler:
public void premiumTicketChanged (Object sender, EventArgs e)
{
int ticketCount = premiumticket.Count(c => c.Checked);
MessageBox.Show( string.Format("You have checked {0} checkboxes....", ticketCount));
}
After you add dynamically a control you can use AddHandler to manage the events of this control.
Remember set the checkbox autopostback property to true.
i'm designing a windows form application. In this app, user selects a number from a combobox, then depending on the number, some dynamic controls will be created(labels and comboboxes).
My problem is, i need to write some code on these dynamically created comboboxs' "selectedindexchanged" event. But i don't know how to create an event to dynamic combobox.
Here is my function:
FORM1.CS
public void getchildCntrl(Panel pnl,ComboBox cmbb)
{
for (int ix = pnl.Controls.Count - 1; ix >= 0; ix--)
if (pnl.Controls[ix].Name.Substring(0, 5) == "Child") pnl.Controls[ix].Dispose();
if (cmbb.SelectedIndex != 0)
{
Label[] childLabels = new Label[cmbb.SelectedIndex];
ComboBox[] txtTeamNames = new ComboBox[cmbb.SelectedIndex];
for (int i = 0; i < txtTeamNames.Length; i++)
{
//label create
var lbl = new Label();
childLabels[i] = lbl;
lbl.Name = "ChildLb" + i.ToString();
lbl.Text = (i + 1).ToString() + ". Çocuk-Yaş :";
lbl.Width = 80;
lbl.Location = new Point(cmbb.Location.X - 85, cmbb.Location.Y + 7 + ((i + 1) * 28));
lbl.Visible = true;
pnl.Controls.Add(lbl);
//combobox create
var cmb = new ComboBox();
txtTeamNames[i] = cmb;
cmb.Name = "Child" + i.ToString();
cmb.Location = new Point(cmbb.Location.X, cmbb.Location.Y + 5 + ((i + 1) * 28));
cmb.Width = 40;
cmb.DropDownStyle = ComboBoxStyle.DropDownList;
cmb.DataSource = ages.ToArray();
cmb.Visible = true;
pnl.Controls.Add(cmb);
}
}
}
You just register to the event like below...
cmb.SelectedIndexChanged += new System.EventHandler((object o, EventArgs e) =>
{
//Do something here
});
Or
cmb.SelectedIndexChanged += new System.EventHandler(cmb_SelectedValueChanged);
private void cmb_SelectedValueChanged(object sender, EventArgs e)
{
//Do something here.
}
You can hook up an event handler to the ComboBox like this:
cmd.SelectionChanged += new SelectionChangedEventHandler(GuiController_SelectionChanged);
void GuiController_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
throw new NotImplementedException();
}
Register event handler this way:
cmb.SelectedIndexChanged+=new EventHandler(cmb_SelectedIndexChanged);
Unregister this way:
cmb.SelectedIndexChanged-=new EventHandler(cmb_SelectedIndexChanged);
private void cmb_SelectedIndexChanged(object sender, System.EventArgs e)
{
//write your event code here
}
How to: Create Event Handlers at Run Time for Windows Forms
public void getchildCntrl(Panel pnl,ComboBox cmbb)
{
//// your code.....
//combobox create
var cmb = new ComboBox();
cmb.SelectedIndexChanged+=new EventHandler(cmb_SelectedIndexChanged);
// remaining code
cmb.Visible = true;
pnl.Controls.Add(cmb);
}
}
}
For specifying parameters - go through:
ComboBox.SelectedIndexChanged Event