【问题标题】:Custom User Controls and Events c#自定义用户控件和事件 c#
【发布时间】:2013-09-21 19:33:33
【问题描述】:

我正在使用 c# 构建一个 windows 窗体应用程序,我构建了许多自定义用户控件,我的 GUI 是这些用户控件的组合,问题是当我从主窗体为此用户控件设置事件时,该事件没有火,但是如果我从它自己的控件中设置该事件并将该控件内的所有项目的事件处理程序设置为该事件处理程序它工作正常,并且我已经包装了控件,我应该深入设置事件和事件处理程序,实际上这将花费更多的开销“我不想要它”。 例如:

在主窗体中,我可以控制他的名字“病人”,这是用户控制.. 如果我从主窗体设置此控件的单击事件,它将不会触发

但是,如果我去耐心的用户控件定义并定义自定义事件和事件处理程序,一切都很好

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 的逻辑??

【问题讨论】:

  • if I set the click event for this control from the main form it will not fire ---> 你能说得清楚点吗?你是怎么做到的,有代码吗?
  • 因此,为了避免在类中违反名称唯一性,您实际上将事件命名为 PatientCli**e**cked ?这是不行的,因为人们会变得恶心和晕船。您应该使用英语后缀或前缀,例如:event EventHandler PatientClicked 而不是 private void RaisePatientClicked()
  • 在主要形式例如:Patient MyPatient = new Patient(); MtPatient.click += PatientClickHandler; private void PatientClichHandler(object sender,EventArgs e) { // Code }@EduardDumitru ..我的问题不在于名称,我与他们没有任何冲突
  • 谁在调用ProcessPatientClickedEvent 方法?这是您问题的一个关键方面,如果没有这些信息,我们无法猜测您面临的真正问题。请确认我做对了:您想完全跳过写在您问题正文中的 C# 代码行吗?我做对了吗?
  • ProcessPatientClickedEvent 将由具有患者用户控件的各个控件调用,例如,如果我在患者用户控件上有一个按钮,则此按钮的单击事件处理程序是 ProcessPatientClickedEvent 方法,我面临的是如果我没有在 Patient 用户控件中实现事件和事件处理程序,并且我为 Patient 用户控件中的每个单独控件设置 click 事件处理程序,它将不会触发,并且如果我为整个控件设置 click 事件处理程序它不会触发的主要形式。为什么点击事件不由它自己触发?

标签: c# .net events event-handling


【解决方案1】:

我会继续尝试。

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

现在,假设您为存在的 4 个不同控件(ButtonListViewRadioButtonUserControl 本身)编写了以下 Click 处理程序:

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

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

    • 到底发生了什么......我认为这是.net的错误,因为单击事件仍被视为单个控件的事件,而不是整个用户控件的事件。但是您需要在用户控件类中重新实现事件及其处理程序。
    • 用一行代码重新定义事件的能力是一项功能,而不是错误。
    • 我的意思是他们不考虑整个用户控制 :)
    猜你喜欢
    • 2015-02-27
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多