简体   繁体   中英

Custom User Controls and Events c#

I am building a windows Forms application using c# , I build many custom user controls and my GUI is combination of these users controls , the problem is when I set an event for this user controls from the main form , the event does not fire , but if I set that event from the controls it self and set the event handler for all items inside this control to that event handler it works fine , and as much I have wrapped controls I should go deeply to set the events and event handlers , actually this will cost more overhead "Which I don't want it". ex:

In main form I have control with he name "Patient" which is user control.. if I set the click event for this control from the main form it will not fire

But if I go to the patient user control definition and I define custom event and event handler everything is fine

public event EventHandler PatientCliecked;

private void PatientClicked()
{
    if (this.PatientCliecked != null)
    this.PatientCliecked(new object(), new EventArgs());
}

private void ProcessPatientClickedEvent(object sender, EventArgs e)
{
    PatientClicked();
}

My question is, is there any other way to do that or this is the logic of .NET ??

A UserControl inherits the Click event from the Control class. It certainly can fire, but that isn't terribly likely to happen. Your user is going to click on the controls inside the UserControl instead. And it will never fire when you've covered the entire UserControl surface with other controls.

You can simply redirect the Click event for your own use. Something you've already experimented with by declaring your own event. That isn't necessary, you can do it like this instead:

private void PatientClicked()
{
    OnClick(this, EventArgs.Empty);
}

Which, like all methods whose name start with On and have the same name as an event, raises the Click event.

I'll go ahead and give it shot.

Say we have a UserControl . Say it looks something like this:

在此处输入图片说明

Now, imagine you wrote the following Click handlers for the 4 distinct controls which are present (the Button , the ListView , the RadioButton and the UserControl itself):

public partial class UserControl1 : UserControl {

    public UserControl1() {
        InitializeComponent();
    }

    private void radioButton1_Click(object sender, EventArgs e) {
        MessageBox.Show("RadioButton");
    }
    private void listView1_Click(object sender, EventArgs e) {
        MessageBox.Show("ListView");
    }
    private void button1_Click(object sender, EventArgs e) {
        MessageBox.Show("Button");
    }
    private void UserControl1_Click(object sender, EventArgs e) {
        MessageBox.Show("UserControl");
    }

}

Just to clarify what I'm saying, check this subset of the .designer.cs file:

...
this.radioButton1.Click += new System.EventHandler(this.radioButton1_Click);
...
this.button1.Click += new System.EventHandler(this.button1_Click);
...
this.listView1.Click += new System.EventHandler(this.listView1_Click);
...
this.Click += new System.EventHandler(this.UserControl1_Click);
...

Consider the following affirmations.

When you click on this blue area:

在此处输入图片说明

the UserControl1_Click handler will get called and you'll see the "UserControl" message box appear.

When you click on this other blue area:

在此处输入图片说明

the 'listView1_Click' handler will get called and you'll see the "ListView" message box appear BUT you won't see the "UserControl" message box.

That is true for both remaining controls, the button:

在此处输入图片说明

and the radiobutton:

在此处输入图片说明

When you're looking at your UserControl from its final container's perspective and you see the Click event, and you're adding an event handler for it, you should expect the very same behaviour as the that of the UserControl1_Click event handler presented here.

If you wish, you can create a custom event handler for any particular set of child controls and simply redirect subscriptions and unsubscriptions to and from that event for whatever handlers the outside world might have:

public event EventHandler SmallButtonsClick {
    add {
        this.radioButton1.Click += value;
        this.button1.Click += value;
    }
    remove {
        this.radioButton1.Click -= value;
        this.button1.Click -= value;
    }
}

public event EventHandler LargeStuffClick {
    add {
        this.listView1.Click += value;
    }
    remove {
        this.listView1.Click -= value;
    }
}

or even subscribe handler in a dynamical way to every child control PLUS the UserControl itself:

public event EventHandler AnythingClick {
    add {
        this.Click += value;
        foreach (var child in this.Controls)
            child.Click += value;
    }
    remove {
        this.Click -= value;
        foreach (var child in this.Controls)
            child.Click -= value;
    }
}

and then just use that from the surrounding world:

UserControl1 someControl = new UserControl1();
someControl.AnythingClick += (sender, e) => MessageBox.ShowMessage("tadaaa!");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM