ValidationRules не устраняет ошибку, когда значение возвращается к действительному значению - PullRequest
5 голосов
/ 20 февраля 2012

ВВЕДЕНИЕ

Я создал DecimalTextBox UserControl, который содержит некоторую десятичную проверку, которую мне нужно сделать, так что мне не нужно каждый раз пересматривать проверкуи может просто использовать вместо UserControl.У этой проверки есть свойства, с которыми нужно связываться, и поэтому я создал DependencyProperties, чтобы я мог связываться с ними, согласно этой статье Джоша Смита .


ПРОБЛЕМА

Проверка элемента управления ведет себя странно.Когда я набираю ошибочное значение в TextBox, оно отображается как ошибка.Однако, когда я пытаюсь изменить значение обратно в коде , значение, показанное в текстовом поле, остается неизменным.

Вот шаги, которые я выполняю, которые вызывают эту ошибку (в этом примере 1 являетсянедопустимое значение):

  1. Загрузить форму и значение по умолчанию: 0 .
  2. Введите 1 в текстовое поле (и текстовое поле).идет красный из-за результата проверки и ошибки)
  3. В коде я установил свойство, привязанное к текстовому полю, на 0
  4. Форма все еще отображает 1 в красном текстовом поле

ПРИМЕР КОДА

Я подготовил пример, демонстрирующий проблему, который можно загрузить здесь.

Я опубликую часть кода здесь, если вы хотите больше, дайте мне знать.

ValidationTestControl's XAML

<UserControl x:Class="WPFTestProject.ValidationTestControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:v="clr-namespace:WPFTestProject"
    x:Name="ValidationTest"
    Height="50" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>          

    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
        <TextBlock Text="Type 'Banana' here: "></TextBlock>
        <TextBox MinWidth="100">
            <TextBox.Text>
                <Binding ElementName="ValidationTest"  Path="Text" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" ValidatesOnDataErrors="True" ValidatesOnExceptions="True">
                    <Binding.ValidationRules>
                        <v:NotBananaValidationRule>
                            <v:NotBananaValidationRule.NotWhatBinding>
                                <v:NotBananaBinding x:Name="NotBananaValidationBinding"></v:NotBananaBinding>
                            </v:NotBananaValidationRule.NotWhatBinding>
                        </v:NotBananaValidationRule>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <TextBlock Text=" (the text will give error when = 'Banana')"></TextBlock>
    </StackPanel>
</Grid>

ValidationTestControls Code Behind

(да, я знаю не очень MVVMно я чувствовал, что это нормально для этого автономного элемента управления)

 public partial class ValidationTestControl : UserControl
{
    public ValidationTestControl()
    {
        InitializeComponent();
        Banana = "Banana";

        Binding BananaBinding = new Binding("Banana");
        BananaBinding.Source = this;

        NotBananaValidationBinding.SetBinding(NotBananaBinding.NotWhatProperty, BananaBinding);
    }

    public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(ValidationTestControl), new PropertyMetadata());
    public static DependencyProperty BananaProperty = DependencyProperty.Register("Banana", typeof(string), typeof(ValidationTestControl), new PropertyMetadata());

    public string Text
    {
        get
        {
            return (string)GetValue(TextProperty);
        }
        set
        {
            SetValue(TextProperty, value);
        }
    }


    public string Banana
    {
        get
        {
            return (string)GetValue(BananaProperty);
        }
        set
        {
            SetValue(BananaProperty, value);
        }
    }


}

ValidationRule и FrameWorkElement, созданные для привязки

 public class NotBananaValidationRule:ValidationRule
{
    private NotBananaBinding _notWhatBinding;
    public NotBananaBinding NotWhatBinding
    {
        get { return _notWhatBinding; }
        set { _notWhatBinding = value; }
    }

    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        string what = value.ToString();

        if(what == _notWhatBinding.NotWhat||string.IsNullOrEmpty(what))
            return new ValidationResult(false,
                       "Please enter a string that is not " + _notWhatBinding.NotWhat);
        else
            return new ValidationResult(true, null);

    }

}


public class NotBananaBinding : FrameworkElement
{
    public static readonly DependencyProperty NotWhatProperty = DependencyProperty.Register(
      "NotWhat", typeof(string), typeof(NotBananaBinding), new UIPropertyMetadata());

    public string NotWhat
    {
        get { return (string)GetValue(NotWhatProperty); }
        set { SetValue(NotWhatProperty, value); }
    }

    public NotBananaBinding() { }
}

По сути, этот код проверяет, еслиВы ввели «Банан», а затем возвращает ошибку проверки.Элемент управления предоставляет свойства зависимостей, потому что я хочу иметь возможность привязываться к ним при использовании элемента управления.FrameworkElement NotBananaBinding позволяет мне создавать свойства зависимостей (потому что это DependencyObject, поэтому я могу связывать вещи для проверки. ValidationRule имеет свойство NotBananaBinding , в котором хранится свойство зависимостии использует его в методе validate.

Я знаю, что мои имена свойств довольно дурацкие, извините. Дело в том, что пример хорошо справляется с отображением ошибки. В спешке приведу пример, который я не сделал.Перечислите переменные очень хорошо. Если вы нашли код дрянной , пожалуйста, скачайте образец здесь.


ЧТО Я ТАК ВЫБИРАЛFAR

В основном эта проблема, по-видимому, вызвана тем фактом, что я фактически не изменяю значение .

Даже если я вызову OnPropertyChanged для свойства,поскольку значение не отличается, оно не пытается переоценить валидацию.

Я, очевидно, могу изменить значение на произвольное допустимое значение, а затем изменить его на то, что я хочуэто будет, и это будет работать, но я надеялся, что есть какой-то способ получить подтверждение вызова вручную, переоценить значение, а затем изменить его и т. д. Смена его и возвращение довольно грязная.


ЗАКЛЮЧЕНИЕ

Я делаю что-то не так (возможно, что-то в том, как я реализовал проверку и привязку из поста Джоша Смита)

Это просто ошибка ac #, илитакое поведение предназначено?Если так, то почему?

Существуют ли элегантные способы исправить это?

u_u

1 Ответ

1 голос
/ 10 марта 2012

Проверка не позволяет установить свойство Text. Поставьте точку останова на сеттер, и вы увидите, что она не сломается, когда вы наберете последний «а». Если вы наберете Bananan и нажмете кнопку Backspace, и она выдаст ошибку, нажмите кнопку, и она заработает. Проверка гарантирует, что в вашей собственности не может быть недопустимого значения. Так что, если вы сохраните его, скажем, в базе данных, в случае ошибки, он не сохранит неверное значение.

...