嗨我有一个带有文本框的数据网格,用于接收作为输入的IP地址。 为了验证文本框,我将其与自定义验证器绑定。
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Margin="20,10,20,10" Height="20" Width="100" HorizontalAlignment="Center" VerticalAlignment="Center" BorderBrush="{Binding Path=IPSrcValidationStatus.Color}">
<TextBox.Text>
<Binding Path="IPSrc" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validators:IPv4ValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
如何从我的代码中访问ValidationResult
,甚至更好地将其与我的视图模型绑定?
答案 0 :(得分:1)
验证规则完全在UI中发生。与转换失败类似,他们将您的控件设置为有错误,但不会发生从视图到视图模型的数据传输。
与wpf一样,有几种方法可以告诉您的viewmodel视图中存在数据错误。
您的validationrule可以获取绑定表达式并在viewmodel上设置一些属性。 Maxence的帖子中有一些代码: Passing state of WPF ValidationRule to View Model in MVVM
我从未使用过这种方法(但它看起来很有效) 我通常想知道转换失败以及任何验证规则失败。在我使用validationrule的情况下,我通常只关心有效数据是否使它成为viewmodel和IsDirty == true
我经常使用的方法是在父网格中冒出控制树时出现任何错误。 这个示例包含我使用的代码:
https://gallery.technet.microsoft.com/scriptcenter/WPF-Entity-Framework-MVVM-78cdc204
我设置
NotifyOnSourceUpdated=True,
NotifyOnValidationError=True,
在我感兴趣的所有绑定上。 然后错误会冒出来。 它们被捕获并从资源字典中的标准模板传递给viewmodel。 ConversionErrorCommand将触发转换,验证结果失败。
<Grid ... >
<i:Interaction.Triggers>
<local:RoutedEventTrigger RoutedEvent="{x:Static Validation.ErrorEvent}">
<e2c:EventToCommand
Command="{Binding EditVM.TheEntity.ConversionErrorCommand, Mode=OneWay}"
EventArgsConverter="{StaticResource BindingErrorEventArgsConverter}"
PassEventArgsToCommand="True" />
</local:RoutedEventTrigger>
<local:RoutedEventTrigger RoutedEvent="{x:Static Binding.SourceUpdatedEvent}">
<e2c:EventToCommand
Command="{Binding EditVM.TheEntity.SourceUpdatedCommand, Mode=OneWay}"
EventArgsConverter="{StaticResource BindingSourcePropertyConverter}"
PassEventArgsToCommand="True" />
</local:RoutedEventTrigger>
</i:Interaction.Triggers>
您还需要RoutedEventTrigger:
public class RoutedEventTrigger : EventTriggerBase<DependencyObject>
{
RoutedEvent routedEvent;
public RoutedEvent RoutedEvent
{
get
{
return routedEvent;
}
set
{
routedEvent = value;
}
}
public RoutedEventTrigger()
{
}
protected override void OnAttached()
{
Behavior behavior = base.AssociatedObject as Behavior;
FrameworkElement associatedElement = base.AssociatedObject as FrameworkElement;
if (behavior != null)
{
associatedElement = ((IAttachedObject)behavior).AssociatedObject as FrameworkElement;
}
if (associatedElement == null)
{
throw new ArgumentException("This only works with framework elements");
}
if (RoutedEvent != null)
{
associatedElement.AddHandler(RoutedEvent, new RoutedEventHandler(this.OnRoutedEvent));
}
}
void OnRoutedEvent(object sender, RoutedEventArgs args)
{
base.OnEvent(args);
}
protected override string GetEventName()
{
return RoutedEvent.Name;
}
}
}