1

我正在尝试为给定控件创建验证规则(在这种情况下,它是 TextBox)。

尽管采取了适当的步骤,但我无法成功绑定到对象的属性:利用了 ValidationRule 和 DepedencyProperty。

请在下面找到代码。附带说明的是,自定义验证类中的“必需”始终为 False,除非我在 XAML 中明确设置值(没有绑定,根据“Is Ranged”参数)。

任何提示和建议表示赞赏。

先感谢您 :)

XAML 代码:

<TextBox Style="{StaticResource ValidationError}" LostFocus="ForceValidationCheck"
         Visibility="{Binding Type, Converter={StaticResource Visibility}, ConverterParameter='Number'}"
         IsEnabled="{Binding RelativeSource={x:Static RelativeSource.Self}, Converter={StaticResource IsEnabled}}">
    <TextBox.Text>
        <Binding Path="Value">
            <Binding.ValidationRules>
                <validation:NumericValidation>
                    <validation:NumericValidation.Dependency>
                        <validation:NumericDependency IsRequired="{Binding Path=IsRequired}" IsRanged="True" Min="5"/>
                    </validation:NumericValidation.Dependency>
                </validation:NumericValidation>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

验证类:

public NumericDependency Dependency { get; set; }

public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
    isRequired = Dependency.IsRequired;
}

验证依赖类:

public static readonly DependencyProperty IsRequiredProperty =
        DependencyProperty.Register("IsRequired", typeof(bool), typeof(NumericDependency), new UIPropertyMetadata(default(bool)));

public bool IsRequired
{
    get
    {
        return (bool) GetValue(IsRequiredProperty);
    }
    set
    {
        SetValue(IsRequiredProperty, value);
    }
}
4

4 回答 4

3

您可以使用代理。它将允许您将属性绑定到您的 ValidationRule。

代理示例

这是一个可以帮助您的代码示例:

<Utils:Proxy In="{Binding IsRequired, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" Out="{Binding ElementName=numericValidationRule, Path=IsRequired}" />
<TextBox>
    <TextBox.Text>
        <Binding Path="Value">
            <Binding.ValidationRules>
                <NumericValidation x:Name="numericValidationRule" />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>
于 2013-06-26T12:34:19.487 回答
1

IsRequired 始终为 false,因为“依赖”对象不是逻辑树的一部分,因此您不能使用 ElementName 或 DataContext 作为内部数据绑定的源。

此问题的解决方案基于以下 Thomas Levesque 的文章:http ://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-未继承/

您必须创建一个继承“Freezable”并声明数据依赖属性的类。Freezable 类的有趣特性是 Freezable 对象可以继承 DataContext,即使它们不在可视树或逻辑树中:

public class BindingProxy : Freezable
{
   #region Overrides of Freezable
   protected override Freezable CreateInstanceCore()
   {
      return new BindingProxy();
   }
   #endregion

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

   // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
   public static readonly DependencyProperty DataProperty =
      DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

然后,您可以在文本框的资源中声明此类的实例,并将 Data 属性绑定到当前 DataContext:

<TextBox.Resources>
   <local:BindingProxy x:Key="proxy" Data="{Binding}"/>
<TextBox.Resources/>

最后,将此 BindingProxy 对象指定为绑定的 Source:

<validation:NumericDependency IsRequired="{Binding Source={StaticResource proxy} Path=Data.IsRequired}" IsRanged="True" Min="5"/>

请注意,绑定路径必须以“Data”为前缀,因为该路径现在是相对于 BindingProxy 对象的。

于 2015-02-06T19:34:07.310 回答
0

还有另一种实现控件验证的方法。但是,我仍然想知道如何解决我最初的问题,因此感谢您提供任何帮助。

另一种方法是实现模型的 IDataErrorInfo 接口。

例子:

public string this[string columnName]
{
    get
    {
        if (string.Equals(columnName, "Value", StringComparison.CurrentCultureIgnoreCase))
        {
            string value = Convert.ToString(Value);

            if (string.IsNullOrEmpty(value) && IsRequired)
            {
                return ValidationMessage.RequiredValue;
            }
        }

        return string.Empty;
    }
}
于 2012-12-06T09:35:16.200 回答
0

自定义验证类中的“是必需的”始终为 False,因为它没有设置。false 是 bool 的默认值。

来自http://www.codeproject.com/Articles/18678/Attaching-a-Virtual-Branch-to-the-Logical-Tree-in

ValidationRule 甚至没有 DataContext 属性,因为它不是从 FrameworkElement 派生的!

请注意,IntegerContainer 是一个 FrameworkElement,而不是一个依赖对象。

于 2014-03-18T10:29:02.370 回答