我正在尝试为给定控件创建验证规则(在这种情况下,它是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);
}
}
答案 0 :(得分:3)
您可以使用代理。它允许您将Property绑定到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>
答案 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,而不是依赖对象。