Changing the GroupByExpression on dynamic grouping

24 posts, 1 answers
  1. erwin
    erwin avatar
    358 posts
    Member since:
    Dec 2006

    Posted 28 May 2008 Link to this post

    In my sample grid, I would like to allow grouping by the user, but add a count(fieldname) aggreagate to the groupbyexpression.
    I found examples for the ASP.NET Grid but could not directly apply these to the WinForms Grid.

    regards
    erwin
  2. Answer
    Jack
    Admin
    Jack avatar
    2333 posts

    Posted 30 May 2008 Link to this post

    Hello Erwin,

    Thanks for the good question.

    Yes, you can achieve the required functionality. You should handle the GroupingChanging event and add the required aggregate to the SelectedFields collection of the new GridGroupByExpression. Note that adding a new aggregate will change the collection again and the event will be fired one more time. This could lead to an infinite recursion, i.e. stack overflow. One way to avoid that is to implement a flag that controls the recursive call.

    Please refer to the following example:

    1 private bool addingAggregate = false
    2  
    3 public Form1() 
    4
    5     InitializeComponent(); 
    6  
    7     this.radGridView1.GroupByChanging += new GridViewCollectionChangingEventHandler(radGridView1_GroupByChanging); 
    8
    9  
    10 private void radGridView1_GroupByChanging(object sender, GridViewCollectionChangingEventArgs e) 
    11
    12     if (addingAggregate) return
    13      
    14     GridGroupByExpression expression = e.NewItems[0] as GridGroupByExpression; 
    15     if (expression == null
    16         return
    17  
    18     addingAggregate = true
    19     GridGroupByField field = new GridGroupByField(expression.SelectFields[0].FieldName); 
    20     field.Aggregate = GridAggregateFunction.Count; 
    21  
    22     expression.SelectFields.Add(field); 
    23  
    24     addingAggregate = false
    25

    I hope this helps. Should you have further questions, do not hesitate to ask.

    Best wishes,
    Jack
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  3. UI for WinForms is Visual Studio 2017 Ready
  4. erwin
    erwin avatar
    358 posts
    Member since:
    Dec 2006

    Posted 31 May 2008 Link to this post


    Thanks, this is what I needed. Had to add an additional test to your code to make it crash proof:

    if(e.NewItems=null) return;













  5. Jack
    Admin
    Jack avatar
    2333 posts

    Posted 02 Jun 2008 Link to this post

    Hi erwin,

    You are correct, thank you for this correction.

    I am glad to hear that the issue is now resolved. Do not hesitate to contact me again if you have other questions.

    Best wishes,
    Jack
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  6. erwin
    erwin avatar
    358 posts
    Member since:
    Dec 2006

    Posted 27 Aug 2008 Link to this post

    The sample code provided does not work correctly when the column contains
    NULL cells. The Grouping works, that is all rows that have a NULL value
    are grouped together, but the aggreagte COUNT() function returns 0 ,
    even if the group contains several rows.
  7. Julian Benkov
    Admin
    Julian Benkov avatar
    1135 posts

    Posted 29 Aug 2008 Link to this post

    Hi Erwin,

    The current implementation and design of the Count aggregate ignores rows with NULL values, although we do plan to redesign this behavior.

    Currently you can use a solution with the RagGridView GroupSumaryEvaluate event:

    void radGridView1_GroupSumaryEvaluate(object sender, GroupSummaryEvaluationEventArgs e) 
        if (e.SummaryItem.Aggregate == GridAggregateFunction.Count) 
        { 
            e.Value = e.Group.RowCount; 
        } 


    All the best,
    Julian Benkov
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  8. erwin
    erwin avatar
    358 posts
    Member since:
    Dec 2006

    Posted 31 Aug 2008 Link to this post

    Hi Julian,

    your solution is just what I needed - thanks a lot.

    Regards
    Erwin
  9. erwin
    erwin avatar
    358 posts
    Member since:
    Dec 2006

    Posted 18 Dec 2008 Link to this post


    Grids that have this mechanism enabled, seem to have problems using SaveLaout() / LoadLayout()

    I have of course added a flag, that suppresses the GroupByChanging event being handled when caused by LoadLayout.

    When I do a SaveLayout() and then a LoadLayout() the group captions (combined format strigs) seem to duplicate.
           static void grid_GroupByChanging(object sender, GridViewCollectionChangingEventArgs e) 
            [ 
                if (_addingAggregates) 
                [ 
                    return
                ] 
     
                if(_loadingLayout) 
                [ 
                    return
                ] 
     
                if(e.NewItems == null
                [ 
                    return
                ] 
     
                if(e.NewItems.Count<1) 
                [ 
                    return
                ] 
     
                GridGroupByExpression expression = e.NewItems[0] as GridGroupByExpression; 
     
                if (expression == null
                    return
     
                if(expression.SelectFields==null
                [ 
                    return
                ] 
     
                if(expression.SelectFields.Count<1) 
                [ 
                    return
                ] 
     
                try 
                [ 
                    _addingAggregates = true
                    expression.SelectFields[0].FormatString = "[0]: [1]"
                    GridGroupByField field = new GridGroupByField(expression.SelectFields[0].FieldName); 
                    field.Aggregate = GridAggregateFunction.Count; 
                    field.FormatString = " ([1])"
                    expression.SelectFields.Add(field); 
                ] 
                finally 
                [ 
                    _addingAggregates = false
                ] 
            ] 
     

            static public bool LoadLayout(RadGridView grid) 
            [ 
                GridInfo info = grid.Tag as GridInfo; 
     
                if (info == null
                [ 
                    return false
                ] 
     
                string savePath = System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); 
                savePath += `"\Octosoft\Octopus\GridLayouts"
     
                savePath += `"\" + info.Guid.ToString() + ".xml"
     
                if(File.Exists(savePath)) 
                [ 
                    try 
                    [ 
                        Debug.Assert(grid.Tag == info); 
                        _loadingLayout = true
                        grid.LoadLayout(savePath); 
                        //MessageBox.Show(grid.Tag.GetType().ToString() + ":" +grid.Tag.ToString()); 
                        //Debug.Assert(grid.Tag == info); 
                        // have to re-set the Tag object, since it got destroyed by LoadLayout 
                        //TODO: BUG in 2008Q3SP1 TicketID 181002  
                        grid.Tag=info; 
                        return true
                    ] 
                    catch (System.Exception ex) 
                    [ 
                        ErrorMessage.Show("Error Loading Grid Layout: " + savePath, ex); 
                        File.Delete(savePath); 
                        return false
                    ] 
                    finally 
                    [ 
                        _loadingLayout = false
                    ] 
                ] 
                return false
            ] 
     

  10. Boyko Markov
    Admin
    Boyko Markov avatar
    610 posts

    Posted 19 Dec 2008 Link to this post

    Hi erwin,

    Thank you very much about your valuable feedback. I am afraid that this behavior can not be avoided in an easier way than you already found. When saving loading/layout grid view persists all related object, like the group-by expressions. After loading the xml with group-expressions persisted, you should not add the custom group-by count field - as you already figured it out.
    The other option would be to exclude all the group-by expressions from persistence if this fits in your scenario.

    Greetings,
    Boyko Markov
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  11. erwin
    erwin avatar
    358 posts
    Member since:
    Dec 2006

    Posted 22 Dec 2008 Link to this post

    Boyko,

    thanks for the response - what I meant is that despite of my efforts, the grid does not save/load layouts correctly in my scenario. Some of the definitions seem to get duplicated on either Save or Load.
    I have filed a bug report with a stripped down sample project that exposes the bug.

    Regards
    Erwin
  12. Nick
    Admin
    Nick avatar
    767 posts

    Posted 23 Dec 2008 Link to this post

    Hello erwin,

    Please refer to the sample application that I send to you in one of your previous tickets about the Tag property (Ticket Id: 181002).

    Sincerely yours,
    Nick
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  13. erwin
    erwin avatar
    358 posts
    Member since:
    Dec 2006

    Posted 23 Dec 2008 Link to this post

    Thank you, Nick

    I've implemented the suggested workaround.

    Regards & Happy Holidays

    Erwin
  14. Dragoljub
    Dragoljub avatar
    26 posts
    Member since:
    Feb 2008

    Posted 29 Jan 2009 Link to this post

    I am having the same issue with an aggregate in the group by expression and load layout. The whole expression gets duplicated. Can you post an example of how to avoid this?
  15. Nick
    Admin
    Nick avatar
    767 posts

    Posted 29 Jan 2009 Link to this post

    Hi Dragoljub,

    Thank you for your question. I have attached the sample application I sent to Erwin. I hope this helps.

    Do not hesitate to contact me back if you have more questions.

    All the best,
    Nick
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  16. Dragoljub
    Dragoljub avatar
    26 posts
    Member since:
    Feb 2008

    Posted 30 Jan 2009 Link to this post

    Hello,

            Dim stringWriter As New IO.StringWriter() 
            Using xmlWriter As New Xml.XmlTextWriter(stringWriter) 
                serializer.WriteObjectElement(xmlWriter, radGrid) 
                xmlWriter.Close()   ' important line - it creates the closing tag for the root element 
            End Using 
            Return stringWriter.ToString()

    In that code I get an exception on serializer.WriteObjectElement(xmlWriter, radGrid): "Index was outside the bounds of the array.".
    Stack trace:
    "   at System.Xml.XmlTextWriter.WriteEndStartTag(Boolean empty)    at System.Xml.XmlTextWriter.AutoComplete(Token token)    at System.Xml.XmlTextWriter.WriteStartElement(String prefix, String localName, String ns)    at System.Xml.XmlWriter.WriteNode(XmlReader reader, Boolean defattr)    at Telerik.WinControls.XmlSerialization.ComponentXmlSerializer.WriteObjectElement(XmlWriter writer, Object toWrite)    at ...

    I don't know what I did wrong. I just know that it does not work even when I deleted the old stored layout. Can it be a different version of RadGrid? I am using: Q3 2008 (8.1.0.0 when browsed in references).
  17. Dragoljub
    Dragoljub avatar
    26 posts
    Member since:
    Feb 2008

    Posted 30 Jan 2009 Link to this post

    I meant Q3 2008 SP1 (just didn't see the "SP1" on the start menu folder, it was cut off).
  18. Dragoljub
    Dragoljub avatar
    26 posts
    Member since:
    Feb 2008

    Posted 30 Jan 2009 Link to this post

    I just read the newsletter and there's an SP2 release! It says "RadGridView: introduced an API for customizing XML Serialization", so maybe that's the thing? Your code works for the new version only?
  19. Miroslav Stantic
    Miroslav Stantic avatar
    42 posts
    Member since:
    Oct 2003

    Posted 02 Feb 2009 Link to this post


  20. Dragoljub
    Dragoljub avatar
    26 posts
    Member since:
    Feb 2008

    Posted 02 Feb 2009 Link to this post

    No, I tried it with the new version (uninstalled the previous one first of course) and still get that same error.

    What is "API for customizing XML Serialization" and how do I use that? Maybe that can help...
  21. Mike
    Admin
    Mike avatar
    640 posts

    Posted 02 Feb 2009 Link to this post

    Hello Dragoljub,

    Thank you for contacting me back.
    Yes indeed, we introduced new API that much simplifies the tweaking the serialization in SP2.
    Here is sample code (modified version of a snipped from the previously attached sample):

    Me.radGridView1.XmlSerializationInfo.SerializationMetadata.Add(GetType(Control), "Tag"New DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)) 
    Me.radGridView1.XmlSerializationInfo.SerializationMetadata.Add(GetType(GridViewTemplate), "SummaryRowGroupHeaders"New DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)) 
    'here you may exclude/include other properties. 
     
    Me.radGridView1.SaveLayout(sfd.FileName) 

    Note you you are no longer required to use GridLayoutSerializer. Now you can just modify the serialization metadata it uses. You need to do this customization only once per grid instance.

    Let me know if this helped.

    All the best,
    Mike
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  22. Dragoljub
    Dragoljub avatar
    26 posts
    Member since:
    Feb 2008

    Posted 04 Feb 2009 Link to this post

    Thanks, it helped. Now it saves without that nasty exception.
  23. Mike
    Admin
    Mike avatar
    640 posts

    Posted 04 Feb 2009 Link to this post

    Hi Dragoljub,

    I am glad it helped.
    In case you want to learn more about grid settings persistence, we just post a KB article and demo project that is wort having a look at:
    http://blogs.telerik.com/blogs/09-02-03/RadGridView_s_Serialization_Made_Easy_WinForms.aspx

    In short, the article describes a way to let the end user specify which grid settings should be persisted and which should not.

    All the best,
    Mike
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  24. Emix
    Emix avatar
    4 posts
    Member since:
    Mar 2013

    Posted 02 Mar 2013 Link to this post

    Hi Team

    I would like to get complete code for grouping multiple columns when user clicks on "checkbox", but not on "radgridview". I now how to add grouping descriptor dynamically. But when I select any single item(checkbox) for grouping, it works great. But if i am going to select more than one item together, I am getting an Error message as shown in "error" Picture. Also I want to enable or disable grouping through check box only, that is when user click on "checkbox" corresponding item will get grouped.
    Hope I will get solution soon....(VB.net code snippette)
        Dim STO_Group_One As New GroupDescriptor()
        Dim STO_Group_Two As New GroupDescriptor()
     
    Private Sub GridFilter_ProName_CBX_ToggleStateChanged(ByVal sender As System.Object, ByVal args As Telerik.WinControls.UI.StateChangedEventArgs) Handles GridFilter_ProName_CBX.ToggleStateChanged
     
            If GridFilter_ProName_CBX.Checked = True Then
                If Me.STO_ReportGrid.GroupDescriptors.Count = 0 And Me.STO_ReportGrid.GroupDescriptors.Expression.Contains("PRProName") = False Then
                    STO_Group_One.GroupNames.Add("PRProName", ListSortDirection.Ascending)
                    Me.STO_ReportGrid.GroupDescriptors.Insert(0, STO_Group_One)
                ElseIf Me.STO_ReportGrid.GroupDescriptors.Count = 1 And Me.STO_ReportGrid.GroupDescriptors.Expression.Contains("PRProName") = False Then
                    STO_Group_One.GroupNames.Add("PRProName", ListSortDirection.Ascending)
                    Me.STO_ReportGrid.GroupDescriptors.Insert(1, STO_Group_One)
                    Exit Sub
                End If
            Else
     
            End If
            If GridFilter_ProName_CBX.Checked = False Then
                If Me.STO_ReportGrid.GroupDescriptors.Expression.Contains("PRProName") = True Then
                    Me.STO_ReportGrid.GroupDescriptors.Remove(STO_Group_One)
                End If
            End If
     
        End Sub
     
     
     
        Private Sub GridFilter_ProCat_CBX_ToggleStateChanged(ByVal sender As System.Object, ByVal args As Telerik.WinControls.UI.StateChangedEventArgs) Handles GridFilter_ProCat_CBX.ToggleStateChanged
     
            If GridFilter_ProCat_CBX.Checked = True Then
                If Me.STO_ReportGrid.GroupDescriptors.Count = 0 And Me.STO_ReportGrid.GroupDescriptors.Expression.Contains("PRProCat") = False Then
                    STO_Group_Two.GroupNames.Add("PRProCat", ListSortDirection.Ascending)
                    Me.STO_ReportGrid.GroupDescriptors.Insert(0, STO_Group_Two)
                ElseIf Me.STO_ReportGrid.GroupDescriptors.Count = 1 And Me.STO_ReportGrid.GroupDescriptors.Expression.Contains("PRProCat") = False Then
                    STO_Group_Two.GroupNames.Add("PRProCat", ListSortDirection.Ascending)
                    Me.STO_ReportGrid.GroupDescriptors.Insert(1, STO_Group_Two)
                    Exit Sub
                End If
            End If
            If GridFilter_ProCat_CBX.Checked = False Then
                If Me.STO_ReportGrid.GroupDescriptors.Expression.Contains("PRProCat") = True Then
                    Me.STO_ReportGrid.GroupDescriptors.Remove(STO_Group_Two)
                End If
            End If
     
        End Sub
     
     
        Private Sub STO_ReportGrid_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles STO_ReportGrid.GroupByChanging
     
            On Error Resume Next
            If Me.STO_ReportGrid.GroupDescriptors.Expression.Contains("PRProName") = True Then
                Me.GridFilter_ProName_CBX.Checked = False
            ElseIf Me.STO_ReportGrid.GroupDescriptors.Expression.Contains("PRProCat") = True Then
                Me.GridFilter_ProCat_CBX.Checked = False
            End If
        End Sub
  25. Julian Benkov
    Admin
    Julian Benkov avatar
    1135 posts

    Posted 06 Mar 2013 Link to this post

    Hello Emix,

    You can add a second descriptor by using the 
    Add method of the GroupDescriptors in your scenario:
    If GridFilter_ProName_CBX.Checked = True Then
        If Me.STO_ReportGrid.GroupDescriptors.Count = 0 And Me.STO_ReportGrid.GroupDescriptors.Expression.Contains("PRProName") = False Then
            STO_Group_One.GroupNames.Add("PRProName", ListSortDirection.Ascending)
            Me.STO_ReportGrid.GroupDescriptors.Insert(0, STO_Group_One)
        ElseIf Me.STO_ReportGrid.GroupDescriptors.Count = 1 And Me.STO_ReportGrid.GroupDescriptors.Expression.Contains("PRProName") = False Then
            STO_Group_One.GroupNames.Add("PRProName", ListSortDirection.Ascending)
            Me.STO_ReportGrid.GroupDescriptors.Add(STO_Group_One)
            Exit Sub
        End If
    Else
     
    End If

    To remove close buttons from the GroupPanel you can process the GroupChanged event and collapse all RemoveButton instances:
    Private Sub gridView_GroupByChanged(sender As Object, e As GridViewCollectionChangedEventArgs)
        Dim templateGroupsElement As TemplateGroupsElement = Me.gridView.GridViewElement.FindDescendant(Of TemplateGroupsElement)()
        If templateGroupsElement IsNot Nothing Then
            For Each element As RadElement In templateGroupsElement.Children
                Dim groupElement As GroupElement = TryCast(element, GroupElement)
                If groupElement IsNot Nothing Then
                    For Each fieldElement As GroupFieldElement In groupElement.GroupingFieldElements
                        fieldElement.RemoveButton.Visibility = ElementVisibility.Collapsed
                    Next
                End If
            Next
        End If
    End Sub

    I hope this helps. Feel free to ask if you have any additional questions.

    Kind regards,
    Julian Benkov
    the Telerik team
    WinForms Q1 2013 boasts PivotGrid, PDF Viewer, Chart enhancements and more. Check out all of the latest highlights.
Back to Top
UI for WinForms is Visual Studio 2017 Ready