So I create dynamic labels in a loop, labels for a list of file folders in a directory.
i want, when you click on the label, the files within the label will display in a listbox. but i cannot get my event handler working, is it necessary to give my label a name as shown, i feel like i need the name for the event, but if the name is dynamic, the event name needs to be too and i cannot do that. also, i will need access to the labels properties within the event, so thats why i created an overloaded method, but regardless, clicking on the label does not do either of my event handlers. please advise, i'd appreciate it. here is whats in my loop and my event handlers
string str = lstMovieFolders[i];
Label lbl = new Label();
lbl.Name = "lbl" + str;
lbl.Location = new Point(25, intStartPoint);
lbl.Text = str;
lbl.Size = new Size(x, y);
lbl.Click += new EventHandler(lbl_Click);
grp.Controls.Add(lbl);
intStartPoint += 30;
public static void lbl_Click(object sender, EventArgs e)
{
MessageBox.Show("HELLOS");
}
public static void lbl_Click(object sender, EventArgs e, Label lbl)
{
MessageBox.Show("HELLO");
}
You can use sender parameter to get the current Label that triggers the event.You do not need an overload
public static void lbl_Click(object sender, EventArgs e)
{
var label = sender as Label;
if(label != null)
{
string text = label.Text;
}
}
Related
I have created a dynamic label on button click on Windows Form. And then on a right click on the label. I'm showing a context menu "cm". I obviously want to add functionality to the context menu items. But what I don't understand is how do I reference the "lbl" object inside the event handler? How can I edit the properties of the labels from inside the event handlers named MarkedImportant and EditLabel?
public void btnMonSub_Click(object sender, EventArgs e)
{
string s = txtMonSub.Text;
Label lbl = new Label();
lbl.Text = s;
lbl.Location = new System.Drawing.Point(205 + (100 * CMonSub), 111);
CMonSub++;
lbl.Size = new System.Drawing.Size(100, 25);
lbl.BackColor = System.Drawing.Color.AliceBlue;
this.Controls.Add(lbl);
ContextMenu cm = new ContextMenu();
cm.MenuItems.Add("Mark Important", MarkImportant);
cm.MenuItems.Add("Edit", EditLabel );
lbl.ContextMenu = cm;
}
private void MarkImportant(object sender, EventArgs e)
{
// imp..
}
private void EditLabel(object sender, EventArgs e)
{
// edit..
}
Or is there a better way to do this? Like dynamically adding the event handler itself?
Thanks in advance.
The ContextMenu has a property called SourceControl and MSDN says it
Gets the control that is displaying the shortcut menu.
So your event handler could reach the ContextMenu from the MenuItem passed as the sender parameter in this way
private void MarkImportant(object sender, EventArgs e)
{
// Convert the sender object to a MenuItem
MenuItem mi = sender as MenuItem;
if(mi != null)
{
// Get the parent of the MenuItem (the ContextMenu)
// and read the SourceControl as a label
Label lbl = (mi.Parent as ContextMenu).SourceControl as Label;
if(lbl != null)
{
....
}
}
}
I managed to create textboxes that are created at runtime on every button click. I want the text from textboxes to disappear when I click on them. I know how to create events, but not for dynamically created textboxes.
How would I wire this up to my new textboxes?
private void buttonClear_Text(object sender, EventArgs e)
{
myText.Text = "";
}
This is how you assign the event handler for every newly created textbox :
myTextbox.Click += new System.EventHandler(buttonClear_Text);
The sender parameter here should be the textbox which sent the even you will need to cast it to the correct control type and set the text as normal
if (sender is TextBox) {
((TextBox)sender).Text = "";
}
To register the event to the textbox
myText.Click += new System.EventHandler(buttonClear_Text);
Your question isn't very clear, but I suspect you just need to use the sender parameter:
private void buttonClear_Text(object sender, EventArgs e)
{
TextBox textBox = (TextBox) sender;
textBox.Text = "";
}
(The name of the method isn't particularly clear here, but as the question isn't either, I wasn't able to suggest a better one...)
when you create the textBoxObj:
RoutedEventHandler reh = new RoutedEventHandler(buttonClear_Text);
textBoxObj.Click += reh;
and I think (not 100% sure) you have to change the listener to
private void buttonClear_Text(object sender, RoutedEventArgs e)
{
...
}
I guess the OP wants to clear all the text from the created textBoxes
private void buttonClear_Text(object sender, EventArgs e)
{
ClearSpace(this);
}
public static void ClearSpace(Control control)
{
foreach (var c in control.Controls.OfType<TextBox>())
{
(c).Clear();
if (c.HasChildren)
ClearSpace(c);
}
}
This should do the job :
private void button2_Click(object sender, EventArgs e)
{
Button btn = new Button();
this.Controls.Add(btn);
// adtionally set the button location & position
//register the click handler
btn.Click += OnClickOfDynamicButton;
}
private void OnClickOfDynamicButton(object sender, EventArgs eventArgs)
{
//since you dont not need to know which of the created button is click, you just need the text to be ""
((Button) sender).Text = string.Empty;
}
I have a problem with getting the Text value of a textbox in the TextChanged event handler.
I have the following code. (simplified)
public float varfloat;
private void CreateForm()
{
TextBox textbox1 = new TextBox();
textbox1.Location = new Point(67, 17);
textbox1.Text = "12.75";
textbox1.TextChanged +=new EventHandler(textbox1_TextChanged);
}
private void textbox1_TextChanged(object sender, EventArgs e)
{
varfloat = float.Parse(textbox1.Text);
}
I get the following error:'the name textbox1 does not exist in the current context'.
I probably made a stupid mistake somewhere, but I'm new to C# and would appreciate some help.
Thanks in advance!
You've declared textBox1 as a local variable within CreateForm. The variable only exists within that method.
Three simple options:
Use a lambda expression to create the event handler within CreateForm:
private void CreateForm()
{
TextBox textbox1 = new TextBox();
textbox1.Location = new Point(67, 17);
textbox1.Text = "12.75";
textbox1.TextChanged +=
(sender, args) => varfloat = float.Parse(textbox1.Text);
}
Cast sender to Control and use that instead:
private void textbox1_TextChanged(object sender, EventArgs e)
{
Control senderControl = (Control) sender;
varfloat = float.Parse(senderControl.Text);
}
Change textbox1 to be an instance variable instead. This would make a lot of sense if you wanted to use it anywhere else in your code.
Oh, and please don't use public fields :)
Try this instead :
private void textbox1_TextChanged(object sender, EventArgs e)
{
varfloat = float.Parse((sender as TextBox).Text);
}
Define the textbox1 out side CreateForm() at class level scope instead of function scope, so that it is available to textbox1_TextChanged event.
TextBox textbox1 = new TextBox();
private void CreateForm()
{
textbox1.Location = new Point(67, 17);
textbox1.Text = "12.75";
textbox1.TextChanged +=new EventHandler(textbox1_TextChanged);
}
private void textbox1_TextChanged(object sender, EventArgs e)
{
varfloat = float.Parse(textbox1.Text);
}
You have not added the textbox control to the form.
It can be done as
TextBox txt = new TextBox();
txt.ID = "textBox1";
txt.Text = "helloo";
form1.Controls.Add(txt);
I have written a method trial for button btnTrial1:
public void trial(object sender, EventArgs e, Button btn, TextBox txt, Label lbl)
{
}
In my application, i am generating more buttons and textboxes and labels dynamically through code and naming them sequentially like btnTrial2, txtTrial2, lblTrial2 then btnTrial3, txtTrial3, lblTrial3 and so on. Now i want to set trial as EventHandler for btnTrial2 then for btnTrial3 and so on.
So now when i call the method trial from btnTrial1, my parameters should be:
Public void (sender, e, btnTrail1, txtTrial1, lblTrial1)
But when i call the method trial from btnTrial2, my parameters should be:
Public void (sender, e, btnTrail2, txtTrial2, lblTrial2)
and so on...
btnTrial1.YourEvent += (sender, args) => trial(sender, args,
btnTrial1, txtTrial1, lblTrial1);
btnTrial2.YourEvent += (sender, args) => trial(sender, args,
btnTrial2, txtTrial2, lblTrial2);
You mention "generating them dynamically" - that is fine, but if you are in a loop you will also need to watch out for the infamous "captured variable / loop" problem - notably, the variables "captured" must be inside the loop; for example:
for(int i = 1 ; i <= 10 ; i++) {
var btnTrial = ...
var txtTrial = ...
var lblTrial = ...
btnTrial.YourEvent += (sender, args) => trial(sender, args,
btnTrial, txtTrial, lblTrial);
}
(if, for example, btnTrial was declared outside the loop, bad things would happen)
Why not make your trial function
public void trial(object sender, EventArgs e)
{
}
And then based on the sender, use different controls:
public void trial(object sender, EventArgs e)
{
Button btn;
TextBox txt;
Label lbl;
if (sender == btnTrial1){
btn = btnTrail1;
txt = txtTrial1;
lbl = lblTrial1;
}
if (sender == btnTrial2){
btn = btnTrail2;
txt = txtTrial2;
lbl = lblTrial2;
}
if (sender == btnTrial3){
btn = btnTrail3;
txt = txtTrial3;
lbl = lblTrial3;
}
//rest of the method
}
Two suggestions:
Refactor trial() to return an EventHandler (or ideally EventHandler<T>):
public EventHandler GetTrialEventHandler(Button btn, TextBox txt, Label lbl)
{
return (sender, args) =>
{
// Do something with btn, txt, lbl
};
}
Rather than name your form elements btnTrial1, btnTrial2, etc, why not just make lists of the elements (or a list of sets of Button+TextBox+Label)? Then you just have to enumerate over the list(s) to set up your event handlers, rather than hard-code for each.
To each button You can add:
this.button.Click += new System.EventHandler(this.button_Click);
method like this:
private void button_Click(object sender, EventArgs e)
{
String name = (sender as Control).Name;
int number = Int32.Parse(name.Substring(name.Length-1));
trial(sender, e, this.Controls["btnTrial"+number], this.Controls["txtTrial"+number], Controls["lblTrial"+number]);
}
At my program i dynamicly add Buttons to my form
{
...
Button bt = new Button();
bt.Text = "bla bla";
bt.MouseClick += new MouseEventHandler(bt_MouseClick);
myPanel.Controls.Add(bt);
...
}
void bt_MouseClick(object sender, MouseEventArgs e)
{
TabPage _tab = new TabPage();
_tab.Text = ??? // I want to get the Button's text ! this.Text returns me the
//main form.Text
}
How can access my dynamic Buttons properties ? How can I understand whick button is
clicked either getting its text.
Thanks.
void bt_MouseClick(object sender, MouseEventArgs e)
{
TabPage _tab = new TabPage();
_tab.Text = ((Button)sender).Text;
}
When an EventHandler delegate is invoked, the sender parameter is the component that raised the event, and the e parameter is a subclass of EventArgs that provides any additional component/event specific information for the event.
Therefore you can establish which button the event fired on by casting the sender parameter to Button:
void bt_MouseClick(object sender, MouseEventArgs e)
{
var button = (Button)sender;
TabPage _tab = new TabPage();
_tab.Text = button.Text;
}