Rod
Rod

Reputation: 4481

Is it possible to have an error message appear around the cell of a DataGrid?

This question is a follow-up to one I posted on SO yesterday. I've followed Andy's suggestion to use INotifyDataErrorInfo. I've used it in the Class model class I referred yesterday. And I found an article on C-SharpCorner.com which I also adapted to my situation. After putting these in place and testing it, I found that it does catch the range restriction. However, it only circled the cell with the problem in the DataGrid in red. It didn't show me the error message next to the cell, which is what my boss wants. I'm wondering if what the boss wants isn't possible in a WPF DataGrid? Or have I botched it?

I set a breakpoint in the HandleValidationResults method from the second link above. It properly assigns the error message to the _errors collection. Here's how I modified the DataGridTextColumn:

<DataGridTextColumn Header="Start" Binding="{Binding StartTime, StringFormat={}{0:0000}, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnNotifyDataErrors=True, UpdateSourceTrigger=PropertyChanged}">
    <Validation.ErrorTemplate>
        <ControlTemplate>
            <StackPanel>
                <AdornedElementPlaceholder x:Name="dataGridTextColumn" />
                <ItemsControl ItemsSource="{Binding}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding ErrorContent}" Foreground="Red" />
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </ControlTemplate>
    </Validation.ErrorTemplate>
</DataGridTextColumn>

Upvotes: 0

Views: 440

Answers (1)

thatguy
thatguy

Reputation: 22129

Do not set the validation error template directly, set it in the ElementStyle or EditingElementStyle:

<DataGridTextColumn.ElementStyle>
   <Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type TextBlock}}">
      <Setter Property="Validation.ErrorTemplate">
         <Setter.Value>
            <ControlTemplate>
               <StackPanel>
                  <AdornedElementPlaceholder x:Name="dataGridTextColumn" />
                  <ItemsControl ItemsSource="{Binding}">
                     <ItemsControl.ItemTemplate>
                        <DataTemplate>
                           <TextBlock Text="{Binding ErrorContent}" Foreground="Red" />
                        </DataTemplate>
                     </ItemsControl.ItemTemplate>
                  </ItemsControl>
               </StackPanel>
            </ControlTemplate>
         </Setter.Value>
      </Setter>
   </Style>
</DataGridTextColumn.ElementStyle>

DataGrid with occluding error template.

However, you will notice that your current approach does not work well, as the error template will occlude other cells below the cell that is in error. A better alternative is to set the error template as ToolTip. This way, the errors are shown as popup if you hover over a cell in error.

<DataGridTextColumn.ElementStyle>
   <Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type TextBlock}}">
      <Style.Triggers>
         <Trigger Property="Validation.HasError" Value="True">
            <Setter Property="ToolTip">
               <Setter.Value>
                  <ToolTip DataContext="{Binding PlacementTarget.(Validation.Errors), RelativeSource={RelativeSource Self}}">
                     <ItemsControl ItemsSource="{Binding }">
                        <ItemsControl.ItemTemplate>
                           <DataTemplate>
                              <TextBlock Text="{Binding ErrorContent}" Foreground="Red" />
                           </DataTemplate>
                        </ItemsControl.ItemTemplate>
                     </ItemsControl>
                  </ToolTip>
               </Setter.Value>
            </Setter>
         </Trigger>
      </Style.Triggers>
   </Style>
</DataGridTextColumn.ElementStyle>

DataGrid column with error tool tip.

Upvotes: 0

Related Questions