Всплывающее окно с результатами проверки WPF - PullRequest
3 голосов
/ 04 января 2011

Я пытаюсь реализовать проверку WPF в нескольких текстовых полях.Я хочу иметь возможность отображать ошибки проверки пользователю с помощью чего-то более очевидного, чем подсказка, но более тонкого, чем диалог или окно сообщения.Я остановился на использовании класса Popup, а не некоторого встроенного текстового поля для отображения ошибок, поскольку существует множество различных полей, которые необходимо проверить таким образом, и я хочу, чтобы обратная связь была «прикреплена» к рассматриваемому полю.

Проблема, с которой я сталкиваюсь, заключается в том, что привязка дочернего TextBox всплывающего окна к присоединенному свойству TextBox (Validation.Errors) не обновляется достаточно агрессивно.Как только появляется объект Error, текст обновляется и отображается (т. Е. «Пожалуйста, введите имя.» Для пустого поля), но если ошибка изменяется (т. Е. Пользователь вводит недопустимый текст), сообщение во всплывающем окне остается прежним.... до тех пор, пока они не введут действительный ввод, после чего всплывающее окно исчезнет, ​​как нужно.

Я выполнил некоторую отладку и обнаружил, что в то время, как правило проверки вызывается правильно и возвращаетДля правильных результатов конвертер для Popup вызывается только при создании исходной ошибки.Я предполагаю, что меня смущает то, что всплывающее окно обновляется только тогда, когда состояние проверки переходит от «без ошибок» к «некоторым ошибкам», так сказать.Кто-нибудь знает способ заставить изменения в Validation.Errors отражаться в TextBox.Text моего всплывающего окна?

Вот пример xaml того, что я написал.

<TextBox Name="MyTextBox">
    <TextBox.Text>
        <Binding Path="MyText" UpdateSourceTrigger="PropertyChanged" >
            <Binding.ValidationRules>
                <local:MyTextBoxValidationRule />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>
<Popup Name="MyPopup" IsOpen="{Binding ElementName=MyTextBox, 
    Path=(Validation.HasError), Mode=OneWay}">
    <Border BorderThickness="1" BorderBrush="Red" Background="White">
        <TextBlock Foreground="Red" Margin="5 5 5 5" 
            Text="{Binding ElementName=MyTextBox, Path=(Validation.Errors), 
            Converter={StaticResource errorsToMessageConverter}}"/>
    </Border>
</Popup>

Ответы [ 2 ]

1 голос
/ 04 января 2011

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

<TextBlock Name="MyPopupTextBox" Foreground="Red" Margin="5 5 5 5" 
    Text="{Binding ElementName=MyTextBox, Path=(Validation.Errors)[0].ErrorContent, 
    UpdateSourceTrigger=PropertyChanged, Mode=OneWay, NotifyOnValidationError=True, 
    NotifyOnSourceUpdated=True, ValidatesOnExceptions=True}"/>
0 голосов
/ 10 марта 2011

Ваша исходная проблема - типичная проблема при привязке к коллекции: пока ваша коллекция не изменяется структурно (вставка / удаление / очистка), привязка не будет видеть никаких причин для обновления.Таким образом, если только элемент в коллекции изменяет какое-либо свойство, это не приводит к обновлению привязки.

Вы уже решили эту проблему, связавшись с элементом в этой коллекции, таким образом, полный путь к измененному свойству(ErrorContent) будет наблюдаться в привязке.

Проблема с привязкой (Validation.Errors)[0] заключается в том, что она вызывает IndexOutOfRange-Exceptions (не выдается, но они находятся там), еслиКоллекция пуста.

Этот поток обсуждает это исключение, а также содержит обходной путь, который мне подходит: http://social.msdn.microsoft.com/forums/en/wpf/thread/1c6cd214-abce-4a8b-a919-0726dd81461a/ Просто замените (Validation.Errors)[0].ErrorContent на (Validation.Errors).CurrentItem.ErrorContent и все готово.

...