Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get rid of the red border when a DataGrid cell is invalid?

Tags:

wpf

How do I do this? I want to get rid of that annoying red border that shows on each invalid datagrid cell.

like image 278
Luis Aguilar Avatar asked Oct 06 '11 16:10

Luis Aguilar


4 Answers

You can just add this line to your DataGrid:

<DataGrid  Validation.ErrorTemplate="{x:Null}" />
like image 71
Openmiracle Support Avatar answered Dec 23 '22 07:12

Openmiracle Support


I had this same issue but in my case I wasn't using IDataError or INotifyDataErrorInfo. I'm using a custom ValidationRule and styles to handle my validation logic and presentation. I was already using the DataGrid RowStyle to display a custom style for the row that has errors so I thought it would be easy to do something similar with the DataGridCell.

Things to note:

  1. You can't just define a style and set the DataGrid.CellStyle. Instead you have to use the ElementStyle and/or the EditingElementStyle.

  2. The style TargetType has to match the DataGridColumn type that the cell is using. So for a DataGridComboBoxColumn the TargetType should be ComboBox

DataGrid Column XAML:

<DataGridComboBoxColumn Header="Column1" 
    ItemsSource="{Binding Path=Column1Path}"
    DisplayMemberPath="Column1DisplayPath"
    ElementStyle="{StaticResource DGComboColValidationStyle}"
    EditingElementStyle="{StaticResource DGComboColValidationStyle}">

    <DataGridComboBoxColumn.SelectedItemBinding>
        <Binding Path="Column1Path" UpdateSourceTrigger="LostFocus">
            <Binding.ValidationRules>
                <Validation:CustomValidationRule ValidationStep="UpdatedValue" ValidatesOnTargetUpdated="True" />
            </Binding.ValidationRules>
        </Binding>
    </DataGridComboBoxColumn.SelectedItemBinding>
</DataGridComboBoxColumn>

Style Definitions

<Style x:Key="DGComboColValidationStyle" TargetType="{x:Type ComboBox}">
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <Grid>
                    <Border BorderThickness="1" 
                            BorderBrush="{Binding ElementName=adorner1, Path=DataContext[0].ErrorContent.ValidationType, Converter={StaticResource ValidationTypeColorConverter}}" 
                            CornerRadius="3">
                    </Border>
                    <AdornedElementPlaceholder Name="adorner1"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="DGTextColValidationStyle" TargetType="{x:Type TextBlock}">
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <Grid>
                    <Border BorderThickness="1" 
                            BorderBrush="{Binding ElementName=adorner2, Path=DataContext[0].ErrorContent.ValidationType, Converter={StaticResource ValidationTypeColorConverter}}" 
                            CornerRadius="3">
                    </Border>
                    <AdornedElementPlaceholder Name="adorner2"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="DGRowValidationStyle" TargetType="{x:Type DataGridRow}">
    <Setter Property="ValidationErrorTemplate">
        <Setter.Value>
            <ControlTemplate x:Name="DGRowValidationTemplate">
                <Grid>
                    <Ellipse Width="12" Height="12" Stroke="Black" StrokeThickness="0.5"
                        Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Path=(Validation.Errors)[0].ErrorContent.ValidationType, Converter={StaticResource ValidationTypeColorConverter}}"/>
                    <TextBlock FontWeight="Bold" Padding="4,0,0,0"
                        Margin="0" VerticalAlignment="Top" Foreground="White" Text="!"
                        ToolTip="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Path=(Validation.Errors)[0].ErrorContent.ValidationMessage}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="BorderThickness" Value="2"/>
            <Setter Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent.ValidationType, Converter={StaticResource ValidationTypeColorConverter}}"/>
        </Trigger>
        <Trigger Property="Validation.HasError" Value="false">
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="BorderBrush" Value="Transparent" />
        </Trigger>
    </Style.Triggers>
</Style>

<Style x:Key="DGCellStyle" TargetType="{x:Type DataGridCell}">
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="false">
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="BorderBrush" Value="Transparent" />
            <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Path=(Validation.Errors)[0].ErrorContent.ValidationMessage}"/>
        </Trigger>
    </Style.Triggers>
</Style>

Reference: http://social.msdn.microsoft.com/Forums/vstudio/en-US/6d2d6513-7bca-4359-a12b-46da3c380b0a/wpf-4-datagrid-editingelementstyle-and-validationerrortemplate-adorner-layer?forum=wpf

like image 38
MoMo Avatar answered Dec 23 '22 09:12

MoMo


Set the ValidatesOnDataErrors and ValidatesOnExpcetions to False for your binding of your cell. In case you want your validations, then you have to override the Validation Template for your control. Please refer to my answer here - Validation Error Style in WPF, similar to Silverlight

like image 37
Rohit Vats Avatar answered Dec 23 '22 09:12

Rohit Vats


I hated the red border because it was put in the adorner and adorners sit on top of the window, meaning that if your element is partially/fully hidden by another element (like it is in a grid) the full adorner still shows :(

That didn't mean I didn't want some customization though, so I can still highlight my items in pink, or change their foreground and have the DataGridCell correctly clip everything off. You can do this by using a style trigger.

Hope this helps!

<DataGrid.Resources>
    <Style TargetType="{x:Type TextBlock}" x:Key="TextBlockErrorStyle">
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <!-- Just the adorned element means NO RED BORDER -->
                    <AdornedElementPlaceholder Name="controlWithError" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="Foreground" Value="Red"/>
                <Setter Property="Background" Value="Pink"/>
                <Setter Property="ToolTip" 
                    Value="{Binding RelativeSource={RelativeSource Self},
                    Path=(Validation.Errors)[0].ErrorContent}"/>
            </Trigger>
        </Style.Triggers>
    </Style>
 </DataGrid.Resources>

...

<DataGridTemplateColumn  Header="Description" MinWidth="150">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=Description,  UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"
                        Style="{StaticResource ResourceKey=TextBlockErrorStyle}"
                        />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
like image 32
viggity Avatar answered Dec 23 '22 09:12

viggity