WPF DependencyProperty验证绑定到对象属性



我正在尝试为给定控件创建一个验证规则(在本场景中,它是TextBox)。

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

请在下面找到代码。需要注意的是,自定义Validation类中的"is Required"始终为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);
}
}

您可以使用代理。它将允许您将属性绑定到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>

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

这个问题的解决方案基于以下内容托马斯·莱维斯克的文章: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对象的。

还有另一种实现控件验证的方法。然而,我仍然想知道如何解决我最初的问题,所以任何帮助都将不胜感激。

另一种方法是实现模型的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;
}
}
自定义Validation类中的"Is Required"始终为False,因为它没有设置。false是bool的默认值。

发件人http://www.codeproject.com/Articles/18678/Attaching-a-Virtual-Branch-to-the-Logical-Tree-in

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

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

相关内容

  • 没有找到相关文章

最新更新