Datagrid cell colour problems

Mar 9, 2009 at 1:40 PM
I am using a WPF Datagrid and have set up a converter to set the background/foreground colours of individual cells based on the value they contain (from an SQL generated datatable).
In order to get some decent sort of speed, I have row and column virtualization set to true, (if I don't, the change of sort on the column and the scrolling lag is unbearably slow and wouldn't be accepted by the client).
The only problem I have is that sometimes when I scroll around the grid, the colours displayed are wrong, if I scroll out and back in to that area, sometimes they correct themselves.
As the colours are representing critical data, this is obviously not good.

I did try putting the datagrid into a scrollviewer, the problem there was one had to scroll to the bottom to get the horizontal scrollbar (my grid has 2 fixed columns on the left), plus, in order to change sorts on the column headers, you have to then scroll back to the top.

Is there a known fix to prevent the colours getting messed up? I have read about loadingrow and unloading row, but that seems to be related to a whole row template rather than reacting to the individual cells (datatable fields).

I presume this is very much a known problem so I am hoping it also has a known solution, apart from not using virtualisation, which as I stated, makes the speed of the grid, to all intents and purposes, unusable.

I have uploaded a full example project here:

http://www.kaisoft-gfx.co.uk/workarea/RotaEnqTester.zip

The view example shown is not uncommon, likely to have 90 columns by anything upto 300 rows.
I'd be grateful if anyone can assist.

PS - I had tried the Xceed datagrid but this seems to suffer the same problems and if anything, the display lag is even slower.

Coordinator
Mar 9, 2009 at 7:10 PM
Hi TerianCS,

I see that in your style of DataGridCell you are binding Foreground and Background to the cell itself and its DataRow. When column virtualization and recycling is turned on cells are used across different columns of same row. Lets consider your case...

  1. A style gets applied to a cell based on itself and its DataRow.
  2. Now when you scroll, this cell gets recylced and used with other columns of same row
  3. None of the two bindings got affected. Its the same DataRow and its the same cell.
  4. Hence cell uses same previous Foreground and Background.

Trying binding to Column property of cell instead of binding to cell itself (I see that you are using cell only to get column). In fact you can bind to Column.SortMemeberPath directly.

Mar 10, 2009 at 10:27 AM
Edited Mar 10, 2009 at 11:06 AM
Forgive me for sounding a bit dense, but am I right in thinking that the way i'm doing it now is very much overkill and is in fact having an impact on the performance?
I must admit I put the code together based on snippets I'd seen on the web so assumed that was the 'logical' way.
Even though I am needing to react to the cell contents, I just use the row and column information, not the cell?

If it's not too much to ask, would it be possible to show me a snippet of code please? Many thanks for your time, this will be very important to us but so far we are very much at the sharp end of the learning curve!

Is this right for the XAML?

                <Setter Property="Foreground">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource myFGColor}" >
                            <MultiBinding.Bindings>
                                <Binding Path="Column.SortMemberPath">
                                </Binding>
                                <Binding Path="Row"></Binding>
                            </MultiBinding.Bindings>
                        </MultiBinding>
                    </Setter.Value>
                </Setter>

Every time I try to use it, I get a '{DependencyProperty.UnsetValue}' not the sortmemberpath or even if I use the <Binding Path="Column">.


Coordinator
Mar 10, 2009 at 5:08 PM
                <Setter Property="Foreground">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource myFGColor}" >
                            <MultiBinding.Bindings>
                                <Binding RelativeSource="{RelativeSource Self}" Path="Column.SortMemberPath">
                                </Binding>
                                <Binding Path="Row"></Binding>
                            </MultiBinding.Bindings>
                        </MultiBinding>
                    </Setter.Value>
                </Setter>

The above should work. (Note that I didnt try this with your application but I am hoping that it would work).
Mar 11, 2009 at 10:39 AM
Many thanks!
I had found that PATH="(Column)" worked but this is better as it reduces a step in the converters.

I am still getting a bit of failure to refresh the view properly, but that is on the columnheader and as maximising & restoring the view seems to sort it out, I think it may be just a display issue as just shifting the scrollbar never fixed the cell colours but does with this.