Передача значения из TextBox в ValidationRule

У меня есть два элемента управления TextBox (как показано ниже), и я хотел бы передать текст первого TextBox [x:Name="defPointFrom1Txt"] в ValidationRule [MinIntegerValidationRule] для второго TextBox [x:Name="defPointTo1Txt"] вместо текущего значения 1. Я мог бы сделать это в коде путем присвоения имени правилу проверки и настройки на основе события, когда значение в первом текстовом поле изменяется. Однако есть ли способ сделать это в 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));
    }
}

person Harrison    schedule 18.03.2013    source источник
comment
Вы на правильном пути. Как ValidateValueCallback реализовано?   -  person DHN    schedule 19.03.2013
comment
Это было реализовано путем проверки значения. ToString может быть успешно преобразован в целое число. Я отказался от этого в XAML. Посмотрев на правильное решение, я решил установить минимальный и максимальный диапазоны в коде на основе событий. Хотя я бы предпочел, чтобы эта логика была в XAML, правильное решение - это обходной путь, поскольку ValidationRule не наследуется от DependencyObject. Следовательно, вы не можете установить DependencyProperty напрямую. Даже после создания DependencyProperty отдельно и помещения его в класс вы по-прежнему не можете использовать его для привязки. См. Ссылку в ответе ниже ...   -  person Harrison    schedule 19.03.2013


Ответы (3)


Вы не можете установить привязку для свойства Min, потому что это не свойство зависимостей. Раньше я создавал атрибут свойства проверки в viewmodel, который дает мне объект экземпляра класса, а затем я выполняю свою проверку на основе этого.

В вашем случае я бы создал Min как объект зависимости.

person TYY    schedule 18.03.2013
comment
Я никогда не создавал собственный объект DependencyObject. Вы можете объяснить, как это сделать? Я просмотрел документацию, и это довольно сбивает с толку. Я опубликую выше правку того, что я сделал до сих пор. - person Harrison; 18.03.2013
comment
@Harrison Я имел в виду DependencyProperty. - person TYY; 18.03.2013
comment
Поскольку ValidationRule не наследуется от DependencyObject, вы не можете создать DependencyProperty для этого класса (или классов, наследующих от него). - person Harrison; 18.03.2013
comment
Да, это правильно, но есть способы обойти это, как обсуждается здесь social.msdn.microsoft.com/Forums/en-US/wpf/thread/ - person TYY; 18.03.2013

Что ж, если вы думаете о Binding, вам придется реализовать относительные огромные накладные расходы, чтобы использовать его, потому что ваш класс проверки уже наследуется от другого класса. Проблема заключается в использовании Binding целью привязки должен быть DependencyProperty (как вы можете прочитать здесь), который вы не можете реализовать непосредственно в своем классе проверки.

Таким образом, вы могли бы создать, например, AttachedProperty для ваших классов проверки, чтобы вы могли использовать Binding. Вы можете найти некоторую информацию здесь.

person DHN    schedule 18.03.2013

В этом сообщении Подключение виртуальной ветви к Логическое дерево в WPF Джош Смит, 6 мая 2007 г. описывает решение этой проблемы.

person Harrison    schedule 18.03.2013