首页 > 解决方案 > 从 ViewModel 绑定 ValidationRule

问题描述

我需要使用 ModelView 中的列表“lFx”

<TextBox Grid.Row="2" Grid.Column="0"
         Style="{StaticResource StyleTxtErr}"
         Validation.ErrorTemplate="{StaticResource ValidationGrp}"
         >
    <TextBox.Text>
        <Binding Path="sGrp" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
         <Binding.ValidationRules>
                <local:cDataGrpRule lFx="{Binding lFx}"/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

实际上,这段代码在 '<local:cDataGrpRule ...' 行向我显示了这个错误
A binding cannot be set to lFx, ...
A binding can only be set to DependencyProperty of a DependenxyObject

如何使用 ViewModel 中设置的对象初始化我的 ValidationRule 对象?

提前致谢。埃里克。

标签: wpfvalidationdata-binding

解决方案


由于您只能绑定到依赖属性,如错误消息所述,您将创建一个派生自DependencyObject并公开依赖属性的包装类。

您还需要一个捕获当前的代理对象DataContext

public class BindingProxy : Freezable
{
    protected override Freezable CreateInstanceCore() => new BindingProxy();

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy),
        new PropertyMetadata(null));
}

然后将 CLR 属性添加到ValidationRule返回此包装类型实例的类中:

public class cDataGrpRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        //your validation logic...
        return ValidationResult.ValidResult;
    }

    public Wrapper Wrapper { get; set; }
}

public class Wrapper : DependencyObject
{
    public static readonly DependencyProperty lFxProperty =
         DependencyProperty.Register("lFx", typeof(object), typeof(Wrapper));

    public object lFx
    {
        get { return GetValue(lFxProperty); }
        set { SetValue(lFxProperty, value); }
    }
}

您可能需要考虑重命名属性以符合 C# 命名约定。

XAML:

<TextBox Grid.Row="2" Grid.Column="0"
         Style="{StaticResource StyleTxtErr}"
         Validation.ErrorTemplate="{StaticResource ValidationGrp}">
    <TextBox.Resources>
        <local:BindingProxy x:Key="proxy" Data="{Binding}"/>
    </TextBox.Resources>
    <TextBox.Text>
        <Binding Path="sGrp" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <local:cDataGrpRule>
                    <local:cDataGrpRule.Wrapper>
                        <local:Wrapper lFx="{Binding Data.lFx, Source={StaticResource proxy}}"/>
                    </local:cDataGrpRule.Wrapper>
                </local:cDataGrpRule>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

请参阅本文以获取更多信息和完整示例。


推荐阅读