Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.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
整个表单的WPF验证_Wpf_Validation - Fatal编程技术网

整个表单的WPF验证

整个表单的WPF验证,wpf,validation,Wpf,Validation,我对WPF验证系统非常失望。无论如何如何通过单击“按钮”验证完整的表单 由于某些原因,WPF中的所有内容都非常复杂!我可以在ASP.NET中用一行代码进行验证,这需要WPF中10-20行代码 我可以使用自己的ValidationEngine框架来实现这一点: Customer customer = new Customer(); customer.FirstName = "John"; customer.LastName = String.Empty; ValidationEngine.Val

我对WPF验证系统非常失望。无论如何如何通过单击“按钮”验证完整的表单

由于某些原因,WPF中的所有内容都非常复杂!我可以在ASP.NET中用一行代码进行验证,这需要WPF中10-20行代码

我可以使用自己的ValidationEngine框架来实现这一点:

Customer customer = new Customer();
customer.FirstName = "John";
customer.LastName = String.Empty;

ValidationEngine.Validate(customer);

if (customer.BrokenRules.Count > 0)
{
   // do something display the broken rules! 
}

我建议您在业务对象上查看IDataErrorInfo接口。请看这篇文章:

对您的问题的描述对我来说有点模糊。我是说,我不确定你的困难是什么。 假设DataContext是某种具有表示客户实例的属性的presenter或controller,ValidateCommand是ICommand类型的属性:

  <StackPanel>  
    <TextBox Text="{Binding CurrentCustomer.FirstName}" />
    <TextBox Text="{Binding CurrentCustomer.LastName}" />
    <Button Content="Validate" 
            Command="{Binding ValidateCommand}"
            CommandParameter="{Binding CurrentCustomer}" />
    <ItemsControl ItemsSource="{Binding CurrentCustomer.BrokenRules}" />
  </StackPanel>

当然,这个XAML是非常简化的,还有其他方法可以做到这一点。
作为一名现在大量参与WPF的Web开发人员,我发现在WPF中这样的任务要容易得多。

如果输入的数据无效,WPF应用程序应该禁用提交表单的按钮。您可以通过在业务对象上实现接口来实现这一点,使用
=true
的绑定。要在出现错误时自定义单个控件的外观,请设置

XAML: 一个明显的改进是将
IDataErrorInfo
实现向上移动到类层次结构中,因为它只依赖于
ValidationEngine
,而不依赖于业务对象


虽然这确实比您提供的简单示例中的代码要多,但它的功能也比只检查有效性要多得多。这将为用户提供细粒度的、自动更新的有关验证问题的指示,并在用户尝试输入无效数据时自动禁用“保存”按钮。

您可能对图书库示例应用程序感兴趣。它显示了如何在WPF中使用验证,以及在存在验证错误时如何控制“保存”按钮。

ValidatesOnDaerRor用于根据视图模型验证业务规则,并且仅当绑定成功时才会验证

ValidatesOnExceptions需要与ValidateSondaerRor一起应用,以处理wpf由于数据类型不匹配而无法执行绑定的场景,假设您希望将文本框绑定到视图模型中的Age(integer)属性

<TextBox Text="{Binding Age, ValidatesOnDataErrors=true, UpdateSourceTrigger=PropertyChanged}" />

如果用户通过键入字母而不是数字作为年龄(例如xyz)输入无效条目,wpf数据绑定将自动忽略该值,因为它无法将xyz绑定到年龄,并且绑定错误将丢失,除非绑定用


ValidatesOnException使用ExceptionValidationRule对绑定错误使用默认异常处理,上面的语法是以下语法的缩写

<TextBox>
    <TextBox.Text>
        <Binding Path="Age" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
            <Binding.ValidationRules>
                  <ExceptionValidationRule />
             </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

您可以通过从ValidationRule派生并实现下面示例中的validate方法NumericRule,来定义自己的规则以根据用户输入进行验证

<TextBox.Text>
 <Binding Path="Age" ValidatesOnDataErrors="True">
   <Binding.ValidationRules>
        <rules:NumericRule />
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>

验证规则应该是通用的,而不是与业务相关的,因为后者是通过IDataErrorInfo和ValidateSondaerRor完成的


与我们的单行绑定语法相比,上面的语法相当混乱,通过将ValidationRule作为附加属性实现,语法可以得到改进,您可以查看它

当我需要确保所有字段都已填充时,这似乎太多了。如果您只需要确保所有字段都已填充,您可以将验证代码放入submit按钮的Click处理程序中。但是你的用户会问“为什么我不能提交表单?”你仍然需要实现所有的通知和东西。如果所有这些都是文本框或输入控件的一部分,那么这是合乎逻辑的。与此类似,验证规则也是数据模型的一部分,而不是GUI。必须能够在没有GUI的情况下检查对象的有效性。例如,考虑面向批处理的数据处理器。这就是我的观点!WPF可以使用绑定并设置validateSondaerRors=true和/或ValidatesOnException=true,将验证委托给域级别。我的回答说明了一种方法。
<TextBox Text="{Binding Age, ValidatesOnDataErrors=true, ValidatesOnExceptions="True", UpdateSourceTrigger=PropertyChanged}" />
<TextBox>
    <TextBox.Text>
        <Binding Path="Age" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
            <Binding.ValidationRules>
                  <ExceptionValidationRule />
             </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>
<TextBox.Text>
 <Binding Path="Age" ValidatesOnDataErrors="True">
   <Binding.ValidationRules>
        <rules:NumericRule />
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>