WPF Datagrid and Legacy Applications

April 24th, 2010

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:

wpf201004241

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

WPF Datagrid IsReadOnly

April 3rd, 2010

I have datagrids (from the WPF toolkit) that are read only. Nevertheless, once in a while certain dataset (ADO.NET) columns were producing the following error:
“A TwoWay or OneWayToSource binding cannot work on the read-only property …”
even if the corresponding binding used the OneTime or OneWay mode.
This was happening for each expression column in my dataset tables.

What I learned:
1. There is a bug in the WPF toolkit (don’t know whether it’s removed in VS 2010), that sets the binding as TwoWay even if it is explicitly defined as OneWay/OneTime.
2. To avoid the problem one simply needs to specify IsReadOnly=”True” for all expression columns.

PS. Same error occurs if the column is created using calculations in the SELECT statement.

Windows Presentation Foundation

March 4th, 2010

I have completed my long WPF project. Well, it was quite an experience. I guess, now I can modestly call myself a WPF Architect. :) I’ll try to summarize this experience and soon come up with a few blog posts about WPF problems I ran across.