c# - 为什么我的按钮的 'Validating' 事件处理程序从未被调用?

标签 c# winforms events

在下面的小应用程序中,我想知道为什么从未调用 BtnOk_Validating 事件处理程序。我预计单击“确定”按钮会调用事件处理程序。

真实的对话框有更多的控件,每个控件都有一个验证事件处理程序。我的计划是使用“确定”按钮验证事件处理程序,在允许对话框关闭之前调用每个其他事件处理程序。

如果不是很明显,那么我在表单开发方面还是个新手。

using System.ComponentModel;
using System.Windows.Forms;

namespace ConsoleApp
{
    class Program
    {
        static void Main( string[] args )
        {
            Dialog dialog = new Dialog();

            dialog.ShowDialog();
        }
    }

    public class Dialog : Form
    {
        Button m_BtnOk;
        Button m_BtnCancel;

        public Dialog()
        {
            m_BtnOk = new System.Windows.Forms.Button();
            m_BtnCancel = new System.Windows.Forms.Button();

            m_BtnOk.CausesValidation = true;
            m_BtnOk.DialogResult = DialogResult.OK;
            m_BtnOk.Text = "Ok";
            m_BtnOk.Location = new System.Drawing.Point( 0, 0 );
            m_BtnOk.Size = new System.Drawing.Size( 70, 23 );
            m_BtnOk.Validating += new CancelEventHandler( BtnOk_Validating );

            m_BtnCancel.CausesValidation = false;
            m_BtnCancel.DialogResult = DialogResult.Cancel;
            m_BtnCancel.Text = "Cancel";
            m_BtnCancel.Location = new System.Drawing.Point( 0, 30 );
            m_BtnCancel.Size = new System.Drawing.Size( 70, 23 );

            Controls.Add( this.m_BtnOk );
            Controls.Add( this.m_BtnCancel );
        }

        private void BtnOk_Validating( object sender, CancelEventArgs e )
        {
            System.Diagnostics.Debug.Assert( false ); // we never get here
        }
    }
}

编辑:请参阅我的后续question以获得更完整的示例(大部分情况下都有效)。

最佳答案

这是因为按钮永远不会失去焦点,因为它是唯一的控件。如果您添加一个 TextBox 或可以获取按钮焦点的内容,那么您将看到它被触发。

来自MSDN

When you change the focus by using the keyboard (TAB, SHIFT+TAB, and so on), by calling the Select or SelectNextControl methods, or by setting the ContainerControl.ActiveControl property to the current form, focus events occur in the following order:

   Enter    
   GotFocus    
   Leave    
   Validating    
   Validated    
   LostFocus    

When you change the focus by using the mouse or by calling the Focus method, focus events occur in the following order:

   Enter    
   GotFocus    
   LostFocus    
   Leave    
   Validating    
   Validated    

If the CausesValidation property is set to false, the Validating and Validated events are suppressed.

更新:就像 Hans 提到的那样,您需要将所有其他控件的每个验证事件中所做的验证提取到单独的函数中。然后您可以创建一个 ValidateAll 函数来检查所有值。如果该函数返回false,则您不会关闭Form。如果它返回true,则调用this.Close()。所以它可能看起来像这样:

// pseudo code
textbox1.Validating += ValidateTx1();
textbox2.Validating += ValidateTx2();
btnOk.Click += OkBtnClicked();

private void OkBtnClicked(...)
{
    if(ValidateAll())
    {
       this.Close();
    }
}

private bool ValidateTx1(...)
{
   DoTx1Validation();
}

private bool ValidateTx2(...)
{
   DoTx2Validation();
}

private bool ValidateAll()
{
   bool is_valid = DoTx1Validation();
   return (is_valid && DoTx2Validation());
}

关于c# - 为什么我的按钮的 'Validating' 事件处理程序从未被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5424132/

相关文章:

c# - MethodInfo.MetadataToken 的目的是什么

c# - 面板控件中的对齐按钮

windows - Control.Enter 和 Control.GotFocus 事件有什么区别?

c# - 无法添加类型为 'add' 且唯一键属性 'name' 设置为 'Access-Control-Allow-Origin' 的重复集合条目

c# - 将 Web 服务与 EF 一起使用时出现异常

c# - 在用户填写登录文本框时预加载整个主表单

c# - 在 C# 中的用户控件中公开和引发子控件的事件

angular - Ionic 事件在延迟加载模块之间无法正常工作

javascript - 通过选中复选框切换禁用字段集

c# - 从具有指定格式的字符串中解析日期时间