将通用事件处理程序连接到相同类型的多个控件

本文关键字:同类型 控件 事件处理 程序 连接 | 更新日期: 2023-09-27 18:12:03

我有一个WinForms应用程序,其中包含许多NumericUpDown控件。简而言之,如果我的用户在控件中输入了一个值,然后删除了文本,我希望在控件失去焦点时恢复它(文本)。所以我决定在控件失去焦点时检查。text,如果它是空的,我设置。text = . value . tostring()。

我在Leave事件处理程序中这样做,它工作得很好。但正如我所说,我有很多这样的控制(确切地说是18个)。我不喜欢创建18个Leave事件处理程序,所有做同样的事情,所以我创建了一个像这样的通用的:

private void numericUpDown_GenericLeave(object sender, EventArgs e)
{
    if (string.IsNullOrEmpty(((NumericUpDown)sender).Text))
        ((NumericUpDown)sender).Text = ((NumericUpDown)sender).Value.ToString();
}

我开始将所有控件连接到这个通用事件处理程序,但我很快就厌倦了这样做:

numericUpDown1.Leave += numericUpDown_GenericLeave;
numericUpDown2.Leave += numericUpDown_GenericLeave;
numericUpDown3.Leave += numericUpDown_GenericLeave;
...
numericUpDown18.Leave += numericUpDown_GenericLeave;

所以我想我应该创建一个函数,它将返回指定类型的所有控件的列表,然后循环遍历该列表并连接事件处理程序。该函数看起来像这样:

public static List<Control> GetControlsOfSpecificType(Control container, Type type)
{
    var controls = new List<Control>();
    foreach (Control ctrl in container.Controls)
    {
        if (ctrl.GetType() == type)
            controls.Add(ctrl);
        controls.AddRange(GetControlsOfSpecificType(ctrl, type));
    }
    return controls;
}

我这样调用函数:

var listOfControls = GetControlsOfSpecificType(this, typeof(NumericUpDown));
foreach (var numericUpDownControl in listOfControls)
{
    numericUpDownControl.Leave += numericUpDown_GenericLeave;
}
然而,当我运行我的应用程序时,我没有看到当我手动将每个控件连接到通用事件处理程序时发生的预期行为。这段代码目前是在我的形式的构造函数,我已经尝试调用它之前以及之后调用InitializeComponent(),但似乎都没有工作。我没有得到任何类型的错误,我只是没有看到我期望的行为。我在通用事件处理程序中设置了一个断点,但调试器从未中断,因此似乎事件处理程序没有正确连接。有人知道这可能是为什么,或者我如何进一步解决它吗?谢谢!

编辑

我刚意识到调用:

var listOfControls = GetControlsOfSpecificType(this, typeof(NumericUpDown));

发生在调用InitializeComponent()之前,所以返回的控件列表当然是空的。哎!感谢所有的回复。我很抱歉浪费了大家的时间。: - (

将通用事件处理程序连接到相同类型的多个控件

您将this传递给您的方法,这可能是对form的引用。您的方法将只捕获直接放置在窗体上的控件。任何不是直接在表单上的NumericUpDown控件(例如,它们位于面板或其他地方)将会被遗漏。

为什么不创建一个带有NumericUpDown控件的用户控件呢?

则在用户控制事件中处理此事件。

这个为我工作:

 private decimal _previous = 0;
  private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            if (((NumericUpDown)sender).Text.Length > 0)
            {
                _previous = this.numericUpDown1.Value;
            }
        }
        private void UserControl1_Leave(object sender, EventArgs e)
        {
            if (this.numericUpDown1.Text == "")
            {
                this.numericUpDown1.Value = _previous;
                this.numericUpDown1.Text = System.Convert.ToString(_previous);
            }
        }

请注意,Leave事件是在用户控件上,而不是在上下控件上。

问题回答。参见上面的编辑。感谢bsegraves为我指明了正确的方向。