Patrick Skelton Ответов: 1

Как "поймать" ошибку проверки WPF?


У меня есть проблема с проверкой в окне WPF.

У меня есть текстовое поле, привязанное к простому строковому свойству в модели представления. Я хочу убедиться, что коробка никогда не может быть пустой. То TextBox объявляется следующим образом:

<TextBox x:Name="TextBoxName" Validation.Error="TextBox_Error" >
    <TextBox.Text>
        <Binding Path="CustomerName" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
            <Binding.ValidationRules>
                <u:NonZeroLengthStringValidator/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>


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

Если в тексте есть один символ "а", то TextBox и я удаляю его, правило проверки возвращает ошибку, и событие срабатывает. В этом случае я открываю диалоговое окно предупреждения, сообщая пользователю, что поле не может быть пустым. Затем я хочу оставить последний символ " а " в поле, чтобы экрану в целом не нужно было беспокоиться о том, что он находится в недопустимом состоянии (что значительно увеличило бы сложность обработки других полей и элементов управления на экране).

Как я могу это сделать?

Что я уже пробовал:

Я перепробовал много вариантов, но мой настоящий камень преткновения заключается в том, что набор на CustomerName не вызывается при сбое правила проверки. Это оставляет резервное поле, содержащее один символ "а", в то время как пользовательский интерфейс показывает пустое поле. Если я заставлю OnPropertyChanged("CustomerName") чтобы обновить пользовательский интерфейс, процесс проверки запускается снова, и я получаю второе диалоговое окно.

Итак, в общем, у меня почти все работает, но я либо получаю пользовательский интерфейс не в ногу с резервным полем, либо получаю два диалоговых окна ошибок.

Может ли кто-нибудь придумать способ обойти это?

1 Ответов

Рейтинг:
10

J. Calhoun

Я лично использую триггер события на событии lost focus, чтобы сделать проверку string. empty. Если строка пуста, то я заменяю ее своей строкой по умолчанию. Я также использую свойство command для запуска проверки в модели представления, или вы можете расширить поведение в элементе управления textbox, чтобы сделать это также.

Триггер события находится в системе.Окна.Интерактивность .dll так что это что-то вроде:

xmlns:i=clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity


Затем,

<TextBox x:Name="TextBoxName" Validation.Error="TextBox_Error" >
    <TextBox.Text>
        <Binding Path="CustomerName" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
            <Binding.ValidationRules>
                <u:NonZeroLengthStringValidator/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="LostFocus">
             <i:InvokeCommandAction Command={Binding ElementName=TextBoxName, Path=Datacontext.YourCommandPropertyHere/>
         </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>



Другим решением было бы расширить текстовое поле с поведением, использующим тот же файл. dll
Хороший пример того, как это работает, можно найти здесь, настраиваемое поведение