WPF 数据表格 Validation.HasError 总是为 false (MVVM)

4

我在获取Datagrid/DataGridCells中的ValidationErrors信息方面遇到了一些问题。

我的目标是通过Commands(CanExecute)来禁用一个按钮,基于存在或不存在验证错误。因此,我将DataGrid的Validation.HasError绑定到按钮上的CommandParameter。

使用IDataErrorInfoViewModel中实现验证,并且它可以正常工作。任何包含错误值的DataGridCell都会有红色边框和描述错误的工具提示。

但我无法将该按钮的CommandParameter绑定到DataGrid的Validation.HasError,如果我调试该问题,则Validation.HasError始终为false。为什么?如何解决这个问题?

我几乎试过了在网上找到的每一个“解决方案”,但迄今为止没有任何效果。

我的DataGrid XAML:

<DataGrid x:Uid="DataGrid_1"
          Name="SomeDataGrid"
          Grid.Column="0"
          Grid.Row="1"
          Grid.RowSpan="2"
          ItemsSource="{Binding SomeItems}"
          SelectedItem="{Binding SomeSelectedItem, Mode=TwoWay}"
          CanUserSortColumns="False"
          CanUserAddRows="False"
          CanUserDeleteRows="False"
          IsReadOnly="False"
          IsSynchronizedWithCurrentItem="True"
          IsTabStop="True"
          IsTextSearchEnabled="True"
          >
    <DataGrid.Resources>
        <SolidColorBrush x:Uid="SolidColorBrush_1"
                         x:Key="{x:Static SystemColors.ControlBrushKey}"
                         Color="{x:Static SystemColors.HighlightColor}" />
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTemplateColumn x:Uid="Comlumn1"
                                x:Name="Comlumn1"
                                Header="SomeHeader"
                                Width="auto">
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate x:Uid="DataTemplate_1">
                    <ComboBox x:Uid="ComboBox_7"
                              ItemsSource="{Binding DataContext.Attributes,Source={StaticResource ProxyElement}}"
                              SelectedItem="{Binding Attribute, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
                              DisplayMemberPath="DESCRIPTION"
                              IsEditable="False"
                              IsTextSearchEnabled="False"
                              Margin="0"
                              Padding="0" />
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate x:Uid="DataTemplate_2">
                    <TextBlock x:Uid="TextBlock_15"
                               Text="{Binding Attribute, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
                               ToolTip="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={x:Static RelativeSource.Self}}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

        <DataGridTextColumn x:Uid="DataGridTextColumn_2"
                            Header="Value"
                            Width="auto"
                            Binding="{Binding VALUE, ValidatesOnDataErrors=True}">
            <DataGridTextColumn.ElementStyle>
                <Style x:Uid="Style_4"
                       TargetType="{x:Type TextBlock}">
                    <Setter x:Uid="Setter_4"
                            Property="DataGridCell.ToolTip"
                            Value="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={x:Static RelativeSource.Self}}" />
                </Style>
            </DataGridTextColumn.ElementStyle>
        </DataGridTextColumn>
        <DataGridTextColumn x:Uid="DataGridTextColumn_3"
                            Header="Unit"
                            Width="auto"
                            Binding="{Binding UNIT, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"
                            IsReadOnly="True" />
        <DataGridTextColumn x:Uid="DataGridTextColumn_4"
                            Header="Remark"
                            Width="auto"
                            Binding="{Binding REMARK}" />
    </DataGrid.Columns>
</DataGrid>

我想绑定到DataGrid Validation.Errors的按钮:

    <Button x:Uid="Button_1"
            Content=" + "
            Command="{Binding AddItemCommand}"
            CommandParameter="{Binding (Validation.HasError), ElementName=SomeDataGrid}" />

2
如果任何子项存在错误,DataGrid 的 Validation.HasError 属性不会自动变为 true。请参见 https://dev59.com/E3VC5IYBdhLWcg3w-mZO。 - LPL
我之前尝试了这个链接中的所有解决方案,但都没有奏效!每个提供的IsValid方法实现始终返回TRUE,无论是否存在ValidationErrors。我还尝试在所有DataGridCells上应用Validation.GetHasError()方法,但该方法始终返回false... - M C
好的。我刚刚再次尝试了IsValid实现,以防昨天错过了什么。我确实错过了。如果在datagrid实际显示之前已经存在验证错误,则它们会显示错误的值。如果我只是选择网格中的任何行或单元格,然后再次执行IsValid方法,它就会显示正确的值。 - M C
如果我使用ValidationRules而不是IDataErrorInfo,问题是相同的。似乎验证太晚了。是否有一种方法可以从ViewModel或CodeBehind启动验证?@LPL - M C
1个回答

9

好的,我终于弄清楚了!来自这里的以下方法确实有效,但只有在包含我的数据网格的窗口完全加载后才能使用(例如,在窗口/Usercontrol Loaded EventHandler中):

public bool IsValid(DependencyObject parent)
{
    if (Validation.GetHasError(parent))
        return false;

    // Validate all the bindings on the children
    for (int i = 0; i != VisualTreeHelper.GetChildrenCount(parent); ++i)
    {
        DependencyObject child = VisualTreeHelper.GetChild(parent, i);
        if (!IsValid(child)) { return false; }
    }

    return true;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接