访问UserControl中的验证错误

时间:2015-05-12 12:39:54

标签: c# wpf validation xaml user-controls

我创建了一个WPF(.Net 4)UserControl,其中包含一些ComboBox和一个TextBox。在XAML中,一些ValidationRules绑定到TextBox。如果TextBox包含无效数据,则会显示红框,并且工具提示将设置为错误说明。效果很好。

接下来,我在表单上放置了两个UserControl实例,并添加了一个按钮。在XAML中,该按钮连接到ViewModel的RelayCommand。现在我希望只有当两个UserControl只包含有效数据时才启用该按钮。

不是问题,我想,让我使用一种在其他地方运作的策略。我添加了一个触发器:

    <Button Content="_OK" ... Command="{Binding Path=OKCommand}">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="IsEnabled" Value="false" />
                <Style.Triggers>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding ElementName=cascadingComboFrom, Path=(Validation.HasError)}" Value="false" />
                            <Condition Binding="{Binding ElementName=cascadingComboTo, Path=(Validation.HasError)}" Value="false" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="IsEnabled" Value="true" />
                    </MultiDataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>

但是有一个问题:UserControls的Validation.HasError始终为false - UserControl内部元素的验证失败,而不适用于UserControl。

我知道我可以注册按钮的Click事件,使用Detecting WPF Validation Errors中显示的方法检查那里的有效性,并通过将RoutedEventArgs的Handled属性设置为true来阻止执行RelayCommand。但这看起来更像WTF而不是WPF。

你有什么建议?如何检索UserControl的子项的验证错误?或者我如何在RelayCommand的CanExecute方法中获取它们?还是其他一些技巧?

2 个答案:

答案 0 :(得分:0)

您可以在名为ValidatesOnDataErrors的命令绑定上设置属性。

实现看起来像这样:

 <Button Content="_OK" Command="{Binding, Path=OKCommand, ValidatesOnDataErrors=True}"/>

您可以详细了解here

答案 1 :(得分:0)

var plan3NodeCount = count("/UnderwritingRequest/Plan[@PlanId='3']"); 属性已经硬连接到Button.IsEnabled的{​​{1}}方法,所以您需要做的就是将返回值设置为CanExecute表单字段无效:

RelayCommand

现在,您如何将false变量设置为private bool CanExecute(object commandParameter) { return areFormFieldsValid; } bool areFormFieldsValid取决于您......有多种方法可以做到这一点。就个人而言,我更喜欢使用IDataErrorInfo interface,它有一个方便的true属性,您可以检查。有许多关于如何实现这一点的在线教程,所以我不会在这里重复...但是,最终的结果是这样的:

false