Briefly, my app adds checkboxes programmatically into a flowlayoutpanel named "fp".
fp.Controls.Add(new CheckBox() { Name = "cb1", Text = "New Checkbox", Checked = true, AutoSize = true, AllowDrop = true });
i'm stuck trying to add a mouseclick event inside that new Checkbox instance. I tried adding the line below into the code above.
this.MouseDown = new MouseEventHandler(cbox_MouseDown);
But I get Invalid initializer member declarator
I also tried to add this:
((CheckBox)(this.Controls.Find("cb1", false))[0]).MouseDown = new MouseEventHandler(cbox_MouseDown);
before adding the new checkbox instance but it does not work either.
I could highly appreciate a way to insert the event directly into the new CheckBox() instance .
Thank you guys <3
CodePudding user response:
- C#'s Object-Initializer syntax does not support events.
- C#'s Object-Initializers have a lot of other shortcomings too, I'm not a fan of them (horrible debugging, broken line-numbers in stack-traces, it ignores
IDisposable
when an exception is thrown, you can't use it with an existing object, often takes up more lines-of-code than otherwise, etc).
- C#'s Object-Initializers have a lot of other shortcomings too, I'm not a fan of them (horrible debugging, broken line-numbers in stack-traces, it ignores
- However, you can define a new extension-method for
ControlsCollection
which will add the event-handler for you.
Like so:
MyExtensions.cs:
public static class MyExtensions
{
public static void AddWithClickHandler( this ControlsCollection ctrls, EventHandler onClickHandler, CheckBox newCheckBox )
{
newCheckBox.Click = onClickHandler;
ctrls.Add( newCheckBox );
}
}
MyForm.cs:
public partial class MyForm : Form
{
private readonly EventHandler onClickHandler;
public MyForm()
{
this.InitializeComponent();
//
this.onClickHandler = new EventHandler( this.cbox_MouseDown );
}
private void cbox_MouseDown( Object sender, EventArgs e )
{
//
}
private Int32 checkboxCount = 0;
private String GetNewCheckboxName()
{
this.checkboxCount = 1;
return "cb" this.checkboxCount.ToString("d");
}
public void AddCheckboxes()
{
this.fp.Controls.AddWithClickHandler( onClickHandler, new CheckBox() { Name = this.GetNewCheckboxName(), Text = "New Checkbox", Checked = true, AutoSize = true, AllowDrop = true } );
this.fp.Controls.AddWithClickHandler( onClickHandler, new CheckBox() { Name = this.GetNewCheckboxName(), Text = "New Checkbox", Checked = true, AutoSize = true, AllowDrop = true } );
this.fp.Controls.AddWithClickHandler( onClickHandler, new CheckBox() { Name = this.GetNewCheckboxName(), Text = "New Checkbox", Checked = true, AutoSize = true, AllowDrop = true } );
}
}
Note that:
- In my code, the
MyForm
class only ever creates a singleEventHandler
instance (usingnew EventHandler
), this is important as you need to allow code to de-register (i.e. remove) event-handlers to prevent memory-leaks.- Unfortunately you cannot remove event-handlers registered using the shorthand syntax like this:
obj.Click = this.OnClickMethod;
- Nor can you remove event-handlers implemented as lambda-methods, e.g.
obj.Click = ( obj, sender ) => this.DoSomething();
- Unfortunately you cannot remove event-handlers registered using the shorthand syntax like this:
- Control Names need to be unique, so rather than hardcoding strings like
"cb1"
and"cb2"
, unique names for each and every checkbox is generated by theGetNewCheckboxName()
method.