C# 自定义用户控件和事件#

C# 自定义用户控件和事件#,c#,.net,events,event-handling,C#,.net,Events,Event Handling,我正在使用c#构建windows窗体应用程序,我构建了许多自定义用户控件,我的GUI是这些用户控件的组合,问题是当我从主窗体为此用户控件设置事件时,事件不会触发,但是,如果我从控件本身设置该事件,并将该控件内所有项目的事件处理程序设置为该事件处理程序,那么它工作得很好,而且由于我已经包装了很多控件,我应该深入设置事件和事件处理程序,实际上这将花费更多的开销,“我不希望这样”。 例: 在主窗体中,我有一个名为“Patient”的控件,它是用户控件。。 如果我从主窗体设置此控件的单击事件,它将不会触

我正在使用c#构建windows窗体应用程序,我构建了许多自定义用户控件,我的GUI是这些用户控件的组合,问题是当我从主窗体为此用户控件设置事件时,事件不会触发,但是,如果我从控件本身设置该事件,并将该控件内所有项目的事件处理程序设置为该事件处理程序,那么它工作得很好,而且由于我已经包装了很多控件,我应该深入设置事件和事件处理程序,实际上这将花费更多的开销,“我不希望这样”。 例:

在主窗体中,我有一个名为“Patient”的控件,它是用户控件。。 如果我从主窗体设置此控件的单击事件,它将不会触发

但是,如果我转到患者用户控件定义,并定义自定义事件和事件处理程序,那么一切都很好

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();
}

我的问题是,是否有其他方法可以做到这一点,或者这是.NET的逻辑???

用户控件从控件类继承单击事件。它当然可以开火,但这种情况不太可能发生。您的用户将单击UserControl中的控件。当您使用其他控件覆盖整个UserControl界面时,它将永远不会触发

您可以简单地重定向Click事件以供自己使用。通过声明自己的事件,您已经尝试过的东西。这不是必需的,您可以这样做:

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

与所有名称以On开头并与事件同名的方法一样,它会引发Click事件。

我将继续并尝试一下

假设我们有一个
UserControl
。假设它看起来像这样:

现在,假设您为存在的4个不同控件(
按钮
列表视图
单选按钮
用户控件本身)编写了以下
单击
处理程序:

为了澄清我的意思,请检查
.designer.cs
文件的子集:

...
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);
...
考虑下面的肯定

单击此蓝色区域时:

UserControl1\u单击
处理程序将被调用,您将看到“UserControl”消息框出现

单击其他蓝色区域时:

“listView1_Click”处理程序将被调用,您将看到“ListView”消息框出现,但您将看不到“UserControl”消息框

对于其余两个控件都是如此,按钮:

和单选按钮:

当您从最后一个容器的角度查看
UserControl
时,您看到
Click
事件,并为其添加事件处理程序时,您应该期待与此处显示的
UserControl1\u Click
事件处理程序的行为完全相同

如果愿意,您可以为任何特定的子控件集创建自定义事件处理程序,并简单地为外部世界可能具有的任何处理程序重定向该事件的订阅和取消订阅:

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;
    }
}
或者甚至以动态方式向每个子控件以及UserControl本身订阅处理程序:

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;
    }
}
然后用周围世界的数据:

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

如果我从主窗体设置此控件的单击事件,它将不会触发
-->您能更清楚地说明这一点吗?如何做到这一点,有代码吗?为了避免类中的名称单一性冲突,您实际命名了事件
PatientCli**e**cked
?这是不允许的,因为人们会感到恶心和晕船。您应该使用英语后缀或前缀,例如:
event EventHandler PatientClicked
,而不是
private void RaisePatientClicked()
在主表单中,例如:
Patient MyPatient=new Patient();MtPatient.click+=PatientClickHandler;私有void patientclichandler(对象发送方,事件参数e){//Code}@eduardumitru。。我的问题不在于名称,也不与名称有任何冲突谁在调用
ProcessPatientClickedEvent
方法?这是你问题的一个关键方面,没有这些信息,我们无法猜测你面临的真正问题。请确认我是对的:你想完全跳过写在你问题正文中的C代码行吗?我做对了吗?ProcessPatientClickedEvent将由包含患者用户控件的各个控件调用,例如,如果我在患者用户控件上有一个按钮,则此按钮的单击事件处理程序为ProcessPatientClickedEvent方法,我面临的是,如果我没有在患者用户控件中实现事件和事件处理程序,并且我为患者用户控件中的每个控件设置了单击事件处理程序,那么它将不会触发,如果我从主窗体为整个控件设置了单击事件处理程序,那么它将不会触发。为什么点击事件不是由它自己触发的呢?这正是发生的。。我认为这是.net的错误,因为单击事件仍然被视为单个控件的事件,而不是整个用户控件的事件。但是,您需要在用户控件类中重新实现事件及其处理程序。用单个代码重新定义事件的能力是一个特性,而不是一个错误。我的意思是,他们不考虑整个用户控件:
UserControl1 someControl = new UserControl1();
someControl.AnythingClick += (sender, e) => MessageBox.ShowMessage("tadaaa!");