Thursday, January 16, 2014

The difference between DataGridTextColumn style and ElementStyle

WPF Version 4.0

Sometimes I can be a bit retarded. I have some XAML that looks like this

<DataGrid Name="EditItemDetailsDataGrid" ItemsSource="{Binding}" AutoGenerateColumns="false">
   <DataGrid.Columns>
       <DataGridTextColumn Header="#" Binding="{Binding Path=Sequence}" IsReadOnly="true" Foreground="Red"/>
   </DataGrid.Columns>
<DataGrid/>

Simple stuff right? Now I have a column in the backing store for this grid that is called "HasErrors". When HasErrors is one I want the Sequence column to have a red foreground, otherwise a black foreground. My first attempt was to use an existing converter called HasErrorsToBrush like this...

<DataGrid Name="EditItemDetailsDataGrid" ItemsSource="{Binding}" AutoGenerateColumns="false">
   <DataGrid.Columns>
       <DataGridTextColumn Header="#" Binding="{Binding Path=Sequence}" IsReadOnly="true" Foreground="{Binding Path=HasErrors, Converter={StaticResource HasErrorsToBrush}}"/>
   </DataGrid.Columns>
<DataGrid/>

But this doesn't work. I put a breakpoint in the converter but it's being used by other grids on the page so I couldn't tell whether this column was calling it or not. Here's a nifty tip...

Converters have a converter parameter. I modified the binding to add a parameter like this.


    Foreground="{Binding Path=HasErrors, Converter={StaticResource HasErrorsToBrush}, ConverterParamter=SEQ}"

Now when I put a break point in the converter I can see that it's never getting called with a parameter of SEQ. What the hell?

Then I realized I was binding the Foreground for the DataGridCell, not for the TextBlock element in the cell. To do that I needed to work a little harder.

<DataGrid Name="EditItemDetailsDataGrid" ItemsSource="{Binding}" AutoGenerateColumns="false">
   <DataGrid.Columns>
       <DataGridTextColumn Header="#" Binding="{Binding Path=Sequence}" IsReadOnly="true"/>
           <DataGridTextColumn.ElementStyle>
               <Style TargetType="TextBlock">
                   <Setter Property=Foreground" Value="{Binding Path=HasErrors, Converter={StaticResource HasErrorsToBrush}}"/>
               </Style>
           </DataGridTextColumn.ElementStyle>
       </DataGridTextColumn>
   </DataGrid.Columns>
<DataGrid/>

Simple stuff, to be sure, but if you're not paying attention you can waste a lot of time on simple stuff.

No comments:

Post a Comment