WPF DependencyProperty验证绑定到对象属性

时间:2012-12-05 14:16:54

标签: wpf validation binding validationrules dependencyobject

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

虽然采取了适当的步骤,但我无法获得对对象属性的成功绑定:ValidationRule和DepedencyProperty被利用。

请在下面找到代码。旁注是自定义Validation类中的“Is Required”始终为False,除非我在XAML中显式设置了值(没有Binding,根据“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 个答案:

答案 0 :(得分:3)

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

Proxy example

以下是可能对您有所帮助的代码示例:

<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>

答案 1 :(得分:1)

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

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

您必须创建一个继承“Freezable”的类并声明一个Data依赖项属性。 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对象指定为绑定的源:

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

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

答案 2 :(得分: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;
    }
}

答案 3 :(得分:0)

&#34;是必需的&#34;在自定义Validation类中始终为False,因为它未设置。 false是bool的默认值。

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

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

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