When you migrate legacy LOB applications, your customers always want to keep “old good” features. I still remember how in mid-1990s I delivered a new fancy system to one of the Lower Mainland warehouses. Client-server application with a fancy Windows 95 client and MS SQL Server as a back-end… I was so proud of myself… The first question that I heard from the customer was “How can we get rid of these colors?” — she meant new Windows 95 colors…
Well, now working with WPF… “How can we have Access/Visual Basic 6/old programs-like indicators for selected and new lines on the data grids?” That is the question, as Shakespeare would say.
I spent a lot of time (and I mean a lot) to answer this question, especially its second part about the new line indicator. And see what I got:
The following style completely defines the selected row indicator and partially (you also need some code behind) deals with the new row indicator:
<Style TargetType="toolkit:DataGridRowHeader"
x:Key="DataGridRowHeaderStyle">
<Setter Property="Content"
Value="{Binding Converter={StaticResource cnvNewRowIndicatorConverter}}" />
<Setter Property="Foreground" Value="RoyalBlue" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontSize" Value="15" />
<Setter Property="Height" Value="18" />
<Style.Triggers>
<Trigger Property="IsRowSelected" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="Black"
BorderThickness="0,1,0,1"
Margin="0,-1,0,0">
<DockPanel Background="Transparent">
<Path x:Name="arrow"
StrokeThickness = "1"
Fill = "RoyalBlue"
Data = "M 5,13 L 10,8 L 5,3 L 5,13"/>
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
For the new line indicator we need to add some code behind:
Public Class NewRowIndicatorConverter
Implements IValueConverter
Public Function Convert(ByVal value As Object, _
ByVal targetType As System.Type, _
ByVal parameter As Object, _
ByVal culture As System.Globalization.CultureInfo) As Object _
Implements System.Windows.Data.IValueConverter.Convert
If value Is Nothing Then Return ""
If value.GetType.FullName = "MS.Internal.NamedObject" Then Return "*"
Return ""
End Function
Public Function ConvertBack(ByVal value As Object, _
ByVal targetType As System.Type, _
ByVal parameter As Object, _
ByVal culture As System.Globalization.CultureInfo) As Object _
Implements System.Windows.Data.IValueConverter.ConvertBack
' this function is not supposed to be called
Throw New Exception
End Function
End Class

