Format Parent Row Based on Child Formatting

6 posts, 0 answers
  1. Eddie
    Eddie avatar
    6 posts
    Member since:
    Mar 2011

    Posted 24 Jun 2014 Link to this post

    I am formatting child rows in a hierarchical grid based on information contained in one of the columns. For example, if a column "Quantity" contains a number below a certain value, I change the RowElement.BackColor to a specific color. I am doing this in the CellFormatting event and it works well. Some rows will be colored and some will not depending on the value of that cell.

    Now I would like to be able to format the parent to have a specific BackColor if any of its Child Rows has been formatted, i.e. contains a value under the indicated value.

    I cannot find a way to access the Parent Row in a way that I can format it once I determine that the child row meets the condition for formatting.
  2. Stefan
    Admin
    Stefan avatar
    2908 posts

    Posted 26 Jun 2014 Link to this post

    Hello Eddie,

    Thank you for writing.

    To style the parent row, you will have to use the formatting events again. Here is a small sample demonstrating how to do this:
    void radGridView1_CellFormatting(object sender, CellFormattingEventArgs e)
    {
        if (e.Row is GridViewHierarchyRowInfo)
        {
            GridViewHierarchyRowInfo parentRow = e.Row as GridViewHierarchyRowInfo;
     
            bool shouldStyleCell = false;
            foreach (GridViewRowInfo row in parentRow.ChildRows)
            {
                if ((int)row.Cells["Quantity"].Value < 30)
                {
                    shouldStyleCell = true;
                    break;
                }
            }
     
            if (shouldStyleCell)
            {
                e.CellElement.DrawFill = true;
                e.CellElement.BackColor = Color.Red;
            }
            else
            {
                e.CellElement.ResetValue(LightVisualElement.DrawFillProperty, ValueResetFlags.Local);
                e.CellElement.ResetValue(LightVisualElement.BackColorProperty, ValueResetFlags.Local);
            }
        }
    }

    Let me know how this works for you.

    Regards,
    Stefan
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  3. Eddie
    Eddie avatar
    6 posts
    Member since:
    Mar 2011

    Posted 26 Jun 2014 in reply to Stefan Link to this post

    Hello Stefan,

    Your method iterates through the children of the parent row to determine whether it needs to be formatted (going from the top to the bottom). Is there a way rather than trickling down from the parent, to trickle up from the child? It seems it would be more efficient code since I am already determining whether a child row needs to be formatted. At the point when this is determined, I would like to format the parent row without iterating through all the child rows.
  4. Stefan
    Admin
    Stefan avatar
    2908 posts

    Posted 26 Jun 2014 Link to this post

    Hello,

    Well, you could do that, but this would require that you expand all your hierarchy rows in order the condition to be executed, which would determine whether the parent should be colorized. Here is how this can be achieved:
    void radGridView1_CellFormatting(object sender, CellFormattingEventArgs e)
    {
        if (e.Row.ViewTemplate != radGridView1.MasterTemplate &&
            e.Column.Name == "ID" &&
            e.CellElement.Value is int &&
            (int)e.CellElement.Value<30)
        {
            e.CellElement.DrawFill = true;
            e.CellElement.BackColor = Color.Red;
            e.CellElement.NumberOfColors = 1;
             
            ((GridViewHierarchyRowInfo)e.Row.Parent).Tag = "styleThisRow";
        }
        else if (e.Row.Tag == "styleThisRow")
        {
            e.CellElement.DrawFill = true;
            e.CellElement.BackColor = Color.Yellow;
            e.CellElement.NumberOfColors = 1;
        }
        else
        {
            e.CellElement.ResetValue(LightVisualElement.DrawFillProperty, ValueResetFlags.Local);
            e.CellElement.ResetValue(LightVisualElement.BackColorProperty, ValueResetFlags.Local);
            e.Row.Tag = null;
        }
      
    }

    I hope this helps.

    Regards,
    Stefan
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  5. Eddie
    Eddie avatar
    6 posts
    Member since:
    Mar 2011

    Posted 26 Jun 2014 in reply to Stefan Link to this post

    Thanks Stefan, but why would I need to expand all the hierarchy rows? This is the code I currently have to determine whether a child row needs to be formatted. I would like to be able to set the parent row 's back color to pint in the part of the code where I set the child row's back color to pink.

    Private Sub gvwRequirements_CellFormatting(sender As Object, e As Telerik.WinControls.UI.CellFormattingEventArgs) Handles gvwRequirements.CellFormatting
           If e.Column.Name = "Revision" AndAlso e.Row.HierarchyLevel = 1 AndAlso e.CellElement.Value IsNot Nothing Then
               If DirectCast(e.CellElement, GridDataCellElement).Value.ToString().Equals([String].Empty) Then
                   If e.Row.Cells("Employee Name").Value.ToString().Equals([String].Empty) Then
                       e.CellElement.RowElement.DrawFill = True
                       e.CellElement.RowElement.ForeColor = Color.Gray
                       e.CellElement.RowElement.NumberOfColors = 1
                       e.CellElement.RowElement.BackColor = Color.LightGray
                   Else
                       e.CellElement.RowElement.DrawFill = True
                       'e.CellElement.RowElement.ForeColor = Color.Red
                       e.CellElement.RowElement.NumberOfColors = 1
                       e.CellElement.RowElement.BackColor = Color.Pink
                   End If
               ElseIf CInt(e.CellElement.Value) < CInt(e.Row.Cells("Current Revision").Value) Then
                   e.CellElement.RowElement.DrawFill = True
                   e.CellElement.RowElement.ForeColor = Color.Red
                   e.CellElement.RowElement.NumberOfColors = 1
                   e.CellElement.RowElement.BackColor = Color.LightYellow
               Else
                   e.CellElement.RowElement.ResetValue(LightVisualElement.DrawFillProperty, ValueResetFlags.Local)
                   e.CellElement.RowElement.ResetValue(LightVisualElement.ForeColorProperty, ValueResetFlags.Local)
                   e.CellElement.RowElement.ResetValue(LightVisualElement.NumberOfColorsProperty, ValueResetFlags.Local)
                   e.CellElement.RowElement.ResetValue(LightVisualElement.BackColorProperty, ValueResetFlags.Local)
     
     
               End If
           End If
       End Sub

  6. Stefan
    Admin
    Stefan avatar
    2908 posts

    Posted 30 Jun 2014 Link to this post

    Hi Eddie,

    RadGridView uses UI virtualization for its cells, which means that there are only certain amount of cells visible at all times and the data in these cells is being changed when scrolling. More information and examples you can find here:  http://www.telerik.com/help/winforms/gridview-cells-formatting-cells.html.

    So, the formatting events are fired for each element that needs to be formatted - for example when data is changed, when you scroll, etc. When the CellFormatting is fired for a cell in the child template, in the event arguments you have precisely this cell (and its row and column) and you do not have access to its parent row visual element in order to format it. So, the only way to format the parent row is when the formatting event is triggered for it, not for the child. However, when the formatting event is fired for the parent, you have to somehow determine whether the row should be formatted or not. One way to do that is to iterate the child rows (the first suggestion provided). This is what I would recommend. Another way is every time you format a child, to set the child's parent row (logical row not visual row) Tag, so you can use this tag later, when the event is fired for the parent in order to determine whether to style the parent row or not. However, this would require expanding all parent rows in advance, so the logic for the child rows can be executed in advance and the Tag for the parent row to be populated. 

    I hope that this clears things up.

    Regards,
    Stefan
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
Back to Top