GridView RowStyleSelector - Based on data value same as previous row

0 Answers 52 Views
GridView
Chris
Top achievements
Rank 1
Chris asked on 08 Feb 2022, 10:34 PM

I followed the instructions in this post to group based on data.

I modified the Github example AlternationRowStyleSelector  I changed the Club.cs code slightly to create a more manageable dataset for this example.

I used reflection to inspect the data in a property on the model.  For this example I looked at the data in the "Est." column.  I want to change the style when the value changes. 

Here is the modified code from AlternationRowStyle.cs

    public Style RowStyle { get; set; }
    public Style AltRowStyle { get; set; }
    public string PropertyName { get; set; }

    public override Style SelectStyle(object item, DependencyObject container)
    {
      var items = ((GridViewRow)container).GridViewDataControl.Items;

      Type t = item.GetType();
      PropertyInfo[] props = t.GetProperties();
      var currentItemValue = props.First(n => n.Name == PropertyName)?.GetValue(item, null);
      int currentItemIndex = items.IndexOf(item);
      if (currentItemIndex > 0)
      {
        var previousItem = items[currentItemIndex - 1];
        var previousItemValue = props.First(n => n.Name == PropertyName)?.GetValue(previousItem, null);
        if (currentItemValue.Equals(previousItemValue))
        {
          return RowStyle;
        }
        else
        {
          return AltRowStyle;
        }
      }

      return RowStyle;

Modified section of MainWindow.xaml

    <my:AlternationRowStyle x:Key="myRowStyle" PropertyName="Established" >
      <my:AlternationRowStyle.AltRowStyle>
        <Style TargetType="telerik:GridViewRow">
          <Setter Property="Background" Value="Gray"/>
        </Style>
      </my:AlternationRowStyle.AltRowStyle>
    </my:AlternationRowStyle>


As you can see the AltRowStyle is being activated when the value of a row is different from the one above it.  This isn't quite what I want.  I want to change styles when the value changes.  Specifically the seventh line above should be white not gray.   I tried a different approach where I used a boolean in the style selector and toggled it.  This works as desired.

Modified StyleSelector SelectStyle method.

    public override Style SelectStyle(object item, DependencyObject container)
    {
      var items = ((GridViewRow)container).GridViewDataControl.Items;

      Type t = item.GetType();
      PropertyInfo[] props = t.GetProperties();
      var currentItemValue = props.First(n => n.Name == PropertyName)?.GetValue(item, null);
      int currentItemIndex = items.IndexOf(item);
      if (currentItemIndex > 0)
      {
        var previousItem = items[currentItemIndex - 1];
        var previousItemValue = props.First(n => n.Name == PropertyName)?.GetValue(previousItem, null);
        if (!currentItemValue.Equals(previousItemValue))
        {
          altRowToggle = !altRowToggle;
        }
      }

      return altRowToggle ? this.AltRowStyle : this.RowStyle;
    }

If you make the window smaller so that you have to scroll, then scroll up and down a couple times to force it to redraw the items and run the style selector, it can get off track.

I realize the scrolling behavior is caused by my using a boolean in an attempt to keep track of the style to use.  When shrinking the grid, it re-evaluates the style selector based on the visible rows and determines which style to use but the toggle is in a state from the previous evaluation.

Is there a better way to achieve the desired result?

 

Thanks,

Chris

Stenly
Telerik team
commented on 11 Feb 2022, 04:13 PM

I will review this requirement and get back to with more information regarding this, at the beginning of the following workweek.
Stenly
Telerik team
commented on 16 Feb 2022, 04:23 PM

Hello Chris,

I generally understand what needs to be achieved, however, in order to prevent any misunderstandings, may I ask if you could provide a bit more information on the desired result? More specifically, do you want to apply a certain style, depending on the previous cell value, or do you want to do it when the current cell value is changed with a new one?

Chris
Top achievements
Rank 1
commented on 16 Feb 2022, 06:10 PM

Stenly,

My goal is to set the style based on the data in that row and the data from the previous row.  If the data in the current row changes, then I need to re-evaluate what the style should be.  If the data in this row makes it different from the surrounding rows - and previously it was visually grouped with one of them, then it needs to affect subsequent rows.

For example, say I change the year for Arsenal4 from 1886 to something other than 1892.  

I have attached the modified AlternationRowStyleSelector project from the Github examples where I have implemented what I have so far plus I merged in some of the items from the DragDropWithLines project.  Ultimately in my application, I will want to have drag and drop re-order functionality in addition to the ability to edit data in the cells.

If I add 

(sender as RadGridView).Rebind();

into the OnDrop method of the RowReorderBehavior, the issue is even more apparent.

Since the toggle is not reset and starts in the opposite state.

Hopefully this helps to clarify what I'm looking for.  I have looked into watching for the PropertyChanged event on the data value (Established) and then triggering the Rebind on the datagrid, but that doesn't solve the toggle issue.

Thanks,

Chris

Stenly
Telerik team
commented on 21 Feb 2022, 05:03 PM

Hello Chris,

I have examined the provided sample project, however, I am afraid that I cannot come up with a straightforward solution, without heavily modifying the RadGridView control's default behavior. Trying to achieve the desired result would require coming up with a logic that will be specific to your project's scenario, and one that would not result in issues, regarding the correct work of the RadGridView element.

No answers yet. Maybe you can help?

Tags
GridView
Asked by
Chris
Top achievements
Rank 1
Share this question
or