3

我有一个包含许多 NumericUpDown 控件的 WinForms 应用程序。简而言之,如果我的用户在控件中输入一个值然后删除文本,我想在控件失去焦点时恢复它(文本)。所以我决定当控件失去焦点时检查.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()之前发生,所以返回的控件列表当然是空的。哦!感谢所有回复。我为浪费大家的时间而道歉。:-(

4

3 回答 3

1

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

于 2011-10-21T14:36:10.210 回答
1

为什么不创建一个包含 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);
            }
        }

请注意,离开事件是在用户控件上而不是在 updown 控件本身上。

于 2011-10-21T15:08:56.660 回答
0

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

于 2011-11-16T16:57:58.673 回答