将文本框中的值传递给ValidationRule



我有两个文本框控件(如下所示),并希望将第一个文本框[x:Name="defPointFrom1Txt"]的文本传递到第二个文本框[x:Name="defPointTo1Txt"]的ValidationRule [MinIntegerValidationRule]中,而不是当前值1。我可以在代码中这样做:当第一个TextBox中的值发生变化时,根据事件命名验证规则并进行设置。但是,在XAML中是否有一种方法可以做到这一点,将所有验证逻辑保存在一个地方?

            <TextBox x:Name="defPointFrom1Txt" Grid.Row="2" Grid.Column="1" Style="{StaticResource lsDefTextBox}" 
                     Text="{Binding Path=OffensePointsAllowed[0].From}" IsEnabled="False"/>
            <TextBox x:Name="defPointTo1Txt" Grid.Row="2" Grid.Column="2" Style="{StaticResource lsDefTextBox}"
                     LostFocus="defPointTo1Txt_LostFocus">
                <TextBox.Text>
                    <Binding Path="OffensePointsAllowed[0].To" StringFormat="N1">
                        <Binding.ValidationRules>
                            <gui:MinIntegerValidationRule Min="1"/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>

为了完整起见,我的验证规则代码如下。

  public class IntegerValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        float controlValue;
        try
        {
            controlValue = int.Parse(value.ToString());
        }
        catch (FormatException)
        {
            return new ValidationResult(false, "Value is not a valid integer.");
        }
        catch (OverflowException)
        {
            return new ValidationResult(false, "Value is too large or small.");
        }
        catch (ArgumentNullException)
        {
            return new ValidationResult(false, "Must contain a value.");
        }
        catch (Exception e)
        {
            return new ValidationResult(false, string.Format("{0}", e.Message));
        }
        return ValidationResult.ValidResult;
    }
}
public class MinIntegerValidationRule : IntegerValidationRule
{
    public int Min { get; set; }
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        ValidationResult retValue = base.Validate(value, cultureInfo);
        if (retValue != ValidationResult.ValidResult)
        {
            return retValue;
        }
        else
        {
            float controlValue = int.Parse(value.ToString());
            if (controlValue < Min)
            {
                return new ValidationResult(false, string.Format("Please enter a number greater than or equal to {0}.",Min)); 
            }
            else
            {
                return ValidationResult.ValidResult;
            }
        }
    }
}
更新:

为了回应下面的答案,我试图创建一个DependencyObject。我这样做了,但不知道如何在ValidationRule代码中使用它(甚至不知道我正确地创建了它)。

public abstract class MinDependencyObject : DependencyObject
{
    public static readonly DependencyProperty MinProperty =
      DependencyProperty.RegisterAttached(
      "Min", typeof(int), 
      typeof(MinIntegerValidationRule),
      new PropertyMetadata(), 
      new ValidateValueCallback(ValidateInt)
      );
    public int Min
    {
        get { return (int)GetValue(MinProperty); }
        set { SetValue(MinProperty, value); }
    }
    private static bool ValidateInt(object value)
    {
        int test;
        return (int.TryParse(value.ToString(),out test));
    }
}

你不能在Min属性上设置绑定,因为它不是一个依赖属性。我过去所做的是在viewmodel上创建一个验证属性属性,它给了我类实例对象,然后我基于它执行验证。

在你的例子中,我会创建Min作为一个依赖对象

如果你认为在Binding上,你将不得不实现一个相对巨大的开销来使用它,因为你的验证类已经继承了另一个类。问题是使用Binding的绑定目标必须是DependencyProperty(你可以在这里读到),你不能在你的验证类中直接实现。

所以你可以为你的验证类创建一个AttachedProperty,这样你就可以使用Binding

这篇文章在WPF中添加一个虚拟分支到逻辑树作者Josh Smith, 2007年5月6日概述了这个问题的解决方案。

相关内容

  • 没有找到相关文章

最新更新