Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.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

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
C# WPF Binding.ValidationRules基于条件_C#_Wpf - Fatal编程技术网

C# WPF Binding.ValidationRules基于条件

C# WPF Binding.ValidationRules基于条件,c#,wpf,C#,Wpf,我目前有一个带有Binding.ValidationRules的文本框,它的工作方式如下 <TextBox> <Binding Path="MyID" NotifyOnValidationError="True" ValidatesOnDataErrors="True" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnSourceUpdated="True"

我目前有一个带有Binding.ValidationRules的文本框,它的工作方式如下

<TextBox>
    <Binding Path="MyID" NotifyOnValidationError="True" ValidatesOnDataErrors="True" 
             Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnSourceUpdated="True" 
             NotifyOnTargetUpdated="True" Delay="100">
        <Binding.ValidationRules>
            <local:IDValidator ValidatesOnTargetUpdated="True" table="Items"  />
        </Binding.ValidationRules>
    </Binding>
</TextBox>
问题是在某些条件下,我希望IDValidator成为ValidationRule。其他时候,我可能想说IDValidator2是ValidationRule

现在我找不到一个方法来完成这个。所以我想,为什么不发送另一个值到IDValidator,然后在Validate的逻辑中处理它,如下所示:

XMAL更新:

<local:IDValidator ValidatesOnTargetUpdated="True" table="Items" testing="{Binding Path=test}"  />

问题是它似乎不喜欢向下发送绑定值。我怎样才能做到这一点呢?

这是可行的,但它不是很简单,有一些你可能无法预料的问题。根本问题是动态绑定只能应用于从DependencyObject派生的对象。ValidationRule不是这样的对象。但是,我们可以向自定义ValidationRule添加一个属性,该规则公开从DependencyObject派生的类。举例说明:

