【问题标题】:WPF: Binding to validation rule's DependencyPropertyWPF:绑定到验证规则的 DependencyProperty
【发布时间】:2017-08-28 13:22:02
【问题描述】:

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

我有验证规则:

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 中,适当的 ViemModel 放置在控件 DataContext 中。

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

【问题讨论】:

  • 如果您需要可配置的MinMax,让它们查看模型属性以及Value
  • 是的,它们在虚拟机中。但我无法将 VM 属性绑定到验证 Min、Max DPs。

标签: c# wpf data-binding dependency-properties


【解决方案1】:

问题是 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>

【讨论】:

  • 太棒了。非常感谢。花了几个小时在它周围跳舞,最后!
猜你喜欢
  • 2023-03-25
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 2013-01-20
  • 2011-05-20
  • 2014-04-27
相关资源
最近更新 更多