访问ValidationResult

时间:2018-04-11 09:12:40

标签: wpf validation binding

嗨我有一个带有文本框的数据网格,用于接收作为输入的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,甚至更好地将其与我的视图模型绑定?

1 个答案:

答案 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;
    }
}

}