0

我正在使用 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 的逻辑?

4

2 回答 2

1

UserControl 从 Control 类继承 Click 事件。它当然可以开火,但这不太可能发生。您的用户将改为单击 UserControl 内的控件。当您用其他控件覆盖整个 UserControl 表面时,它永远不会触发。

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

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

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

于 2013-09-17T11:59:57.457 回答
0

我会继续拍摄。

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

在此处输入图像描述

Click现在,假设您为存在的 4 个不同的控件(the Button、the ListView、theRadioButton和 theUserControl本身)编写了以下处理程序:

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

}

只是为了澄清我在说什么,检查.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_Click程序将被调用,您将看到“UserControl”消息框出现。

当您单击另一个蓝色区域时:

在此处输入图像描述

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

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

在此处输入图像描述

和单选按钮:

在此处输入图像描述

当您UserControl从其最终容器的角度查看您的事件并看到该Click事件并为其添加事件处理程序时,您应该期望与UserControl1_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!");
于 2013-09-17T12:15:40.030 回答