WPF:绑定到验证规则的DependencyProperty

3

我想根据标准规则验证文本框的值,其中一些规则是最小值和最大值。问题是,我需要将这些值可配置化(例如在设置文件中)。

我有验证规则:

public class TextBoxWithIntegerValidation : ValidationRule
    {
        private Int32RangeChecker _validRange;

        public Int32RangeChecker ValidRange
        {
            get { return _validRange; }
            set { _validRange = value; }
        }

        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            var str = value as string;
            if (str == null)
            {
                return new ValidationResult(false, Resources.TextResources.TextBoxIsEmpty_ErrorMessage);
            }

            int intValue = -1;
            if (!int.TryParse(str, out intValue))
            {
                return new ValidationResult(false, Resources.TextResources.TextBoxNotIntegerValue_ErrorMessage);
            }

            if (intValue < ValidRange.Minimum)
            {
                return new ValidationResult(false, 
                    string.Format(Resources.TextResources.TextBoxValueLowerThanMin_ErrorMessage, ValidRange.Minimum));
            }

            return new ValidationResult(true, null);
        }
    }

整数范围检查器:
 public class Int32RangeChecker : DependencyObject
{
    public int Minimum
    {
        get { return (int)GetValue(MinimumProperty); }
        set { SetValue(MinimumProperty, value); }
    }

    public static readonly DependencyProperty MinimumProperty =
        DependencyProperty.Register("Minimum", typeof(int), typeof(Int32RangeChecker), new UIPropertyMetadata(0));

    public int Maximum
    {
        get { return (int)GetValue(MaximumProperty); }
        set { SetValue(MaximumProperty, value); }
    }

    public static readonly DependencyProperty MaximumProperty =
        DependencyProperty.Register("Maximum", typeof(int), typeof(Int32RangeChecker), new UIPropertyMetadata(100));

}

并且文本框验证:

<TextBox>
<TextBox.Text>
    <Binding Path="Interval" UpdateSourceTrigger="PropertyChanged" ValidatesOnNotifyDataErrors="True">
        <Binding.ValidationRules>
            <validationRules:TextBoxWithIntegerValidation>
                <validationRules:TextBoxWithIntegerValidation.ValidRange>
                    <validationRules:Int32RangeChecker
                            Minimum="{Binding IntervalMinValue}"
                        />
                </validationRules:TextBoxWithIntegerValidation.ValidRange>
            </validationRules:TextBoxWithIntegerValidation>
        </Binding.ValidationRules>
    </Binding>
</TextBox.Text>

将TextBox放置在UserControl中,并在控件DataContext中放置适当的ViemModel。

问题是:属性IntervalMinValue未绑定到验证规则。如果我手动设置它-可以正常工作,但无法使用绑定。


如果您需要可配置的“Min”和“Max”,请将它们作为视图模型属性,以及“Value”。 - Dennis
是的,它们在虚拟机中。但是我无法将虚拟机属性绑定到验证的最小值和最大值数据点。 - Alex
1个回答

7
问题在于Int32RangeChecker对象附加到一个不属于可视树的对象上,因此无法访问视图模型。如果查看输出窗口,您将看到以下错误...
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=IntervalMinValue; DataItem=null; target element is 'Int32RangeChecker' (HashCode=32972388); target property is 'Minimum' (type 'Int32')

要修复这个问题,您需要将Minimum属性的绑定连接到可视树中的一个元素。一种方法是添加一个不可见的虚拟元素,并在其上绑定数据上下文...
    <FrameworkElement x:Name="dummyElement" Visibility="Hidden"/>
    <TextBox>
        <TextBox.Text>
            <Binding Path="Interval" UpdateSourceTrigger="PropertyChanged" ValidatesOnNotifyDataErrors="True">
                <Binding.ValidationRules>
                    <local:TextBoxWithIntegerValidation>
                        <local:TextBoxWithIntegerValidation.ValidRange>
                            <local:Int32RangeChecker
                        Minimum="{Binding Source={x:Reference dummyElement}, Path=DataContext.IntervalMinValue}"
                    />
                        </local:TextBoxWithIntegerValidation.ValidRange>
                    </local:TextBoxWithIntegerValidation>
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>

太棒了。非常感谢。花了好几个小时绕来绕去,终于搞定了! - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接