公共类IDValidator:ValidationRule { 专用IDValidatorRange\u范围; public int MinLength{get;set;} 公共int MaxLength{get;set;} 公共IDV范围 { 获取{return\u range;} 设置 { _范围=数值; 值?设置此值; } } 公共重写ValidationResult Validateobject值,CultureInfo CultureInfo { //逻辑 } } 注意从Range属性返回的IDValidatorRange对象。您将需要使用DependencyProperties和更新IDValidator规则属性的机制来创建此类。以下是此类课程的一个示例:

公共类IDValidatorRange:可冻结 { 公共静态只读DependencyProperty MinLengthProperty=DependencyProperty.Register MinLength、typeof int、typeof IDValidatorRange、新的FrameworkPropertyMetadata5、OnMinLengthChanged; 公共静态只读DependencyProperty MaxLengthProperty=DependencyProperty.Register MaxLength、typeof int、typeof IDValidatorRange、新的FrameworkPropertyMetadata10、OnMaxLength已更改; 公共无效setValidator验证程序IDValidator验证程序 { 验证器=验证器; 如果验证程序!=null { validator.MinLength=最小长度; validator.MaxLength=MaxLength; } } 公共整数最大长度 { 获取{return int GetValueMaxLengthProperty;} set{SetValueMaxLengthProperty,value;} } 公共整数最小长度 { 获取{return int GetValueMinLengthProperty;} set{SetValueMinLengthProperty,value;} } 私有IDValidator验证程序{get;set;} MaxLengthChangedPendencyObject d上的私有静态无效,DependencyPropertyChangedEventArgs e { var范围=IDD范围; 如果range.Validator!=null { range.Validator.MaxLength=int e.NewValue; } } MinlLengthChangedDependencyObject d上的私有静态无效,DependencyPropertyChangedEventArgs e { var范围=IDD范围; 如果range.Validator!=null { range.Validator.MinLength=int e.NewValue; } } 受保护的重写Freezable CreateInstanceCore { 返回新的IDV范围; } } 您可以看到,我是从Freezable派生的,而不是它的祖先DependencyObject,因为我们希望为绑定继承DataContext。DependencyObject不提供此功能,但Freezable提供此功能

最后,我们可以在XAML中将这一切放在一起,如下所示:

最后一个问题是,由于验证规则不保存或继承DataContext,如果您试图声明与规则内联的所有内容,这将阻止绑定按预期工作。相反,将可绑定规则选项声明为资源,并使用StaticBinding在自定义规则上设置属性


这种方法需要大量工作,而且有点混乱。如果您的双手不受数据上下文的束缚,我建议您探索其他选项。在视图模型上使用INotifyDataErrorInfo接口可能是解决此问题的一种更优雅的方法。

这是可行的,但它不是很简单,并且有一些您可能无法预料的问题。根本问题是动态绑定只能应用于从DependencyObject派生的对象。ValidationRule不是这样的对象。但是,我们可以向自定义ValidationRule添加一个属性,该规则公开从DependencyObject派生的类。举例说明:

公共类IDValidator:ValidationRule { 专用IDValidatorRange\u范围; public int MinLength{get;set;} 公共int MaxLength{get;set;} 公共IDV范围 { 获取{return\u range;} 设置 { _范围=数值; 值?设置此值; } } 公共重写ValidationResult Validateobject值,CultureInfo CultureInfo { //逻辑 } } 注意从Range属性返回的IDValidatorRange对象。您将需要使用DependencyProperties和更新IDValidator规则属性的机制来创建此类。以下是此类课程的一个示例:

公共类IDValidatorRange:可冻结 { 公共静态只读DependencyProperty MinLengthProperty=DependencyProperty.Register MinLength、typeof int、typeof IDValidatorRange、新的FrameworkPropertyMetadata5、OnMinLengthChanged; 公共静态只读DependencyProperty MaxLengthProperty=DependencyProperty.Register MaxLength、typeof int、typeof IDValidatorRange、新的FrameworkPropertyMetadata10、OnMaxLength已更改; 公共无效setValidator验证程序IDValidator验证程序 { 验证器=验证器; 如果验证程序!=null { validator.MinLength=最小长度; validator.MaxLength=MaxLength; } } 公共整数最大长度 { 获取{return int GetValueMaxLengthProperty;} set{SetValueMaxLengthProperty,value;} } 公共整数最小长度 { 获取{return int GetValueMinLengthProperty;} set{SetValueMinLengthProperty,value;} } 私有IDValidator验证程序{get;set;} MaxLengthChangedPendencyObject d上的私有静态无效,DependencyPropertyChangedEventArgs e { var范围=IDD范围; 如果range.Validator!=null { range.Validator.MaxLength=int e.NewValue; } } MinlLengthChangedDependencyObject d上的私有静态无效,DependencyPropertyChangedEventArgs e { var范围=IDD范围; 如果range.Validator!=null { range.Validator.MinLength=int e.NewValue; } } 受保护的重写Freezable CreateInstanceCore { 返回新的IDV范围; } } 您可以看到,我是从Freezable派生的,而不是它的祖先DependencyObject,因为我们希望为绑定继承DataContext。DependencyObject不提供此功能,但Freezable提供此功能

最后,我们可以在XAML中将这一切放在一起,如下所示:

最后一个问题是,由于验证规则不保存或继承DataContext,如果您试图声明与规则内联的所有内容,这将阻止绑定按预期工作。相反,将可绑定规则选项声明为资源,并使用StaticBinding在自定义规则上设置属性


这种方法需要大量工作,而且有点混乱。如果您的双手不受数据上下文的束缚,我建议您探索其他选项。在视图模型上使用INotifyDataErrorInfo接口可能是解决此问题的更优雅的方法。

测试作为道具存在于ID所在的同一对象上?测试作为道具存在于ID所在的同一对象上?
<local:IDValidator ValidatesOnTargetUpdated="True" table="Items" testing="{Binding Path=test}"  />
public string testing { get; set; }