【问题标题】:How to show a list of validation error messages out of a datagrid row如何从数据网格行中显示验证错误消息列表
【发布时间】:2020-07-16 10:35:06
【问题描述】:

有没有办法在数据网格之外显示所有验证消息? 如果您运行多个验证行规则并收到多条消息,则行标题中的悲伤工具提示是不够的。我更喜欢另一个数据网格来显示所有这些消息(或任何其他“ItemsControl”)。我已经尝试在 datagrid 上使用 validation.error 事件(数据集有界),但它没有触发。如何将 ItemSource 绑定到此类数据网格中的实际 ErrorContent? “ValidationAdornerSite”显然有效,但它的占位符在行头中,而不是在我想要的地方...... 我也尝试过WPF 3.5 SP1 Feature: BindingGroups with Item-level Validation 中给出的方法,效果很好,但不适用于数据网格

非常感谢您。

【问题讨论】:

    标签: wpf datagrid


    【解决方案1】:

    嗯,问题是大声说出来,答案就来了,所以,为了这个问题,我正在描述我所犯的错误和误解,以及如何通过将所有东西放在适当的位置来最终实现我的目标方式同时

    1. 第一个错误:在数据网格中使用 BindingGroup 而不是 ItemBindingGroup。这允许您使用 NotifyOnValidationError 属性,因此 Validation.Error 事件正常触发。然后您可以忘记 DataGrid.RowValidationRules,因为您应该将验证规则放在 ItemBindingGroup 的 BindingGroup 对象中。

    2. 而 Validation.Error 处理程序可以在 Datagrid 中定义,而 Validation.ValidationAdornerSite 应该在 BindingGroup 对象中定义。

    3. 不要在 BindingGroup 的任何绑定中使用 UpdateSourceTrigger 属性。这是我做的一个误会,它会引发 不稳定 行为,因为 BindingGroup 会忽略这些绑定,而 Binding 会自行更新源代码。

    这是我用来以正确方式将所有东西放在一起的代码:

    定义 Datagrid 和 ItemBindigGroup

        <DataGrid ItemsSource="{Binding Source={StaticResource WinViewSource}}" 
              Validation.Error="BindingGroup_Error" >
    
        <DataGrid.ItemBindingGroup>
            <BindingGroup NotifyOnValidationError="True" ValidatesOnNotifyDataError="True" Validation.ValidationAdornerSite="{Binding ElementName=ErrorListBox}" >
                <BindingGroup.ValidationRules>
                    <YourValidationRule ValidationStep="UpdatedValue" ValidatesOnTargetUpdated="False"/>
                </BindingGroup.ValidationRules>
            </BindingGroup>
        </DataGrid.ItemBindingGroup>
    
        <...>
            
    </DataGrid>
    <ListBox Name="ErrorListBox" Style="{StaticResource ListBoxErrorStyle}" Button.Click="GoToErrorButton_Click"/>
    

    ValidationAdornerSite 的 ListBox 的样式。

        <Style x:Key="ListBoxErrorStyle" TargetType="{x:Type ListBox}" BasedOn="{StaticResource {x:Type ListBox}}">
        <Setter Property="ItemsSource" Value="{Binding (Validation.ValidationAdornerSiteFor).(Validation.Errors), RelativeSource={RelativeSource Self}}" />
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Grid Background="LightYellow">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Button Grid.Column="0" Content="Go to" Visibility="{Binding ErrorContent.ButtonGoToVisibility}" />
                        <TextBlock Grid.Column="1" Text="{Binding Path=ErrorContent.ErrorCode}" Margin="3"/>
                        <TextBlock Grid.Column="2" Text="{Binding Path=ErrorContent.ErrorMessage}" Margin="3"/>
                    </Grid>
                </DataTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=Items.Count, RelativeSource={RelativeSource Self}}" Value="0">
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
    

    将 ItemsSource 绑定到 Validation.Errors 是不够的,因为尽管任何时候出现验证错误,ListBox 都会检查最后一个 ListViewItem 是否有 Validation.Errors,这将是 last ListViewItem 而不是 当前 ListViewItem。为避免这种情况,您需要 Validation.Error 事件才能重新附加

      Private Sub BindingGroup_Error(sender As Object, e As ValidationErrorEventArgs)
    
         Validation.SetValidationAdornerSite(DirectCast(e.OriginalSource, DependencyObject), ErrorListBox)
    
      End Sub
    

    我的客户要求包括一个非常简单的对象,即带有 3 个属性的 ErrorContent,这些值应该在验证规则中定义,以便找到错误的原因

       Public Class ErrorContent
          Public Property ErrorCode As String
          Public Property ErrorMessage As String
          Public Property ButtonGoToVisibility As Visibility = Visibility.Visible
       End Class
    

    通过上述操作,您将在屏幕上任何您想要的列表中看到所有验证错误,并且用户可以获得更好的处理它们的体验。

    【讨论】:

      猜你喜欢
      • 2022-11-09
      • 1970-01-01
      • 2021-10-12
      • 2020-05-11
      • 2019-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多