This is a migrated thread and some comments may be shown as answers.

GridViewCell styling based on the property of the cell's value

7 Answers 690 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Boardy
Top achievements
Rank 1
Veteran
Boardy asked on 31 Oct 2017, 10:23 AM

The items shown in my grid have properties of the type

public class CheckerProperty
{
  ...
  public object Value { get; private set; }
  public bool Changed { get; private set; }
}

(So there is an itm.Status property of type CheckerProperty and a itm.Diameter of type CheckerProperty etc.) The Value should be shown, and when the Changed property is true, the background should have a different colour.

Since there are a lot of diferent properties and I would like to have a single style that handles the background change. Something like:

<Style x:Key="stlChangeCheckerProp" TargetType="telerik:GridViewCell" BasedOn="{StaticResource GridViewCellStyle}">
    <Setter Property="telerik:GridViewCell.Background" Value="Transparent" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self}}" Value="True">
            <Setter Property="telerik:GridViewCell.Background" Value="{StaticResource brChange}" />
        </DataTrigger>
    </Style.Triggers>
</Style>

I'm struggling with the binding. How can I bind to the Changed property of the cell's value? It seems when I use RelativeSource, as in this example, I get the GridViewCell itself. When I use no RelativeSource, I get the item itself and I don't know which property (Status, Diameter etc.) is being displayed.

How can I set up the binding correctly?

7 Answers, 1 is accepted

Sort by
0
Simon
Top achievements
Rank 1
answered on 01 Nov 2017, 02:58 AM
GridViewColumn.CellStyleSelector can be set to a StyleSelector that can change cell styling such as BackgroundColor dynamically depending on the cell contents.
0
Boardy
Top achievements
Rank 1
Veteran
answered on 01 Nov 2017, 10:51 AM

Thank you for your reply. But when using a CellStyleSelector, I get the item (subclass of Checker) for the row, Not the item (class CheckerProperty) that is presented in the cell.

I managed get the desired result by using a multi-binding on the row-item and the GridViewCell. From the latter I can derive the property being displayed in the cell (with cell.Column.UniqueName) and then use reflection to get the value from the item. It seems rather circuitous, but it seems to yield the desired result.

If there's a better way, I would really like to hear from it.

0
Simon
Top achievements
Rank 1
answered on 01 Nov 2017, 06:56 PM
What you have described is exactly how I do it.  I do not know of a better way.
0
Simon
Top achievements
Rank 1
answered on 01 Nov 2017, 07:38 PM

In my previous post, I said 'What you have described is exactly how I do it.'  On second thoughts, that only applies to 'I can derive the property being displayed in the cell (with cell.Column.UniqueName) and then use reflection to get the value from
the item'.

I've never used multi-binding.  I had to look it up just now to see what it means, but I think I get it.  Perhaps there's something specific to your application that I've not understood or I've not understood multi-binding.  But, as it stands, I wonder if you could simplify your XAML by dispensing with the multi-binding.  I cannot see how it is relevant to CellStyleSelector. Here's why:

The cell value can itself be a class instance with multiple properties, as is the case in your CheckerProperty class.  So, in the SelectStyle override method of your CellStyleSelector class (a subclass of StyleSelector), simply cast the cell value obtained by reflection to an instance of the class.  All those properties will be exposed for your use, e.g. if one of them indicates the requirement for a cell format change, as with your CheckerProperty.Changed property.

Perhaps what you are missing to make this simpler solution work for CheckerProperty to override the ToString() method.  Then, if your XAML simply bind to CheckerProperty instead of multi-binding its Value and Changed properties, what will actually be displayed on the grid will be only what CheckerProperty.ToString() evaluates to. 

So, CheckerProperty.ToString() could be coded something like this:

public override string ToString() {

    return Value.ToString() // where Value.ToString() returns Value suitably formatted.

}

If you code CheckerProperty.ToString() something like the above, the XAML will simply ignore the Changed property (and only access the Value property indirectly, via ToString()).  But that should be fine, as I think you only need to access the Changed property in the CellStyleSelector.

0
Boardy
Top achievements
Rank 1
Veteran
answered on 02 Nov 2017, 10:52 AM

Thanks for the suggestion of overriding ToString(). That's exactly what I do.

The problem with the CellStyleSelector is that the first parameter of the SelectStyle() method is the item itself (Checker) not the displayed property (CheckerProperty). In other words: I still have to do reflection to get the property I want.

0
Accepted
Simon
Top achievements
Rank 1
answered on 02 Nov 2017, 06:41 PM

[quote]Boardy said:

Thanks for the suggestion of overriding ToString(). That's exactly what I do.[/quote]

Good.  So, just to clarify, does that mean you no longer need to do multi-binding?

[quote]Boardy said:

The problem with the CellStyleSelector is that the first parameter of the SelectStyle() method is the item itself (Checker) not the displayed property (CheckerProperty). In other words: I still have to do reflection to get the property I want.[/quote]

That's right.  There's no way round that.

0
Boardy
Top achievements
Rank 1
Veteran
answered on 03 Nov 2017, 07:47 AM
[quote]Simon said:

Good.  So, just to clarify, does that mean you no longer need to do multi-binding?[/quote]

I don't need the multi-binding for displaying the property's value. It's used solely for the styling.

[quote]Simon said:

[quote]Boardy said:

The problem with the CellStyleSelector is that the first parameter of the SelectStyle() method is the item itself (Checker) not the displayed property (CheckerProperty). In other words: I still have to do reflection to get the property I want.[/quote]

That's right.  There's no way round that.

[/quote]

Ok. That means I can choose if I want to use the CellStyleSelector or multi-binding as a way to get the data needed to derive the value of the cell, but there's no direct way to get it.

Tags
GridView
Asked by
Boardy
Top achievements
Rank 1
Veteran
Answers by
Simon
Top achievements
Rank 1
Boardy
Top achievements
Rank 1
Veteran
Share this question
or