0

I've tried many options, but none seem to work fine for me. Here is the problem:

Dynamic columns. I get a list of dictionaries. All dictionaries may have different keys. E.g.

[ [key1: 111], [key2: 222] ]
[ [key1: 333], [key4: 444] ]
[ [key5: 777] ]

I need to display a grid with all keys as columns like this:

[key1] [key2] [key4] [key5]
  111    222
  333           444
                       777

This is pretty easy, I just generate columns in code either for GridView or DataGrid.

But there is a second requirement:

I need to color particular cells depending on value in them. E.g. for 111 bg color should be green, for 333 it should be red etc.

Currently I can only make one part work. I can dynamically create columns, but then I can't color them. Or I can create static columns and create custom cell templates with bindings for bg colors. But, then in every template I have to specify the binding. So the number of templates will be big. Is there a way to achive what I need, without generating template for each column?

Personally I would like to avoid generating templates in code.

Filburt
  • 17,626
  • 12
  • 64
  • 115
Vladimir Perevalov
  • 4,059
  • 18
  • 22

2 Answers2

0

Not sure I understand your problem completely, but it should be quite simple. DataGrid is amazingly flexible.

You almost have it, as far I understand. Now you want one global CellTemplate that can be obtained from XAML resources(so you don't hardcode it into code).

The CellTemplate can change colors based on triggers. You can either hardcode it into XAML or provide Dictionary that can map from "VALUE" to "COLOR" and just bind CellTemplate's Background to that Dictionary.

When you generate dynamically columns, you set DataGridTextColumn.CellTemplate to LoadDynamicallyXaml("yourresource"). When you generate columns, you have access to your DataGrid Resources, and you can obtain the CellTemplate from there too, that's cleaner way.

Loading XAML at runtime?

Community
  • 1
  • 1
Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
0

You can define a Style for a TextBlock that contains your DataTriggers and then just apply that Style to a TextBlock in your dynamically created columns... this method should be good for up to around 8 different value/colour pairs before the code gets too long:

<Style TargetType="{x:Type TextBlock}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding}" Value="111">
            <Setter Property="TextElement.Foreground" Value="LightGreen" />
        </DataTrigger>
        <DataTrigger Binding="{Binding}" Value="222">
            <Setter Property="TextElement.Foreground" Value="LightBlue" />
        </DataTrigger>
        <DataTrigger Binding="{Binding}" Value="333">
            <Setter Property="TextElement.Foreground" Value="LightPink" />
        </DataTrigger>
    </Style.Triggers>
</Style>

The other method that you can use is to use a Converter class with your Binding. You can find a detailed example of doing this in many online posts... here are a few:

How to set Foreground of DataGrid Column with ValueConverter
Datagrid AutoGenerateColumns="True" forecolor IValueConverter

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • Yes I tried what you show. But, unfortunately, the DataContext for TextBlock is the whole dictionary. So I don't get access to the actual value. And value converted to string (from Text binding) does not suit. – Vladimir Perevalov Dec 12 '13 at 14:24