#silverlight
#silverlight
Вопрос:
Как вы реализуете проверку в пользовательских элементах управления? Я хочу воспроизвести стандартную логику проверки, которую вы могли бы видеть, с помощью текстового поля, привязанного к данным модели или view-model, которое предоставляет IDataErrorInfo или INotifyDataErrorInfo.
Комментарии:
1. Что именно вы хотите изменить? Насколько я знаю, проверка является свойством привязок, и при сбое привязки возникает событие BindingValidationError. Нет разницы между стандартным элементом управления и пользовательским элементом управления.
2. Ошибка BindingValidationError: автор элемента управления обычно не должен ни вызывать, ни обрабатывать это событие при разработке элемента управления и реализации класса управления.
3. Представьте, что вы пишете свое собственное текстовое поле с нуля. Как бы вы реализовали такие вещи, как всплывающая подсказка по проверке?
Ответ №1:
Для реализации проверки вам следует добавить группу «ValidationStates» в VisualStateManager элемента управления.
Я проиллюстрирую простой пользовательский элемент управления TestControl
с TestProperty
помощью свойства.
Стиль в Generic.xaml в зависимости от состояния отображает синий текст или красную рамку с первым сообщением об ошибке:
<Style TargetType="local:TestControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TestControl">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ValidationStates">
<VisualState x:Name="Valid" />
<VisualState x:Name="InvalidFocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="InvalidBorder" Storyboard.TargetProperty="Visibility" Duration="0">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="InvalidUnfocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="InvalidBorder" Storyboard.TargetProperty="Visibility" Duration="0">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBlock Text="{TemplateBinding TestProperty}" Foreground="Blue" />
<Border x:Name="InvalidBorder" BorderBrush="Red" BorderThickness="2" Visibility="Collapsed">
<TextBlock Text="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource TemplatedParent}}" Foreground="Red" FontWeight="Bold" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Существует 3 состояния:
- Допустимо — ошибок проверки нет.
- InvalidFocused — применяется, когда вы устанавливаете фокус на элемент управления в недопустимом состоянии. Элементы управления по умолчанию отображают красное всплывающее окно, а также красную рамку в этом состоянии, но в моем конкретном примере я не показываю это для простоты. Пользователи могут вызвать это состояние с помощью кнопки Tab на клавиатуре или щелчком по фокусируемому внутреннему элементу управления, такому как TextBox.
- InvalidUnfocused — применяется, когда элемент управления находится в недопустимом состоянии, но не сфокусирован.
Вот код элемента управления, он содержит только одно свойство:
public class TestControl : Control
{
public TestControl()
{
this.DefaultStyleKey = typeof(TestControl);
}
public string TestProperty
{
get { return (string)GetValue(TestPropertyProperty); }
set { SetValue(TestPropertyProperty, value); }
}
public static readonly DependencyProperty TestPropertyProperty =
DependencyProperty.Register("TestProperty", typeof(string), typeof(TestControl), new PropertyMetadata(null));
}
После этого, если вы используете IDataErrorInfo, правильный xaml будет:
<local:TestControl TestProperty="{Binding SomeModelProperty, ValidatesOnDataErrors=True}" />
Для INotifyDataErrorInfo правильный xaml еще проще:
<local:TestControl TestProperty="{Binding SomeModelProperty}" />
Комментарии:
1. Спасибо, это имеет большой смысл. Вам было бы интересно написать полноценную статью о разработке пользовательских элементов управления в Silverlight?
2. @Jonathan Allen Что означает слово «проектирование»: реализация с нуля или оформление в Expression Blend? Я могу написать статью о пользовательских элементах управления в целом с точки зрения разработчика, но мои навыки дизайнера оставляют желать лучшего.
3. Что я ищу, так это шаги, необходимые для поддержки всех основных функциональных возможностей, таких как создание шаблонов, проверка и привязка данных. Уже есть бесчисленное количество статей о том, как сделать это красиво, как только это будет сделано. Напишите мне сообщение, и мы сможем обсудить детали: jonathan@infoq.com
4. @Jonathan Allen Я пытался написать статью о создании пользовательских элементов управления с нуля: vortexwolf.wordpress.com/2011/04/14 /… .
5. @imdadhusen Реализуйте интерфейс INotifyDataErrorInfo или IDataErrorInfo в вашей модели представления. Вы можете загрузить образец приложения из сообщения в моем блоге: vortexwolf.wordpress.com/2011/10/01 /…