Home > front end >  Add Mousedown event in new CheckBox() instance
Add Mousedown event in new CheckBox() instance

Time:11-28

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).
  • 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 single EventHandler instance (using new 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();
  • 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 the GetNewCheckboxName() method.
  •  Tags:  
  • c#
  • Related