DataGrid - Formatting and Styling

Sep 22, 2008 at 7:49 AM
I am working with the WPF DataGrid and attempting to determine how to do the following:

Given a data grid populated with data, when editing a cell I want to change the style of the cell based on the data that is being entered.  For example I might want the data grid cell to only enter characters, no numbers, so while the user is typing in the cell the cell would go red if the user typed a numeric value.

Presently I am using a DataGridTextColumn and have an "ElementStyle" and "EditElementStyle" set to use a converter so this functionality occurs when the data is initially populated (any invalid values have a red background) and when the user completes typing and moves to the next cell (if they have a numeric value in the cell it turns red).  I'd really like that "convert style" to occur as the user types so they get the feedback before moving cells.

Has anyone implemented something like this?  Is there some method of doing this that I'm not using?  Am I just doing this wrong?

thanks
Chris
Coordinator
Sep 22, 2008 at 7:24 PM
I'm not sure if you are putting the converter on the main binding for the column. If you are not and have your own Binding, then you can set UpdateSourceTrigger to PropertyChanged. The main binding uses Explicit so that it can control when the source is updated with the changes the user made.

Example:
{Binding Path=Example,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource ExampleConverter}}

Ben
Sep 23, 2008 at 1:59 AM
I tried to up the UpdateSourceTrigger in a couple of different locations, but without any luck.  This is what I have currently in terms of the converter/DataGridTextColumn.  Again this works perfectly on the initial binding and when one moves out of the cell, I'm just looking for a method of having this same functionality as the user types. 

This is what I currently have:
<dg:DataGridTextColumn DataFieldBinding="{Binding Description}" Header="Description">
    <dg:DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Background" Value="{Binding ., Converter={StaticResource DescriptionToCellStyleConverter}, ConverterParameter=DescriptionForeground }" />
            <Setter Property="ToolTip" Value="{Binding ., Converter={StaticResource DescriptionToToolTipConverter}, ConverterParameter=DescriptionToolTip }" />
        </Style>
    </dg:DataGridTextColumn.ElementStyle>
    <dg:DataGridTextColumn.EditingElementStyle>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Background" Value="{Binding ., Converter={StaticResource DescriptionToCellStyleConverter}, ConverterParameter=DescriptionForeground_EDIT }" />
            <Setter Property="ToolTip" Value="{Binding ., Converter={StaticResource DescriptionToToolTipConverter}, ConverterParameter=DescriptionToolTip_EDIT }" />
        </Style>
    </dg:DataGridTextColumn.EditingElementStyle>
</dg:DataGridTextColumn>

thanks
Chris
Coordinator
Sep 23, 2008 at 2:15 AM
The issue is that your Background and ToolTip Bindings do not refer to a path. They refer to the DataContext object. This means they will not be re-evaluated unless the DataContext itself changes (or when focus changes). If you changed them to refer to Description (requiring the converters to be changed too since they'll be receiving the value of Description instead of the DataContext object), you might have better results.

Ben
Sep 23, 2008 at 4:10 AM
I've tried your suggestion, but the Converter only seems to execute once I change fields still.  I've attached the updated code here (note: I removed the ToolTip to make this a bit cleaner/easier to read).  I've tried putting the UpdateSourceTrigger in a couple of locations, but am guessing it is best on the DataGridTextColumn?  Am I just putting that in the wrong area or is there something else?

<dg:DataGridTextColumn DataFieldBinding="{Binding Description, UpdateSourceTrigger=PropertyChanged}" Header="Description">
    <dg:DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Background" Value="{Binding Description, Converter={StaticResource DescriptionToCellStyleConverter}}" />
        </Style>
    </dg:DataGridTextColumn.ElementStyle>
    <dg:DataGridTextColumn.EditingElementStyle>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Background" Value="{Binding Description, Converter={StaticResource DescriptionToCellStyleConverter}}" />
        </Style>
    </dg:DataGridTextColumn.EditingElementStyle>
</dg:DataGridTextColumn> 

thanks
Chris
Coordinator
Sep 23, 2008 at 7:44 PM

Change the bindings on the TextBlock/TextBox to {Binding Text,RelativeSource={RelativeSource Self},Converter={StaticResource TestConverter}}.

The DataFieldBinding is always set to Explicit and can't be changed in order to control updates to the source. This is why Description would not update and thus why other bindings to Description would not update.

Ben

Sep 24, 2008 at 2:03 AM
Ben,

That works perfectly, thanks for all your help.

best regards,
Chris