首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有依赖属性的WPF ValidationRule

具有依赖属性的WPF ValidationRule
EN

Stack Overflow用户
提问于 2010-10-05 09:28:15
回答 1查看 18.7K关注 0票数 21

假设您有一个从ValidationRule继承的类:

代码语言:javascript
复制
public class MyValidationRule : ValidationRule
{
    public string ValidationType { get; set; }
    
    public override ValidationResult Validate(object value, CultureInfo cultureInfo) {}
}

在XAML中,您的验证如下:

代码语言:javascript
复制
<ComboBox.SelectedItem>
    <Binding Path="MyPath" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
        <Binding.ValidationRules>
            <qmvalidation:MyValidationRule  ValidationType="notnull"/>
        </Binding.ValidationRules>
    </Binding>
</ComboBox.SelectedItem>

一切都很好。

但假设现在,您希望有ValidationType="{Binding MyBinding}",而MyBinding来自DataContext

为此,我需要将MyValidationRule作为一个DependencyObject,并添加一个依赖项属性

我试图编写一个类,即DependencyObject,并绑定它。但是有两个问题..。ValidationRule没有来自Combobox / Item的DataContext

你对如何解决这个问题有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2016-07-13 13:31:31

由于ValidationRule不是从DependencyObject继承的,所以不能在自定义验证类中创建DependecyProperty

但是,正如在此链接中解释的那样,验证类中可以有一个正常的属性,它的类型是从DependecyObject继承并在该类中创建DependencyProperty的类型。

例如,这里有一个支持可绑定属性的自定义ValidationRule类:

代码语言:javascript
复制
[ContentProperty("ComparisonValue")]
public class GreaterThanValidationRule : ValidationRule
{
    public ComparisonValue ComparisonValue { get; set; }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        string s = value?.ToString();
        int number;

        if (!Int32.TryParse(s, out number))
        {
            return new ValidationResult(false, "Not a valid entry");
        }

        if (number <= ComparisonValue.Value)
        {
            return new ValidationResult(false, $"Number should be greater than {ComparisonValue}");
        }

        return ValidationResult.ValidResult;
    }
}

ComparisonValue是一个简单的类,它继承自DependencyObject,并具有一个DependencyProperty

代码语言:javascript
复制
public class ComparisonValue : DependencyObject
{
    public int Value
    {
        get { return (int)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }
    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
        nameof(Value),
        typeof(int),
        typeof(ComparisonValue),
        new PropertyMetadata(default(int));

这解决了原来的问题,但不幸的是,它带来了另外两个问题:

  1. 绑定不能正常工作,因为ValidationRules不是可视树的一部分,因此无法正确地获得绑定属性。例如,这种天真的方法不起作用: <:比较值Value="{Binding Text,ElementName=TextBoxToValidate}"/> :GreaterThanValidationRule> 相反,应该使用代理对象,如答案中所解释的那样: BindingProxy是一个简单的类: 公共类BindingProxy :可冻结的{受保护的覆盖可冻结的CreateInstanceCore() {返回新的BindingProxy();}公共对象数据{ get {返回GetValue( DataProperty );} set { SetValue(DataProperty,值);}公共静态只读DependencyProperty DataProperty=DependencyProperty.Register(名称(数据)、类型(对象)、类型(BindingProxy)、新的UIPropertyMetadata(null));}
  2. 如果自定义ValidationRule中的属性绑定到另一个对象的属性,则当其他对象的属性更改时,原始属性的验证逻辑将不会触发。 为了解决这个问题,我们应该在更新ValidationRule的绑定属性时更新绑定。首先,我们应该将该属性绑定到我们的ComparisonValue类。然后,当Value属性发生变化时,我们可以更新绑定的源: 公共类ComparisonValue : DependencyObject { public int值{ get { class (int)GetValue( ValueProperty );} set { SetValue(ValueProperty,value);}公共静态只读DependencyProperty ValueProperty= DependencyProperty.Register(名称(值)、类型(Int)、类型(ComparisonValue)、新PropertyMetadata(默认值(Int)、OnValueChanged));私有静态空OnValueChanged(DependencyObject d,DependencyPropertyChangedEventArgs e) { ComparisonValue comparisonValue = (ComparisonValue) d;BindingExpressionBase bindingExpressionBase =ComparisonValue BindingToTriggerProperty;bindingExpressionBase?.UpdateSource();}公共对象BindingToTrigger { get {value( BindingToTriggerProperty);} set { SetValue(BindingToTriggerProperty,value);}公共静态只读FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));BindingToTriggerProperty = DependencyProperty.Register(名称(BindingToTrigger)、类型(对象)、类型(ComparisonValue)、新FrameworkPropertyMetadata(默认(对象))、BindingToTriggerProperty} 在第一种情况下,同样的代理问题也存在于这里。因此,我们应该创建另一个代理对象: {en19#}}“”{Binding,Source={StaticResource SourceProxy}}"/> 在这种情况下,Text属性TextBoxToValidate将根据SomeCollectionItems.Count属性进行验证。当列表中的项数发生变化时,将触发Text属性的验证。
票数 34
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3862385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档