Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# t进入WinForms库_C#_.net_Winforms_Validation_User Interface - Fatal编程技术网

C# t进入WinForms库

C# t进入WinForms库,c#,.net,winforms,validation,user-interface,C#,.net,Winforms,Validation,User Interface,每个控件-派生对象都有两个名为验证和验证的事件。它还有一个名为的属性。当该值设置为true(默认为true)时,控件将参与验证。否则,它不会 验证是焦点的一部分。当您不关注控件时,将触发其验证事件。事实上,焦点事件是按特定顺序触发的。发件人: 当您使用 键盘(TAB、SHIFT+TAB等), 通过调用Select或 选择下一步控制方法,或按 设定 ContainerControl.:.ActiveControl 属性设置为当前窗体的焦点 事件按以下顺序发生: 进入 戈特福克斯 离开 验证 验证

每个
控件
-派生对象都有两个名为
验证
验证
的事件。它还有一个名为的属性。当该值设置为true(默认为true)时,控件将参与验证。否则,它不会

验证是焦点的一部分。当您不关注控件时,将触发其验证事件。事实上,焦点事件是按特定顺序触发的。发件人:

当您使用 键盘(TAB、SHIFT+TAB等), 通过调用Select或 选择下一步控制方法,或按 设定 ContainerControl.:.ActiveControl 属性设置为当前窗体的焦点 事件按以下顺序发生:

  • 进入
  • 戈特福克斯
  • 离开
  • 验证
  • 验证
  • 失焦
  • 当您使用 鼠标或通过调用Focus方法, 焦点事件发生在以下几个方面: 订单:

  • 进入
  • 戈特福克斯
  • 失焦
  • 离开
  • 验证
  • 验证
  • 如果CausesValidation属性为 设置为false时,验证和 已验证的事件将被抑制

    如果 在中,CancelEventArgs设置为true 正在验证事件委托,所有事件 这通常发生在 验证事件被抑制


    此外,ContainerControl还有一个名为的方法,该方法将循环通过包含的控件,并验证它们。

    我意识到这个线程非常旧,但我想我会发布我提出的解决方案

    WinForms上验证的最大问题是,只有在控件“失去焦点”时才执行验证。因此,用户必须实际在文本框内单击,然后单击其他地方,以执行验证例程。如果您只关心输入的数据是否正确,则可以这样做。但是,如果您试图确保用户没有跳过文本框而将文本框留空,那么这种方法就不能很好地工作

    在我的解决方案中,当用户单击表单的submit按钮时,我检查表单上的每个控件(或指定的任何容器),并使用反射来确定是否为该控件定义了验证方法。如果是,则执行验证方法。如果任何验证失败,例程将返回失败并允许进程停止。此解决方案非常有效,尤其是当您需要验证多个表单时

    1) 只需将这段代码复制并粘贴到您的项目中。我们正在使用反射,因此您需要在using语句中添加System.Reflection

    class Validation
    {
        public static bool hasValidationErrors(System.Windows.Forms.Control.ControlCollection controls)
        {
            bool hasError = false;
    
            // Now we need to loop through the controls and deterime if any of them have errors
            foreach (Control control in controls)
            {
                // check the control and see what it returns
                bool validControl = IsValid(control);
                // If it's not valid then set the flag and keep going.  We want to get through all
                // the validators so they will display on the screen if errorProviders were used.
                if (!validControl)
                    hasError = true;
    
                // If its a container control then it may have children that need to be checked
                if (control.HasChildren)
                {
                    if (hasValidationErrors(control.Controls))
                        hasError = true;
                }
            }
            return hasError;
        }
    
        // Here, let's determine if the control has a validating method attached to it
        // and if it does, let's execute it and return the result
        private static bool IsValid(object eventSource)
        {
            string name = "EventValidating";
    
            Type targetType = eventSource.GetType();
    
            do
            {
                FieldInfo[] fields = targetType.GetFields(
                     BindingFlags.Static |
                     BindingFlags.Instance |
                     BindingFlags.NonPublic);
    
                foreach (FieldInfo field in fields)
                {
                    if (field.Name == name)
                    {
                        EventHandlerList eventHandlers = ((EventHandlerList)(eventSource.GetType().GetProperty("Events",
                            (BindingFlags.FlattenHierarchy |
                            (BindingFlags.NonPublic | BindingFlags.Instance))).GetValue(eventSource, null)));
    
                        Delegate d = eventHandlers[field.GetValue(eventSource)];
    
                        if ((!(d == null)))
                        {
                            Delegate[] subscribers = d.GetInvocationList();
    
                            // ok we found the validation event,  let's get the event method and call it
                            foreach (Delegate d1 in subscribers)
                            {
                                // create the parameters
                                object sender = eventSource;
                                CancelEventArgs eventArgs = new CancelEventArgs();
                                eventArgs.Cancel = false;
                                object[] parameters = new object[2];
                                parameters[0] = sender;
                                parameters[1] = eventArgs;
                                // call the method
                                d1.DynamicInvoke(parameters);
                                // if the validation failed we need to return that failure
                                if (eventArgs.Cancel)
                                    return false;
                                else
                                    return true;
                            }
                        }
                    }
                }
    
                targetType = targetType.BaseType;
    
            } while (targetType != null);
    
            return true;
        }
    
    }
    
    2) 对任何要验证的控件使用标准验证事件确认失败时,请务必使用e.取消

    private void txtLastName_Validating(object sender, CancelEventArgs e)
        {
            if (txtLastName.Text.Trim() == String.Empty)
            {
                errorProvider1.SetError(txtLastName, "Last Name is Required");
                e.Cancel = true;
            }
            else
                errorProvider1.SetError(txtLastName, "");
        }
    
    3) 不要跳过这一步将表单上的自动验证属性设置为启用AllowFocusChange。这将允许在验证失败时切换到另一个控件

    4) 最后,在Submit按钮方法中,调用Validation方法并指定要检查的容器。它可以是整个表单,也可以只是表单上的一个容器,如面板或组

    private void btnSubmit_Click(object sender, EventArgs e)
        {
            // the controls collection can be the whole form or just a panel or group
            if (Validation.hasValidationErrors(frmMain.Controls))
                return;
    
            // if we get here the validation passed
            this.close();
        }
    

    快乐编码

    如果将上述思想与通用验证事件处理程序相结合,您将获得一个良好的验证错误“框架”,其中包含业务类中的所有验证方法。我刚刚用丹麦的想法扩展了Bruce代码。 对实体框架和devexpress组件进行了测试,但是可以轻松删除这些依赖项。 享受吧

    公共类验证管理器
    {
    /// 
    ///调用此方法以验证给定控件列表的所有控件
    ///验证事件将在每个事件上调用
    /// 
    /// 
    /// 
    公共静态bool hasvalidateErrors(System.Windows.Forms.Control.ControlCollection控件)
    {
    bool hasrerror=false;
    //现在我们需要遍历控件并确定它们是否有错误
    foreach(控件中的控件)
    {
    //检查控件并查看它返回的内容
    bool validControl=IsValid(控制);
    //如果无效,则设置标志并继续。我们希望通过所有测试
    //如果使用了errorProviders,验证程序将显示在屏幕上。
    如果(!validControl)
    hasrerror=true;
    //如果它是一个容器控件,那么它可能有需要检查的子项
    if(control.HasChildren)
    {
    if(HasValidationErrors(control.Controls))
    hasrerror=true;
    }
    }
    返回错误;
    }
    /// 
    ///将所有正在验证的事件附加到此事件处理程序(如果控件需要验证)
    ///将在绑定的业务实体上搜索名为Validate+PropertyName的方法,如果找到,则调用该方法
    ///如果在方法逻辑中检测到验证错误,则引发包含所需消息的异常
    /// 
    /// 
    /// 
    公共静态void ValidationHandler(对象发送方,CancelEventArgs e)
    {
    BaseEdit控件=发送方为BaseEdit;
    如果(control.DataBindings.Count>0)//控件已绑定
    {
    string bindedFieldName=control.DataBindings[0].BindingMemberInfo.BindingField;
    object BindeObject=control.BindingManager.Current;
    如果(bindeObject!=null)//控件绑定到对象实例
    {
    //查找并调用name=Validate+PropertyName的方法
    MethodInfo validationMethod=(来自bindeObject.GetType().GetMethods()中的方法)
    其中method.IsPublic&&
    method.Name==String.Format(“验证{0}”,bindedFieldName)&&
    
    class Validation
    {
        public static bool hasValidationErrors(System.Windows.Forms.Control.ControlCollection controls)
        {
            bool hasError = false;
    
            // Now we need to loop through the controls and deterime if any of them have errors
            foreach (Control control in controls)
            {
                // check the control and see what it returns
                bool validControl = IsValid(control);
                // If it's not valid then set the flag and keep going.  We want to get through all
                // the validators so they will display on the screen if errorProviders were used.
                if (!validControl)
                    hasError = true;
    
                // If its a container control then it may have children that need to be checked
                if (control.HasChildren)
                {
                    if (hasValidationErrors(control.Controls))
                        hasError = true;
                }
            }
            return hasError;
        }
    
        // Here, let's determine if the control has a validating method attached to it
        // and if it does, let's execute it and return the result
        private static bool IsValid(object eventSource)
        {
            string name = "EventValidating";
    
            Type targetType = eventSource.GetType();
    
            do
            {
                FieldInfo[] fields = targetType.GetFields(
                     BindingFlags.Static |
                     BindingFlags.Instance |
                     BindingFlags.NonPublic);
    
                foreach (FieldInfo field in fields)
                {
                    if (field.Name == name)
                    {
                        EventHandlerList eventHandlers = ((EventHandlerList)(eventSource.GetType().GetProperty("Events",
                            (BindingFlags.FlattenHierarchy |
                            (BindingFlags.NonPublic | BindingFlags.Instance))).GetValue(eventSource, null)));
    
                        Delegate d = eventHandlers[field.GetValue(eventSource)];
    
                        if ((!(d == null)))
                        {
                            Delegate[] subscribers = d.GetInvocationList();
    
                            // ok we found the validation event,  let's get the event method and call it
                            foreach (Delegate d1 in subscribers)
                            {
                                // create the parameters
                                object sender = eventSource;
                                CancelEventArgs eventArgs = new CancelEventArgs();
                                eventArgs.Cancel = false;
                                object[] parameters = new object[2];
                                parameters[0] = sender;
                                parameters[1] = eventArgs;
                                // call the method
                                d1.DynamicInvoke(parameters);
                                // if the validation failed we need to return that failure
                                if (eventArgs.Cancel)
                                    return false;
                                else
                                    return true;
                            }
                        }
                    }
                }
    
                targetType = targetType.BaseType;
    
            } while (targetType != null);
    
            return true;
        }
    
    }
    
    private void txtLastName_Validating(object sender, CancelEventArgs e)
        {
            if (txtLastName.Text.Trim() == String.Empty)
            {
                errorProvider1.SetError(txtLastName, "Last Name is Required");
                e.Cancel = true;
            }
            else
                errorProvider1.SetError(txtLastName, "");
        }
    
    private void btnSubmit_Click(object sender, EventArgs e)
        {
            // the controls collection can be the whole form or just a panel or group
            if (Validation.hasValidationErrors(frmMain.Controls))
                return;
    
            // if we get here the validation passed
            this.close();
        }