Expand / Colllapse Master / Parent / ChildGridViewTemplates Programmatically in RadGridView

23 posts, 1 answers
  1. Tom Chien
    Tom Chien avatar
    125 posts
    Member since:
    Jun 2009

    Posted 25 Sep 2009 Link to this post

    I'm trying to implement keyboard shortcuts for expanding and collapsing hierarchical templates via the Right and Left Arrow Keys like you can do in the Folders Pane of Windows Explorer or Outlook.  I started by inheriting the BaseGridBehavior and overriding the ProcessKey Function (like you guys had suggested for implementing Ctrl-Home/-End Keys for Top/Bottom of Grid).  The Right key works fine for Expanding a Row.  The Left key works fine for Collapsing a Row if its currently Expanded.  However, if the Current Row is not Expanded, the Left key doesn't seem to do anything.  If I set the CurrentRow.Parent.IsExpanded = False, it'll collapse the Current Template, but then it doesn't set the Current / Selected Row in the Parent Template (no Row is highlighted until I move up or down or click on a Row in the Parent Template) even if I set CurrentRow =  ParentRow, SelectedRows(0) = CurrentRow and SelectedRows(0).IsCurrent = True and call CurrentRow and SelectedRows(0)'s  InvalidateRow() and EnsureVisible() methods.  However, I'm not sure I want it to immediately collapse the Current Row's Template.  In Windows Explorer and Outlook, if the CurrentRow is not Expanded when you press Left Arrow, it simply moves the Current Row up to it's Group / Template's Parent Row.  Then you collapse that Parent Row normally when you press the Left Arrow again since it would be an Expanded Current Row at that point.

    Else ' -- Not Keys.Control, .Shift or .Alt  
     
        Select Case keys.KeyCode 
     
            Case Windows.Forms.Keys.Left 
     
                If Not .MasterGridViewTemplate.AllowEditRow Then 
                    ' -- If Only One Row Selected 
                    If .SelectedRows.Count = 1 Then 
                        ' -- If Selected Row is Expanded 
                        If .SelectedRows(0).IsExpanded Then 
                            .SelectedRows(0).IsExpanded = False 
                            Return True 
                        Else 
                            Dim oParentRow As GridViewDataRowInfo = .CurrentRow.ViewInfo.ParentRow 
                            If oParentRow IsNot Nothing Then 
                                .CurrentRow = oParentRow 
                                'oParentRow.IsExpanded = False 
                                .SelectedRows(0) = .CurrentRow 
                                .SelectedRows(0).IsCurrent = True 
                                .SelectedRows(0).InvalidateRow() 
                                .CurrentRow.InvalidateRow() 
                                .CurrentRow.EnsureVisible() 
                                .SelectedRows(0).EnsureVisible() 
                            End If 
                            Return True 
                        End If ' -- Else Not (Selected Row is Expanded) 
                    End If ' -- Only One Row Selected 
     
                    ' -- Don't allow Column selection on Master Template 
                    Return True 
                End If ' -- Not AllowEditRow 
     
                ' -- End Case Windows.Forms.Keys.Left 
     
            Case Windows.Forms.Keys.Right 
     
                    If Not .MasterGridViewTemplate.AllowEditRow Then 
                        If .SelectedRows.Count = 1 Then 
                            .SelectedRows(0).IsExpanded = True 
                        End If 
                        Return True 
                    End If ' -- Not AllowEditRow 
     
                    ' -- End Case Windows.Forms.Keys.Left 
     
        End Select ' -- keys.KeyCode 
     
    End If ' -- Else Not Keys.Control, .Shift or .Alt  
     

  2. Answer
    Jack
    Admin
    Jack avatar
    2335 posts

    Posted 29 Sep 2009 Link to this post

    Hello Tom Chien,

    You can use GridNavigator in this case. You should call its SelectPreviousRow method. Here is a sample:

    Me.radGridView1.GridNavigator.SelectPreviousRow(1, FalseFalse

    Please tell whether this helps. If not, send me your application and I will try to find a proper solution. I am looking forward to your reply.

    Greetings,
    Jack
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Tom Chien
    Tom Chien avatar
    125 posts
    Member since:
    Jun 2009

    Posted 29 Sep 2009 Link to this post

    That worked great!  Thanks!

    Now, on a semi-related Note, how do I the same thing with Groups (or should I create a new Forum Post)?
  5. Tom Chien
    Tom Chien avatar
    125 posts
    Member since:
    Jun 2009

    Posted 29 Sep 2009 Link to this post

    Actually, your solution needed a little adjustment.  When the CurrentRow is not the first Row in a ChildTemplate, your solution has it moving up to the previous Row in that Template, whereas Explorer and Outlook would move it to that Template's ParentRow.  The following is how I got it to work:

    Dim iCurrRowIdx As Integer = .CurrentRow.ViewInfo.CurrentIndex 
    .GridNavigator.SelectPreviousRow(1 + (iCurrRowIdx - 0), False, False) 

    I still have the question from my previous post about doing this with Groups vs. Templates.
  6. Jack
    Admin
    Jack avatar
    2335 posts

    Posted 30 Sep 2009 Link to this post

    Hi Tom,

    Yes, I missed that case. I am glad to hear that you have found a solution. However, I am not sure that I understand your question. SelectPreviousRow method should work also for a group row and you can use GridViewDataRowInfo.ParentRow property to get the group that owns the specific row. If this doesn't help, please describe your issue in detail and I will be glad to help further. I am looking forward to your reply.

    Kind regards,
    Jack
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  7. Tom Chien
    Tom Chien avatar
    125 posts
    Member since:
    Jun 2009

    Posted 02 Oct 2009 Link to this post

    I just noticed your reply. 

    1. I'm not sure how to use GridViewDataRowInfo.  I tried referencing .CurrentRow.ViewInfo.ParentRow but it's Nothing.

    2. Anyhoo, I got it to work with Groups also.  My code was checking for .SelectedRows.Count > 1 (to avoid expanding / collapsing when multiple Rows are selected), however when I'm on a Group Header Row .SelectedRows.Count = 0.  Here's the updated code snippet that works with Groups and Templates:

        Public Class MyRadGridBehavior 
            Inherits BaseGridBehavior 
     
            Public Overloads Overrides Function ProcessKey(ByVal keys As KeyEventArgs) As Boolean 
     
                With Me.GridControl 
     
    ... 
     
                    Else ' -- Not Keys.Control, .Shift or .Alt  
     
                        Select Case keys.KeyCode 
     
                            Case Windows.Forms.Keys.Left 
     
                                ' -- If Root Template Does NOT Allow Editing,  
                                If Not .MasterGridViewTemplate.AllowEditRow Then 
     
                                    ' -- If Not Mulitple Rows Selected (<vs. = cause if on Group Header Row, no SelectedRows) 
                                    If .SelectedRows.Count <= 1 Then 
                                        ' -- If Current Row Exists (i.e. not in an empty Template) 
                                        If .CurrentRow IsNot Nothing Then 
                                            ' -- If Current Row is Expanded 
                                            If .CurrentRow.IsExpanded Then 
                                                .CurrentRow.IsExpanded = False 
                                            Else 
                                                Dim iCurrRowIdx As Integer = .CurrentRow.ViewInfo.CurrentIndex 
                                                .GridNavigator.SelectPreviousRow(1 + (iCurrRowIdx - 0), False, False) 
                                            End If ' -- Else Not (Selected Row is Expanded) 
                                            Return True 
                                        End If ' -- Current Row Exists (i.e. not in an empty Template) 
                                    End If ' -- Not Mulitple Rows Selected 
     
                                    ' -- Don't allow Column selection on Master Template 
                                    Return True 
                                End If ' -- Root Template Does NOT Allow Editing 
     
                                ' -- End Case Windows.Forms.Keys.Left 
     
                            Case Windows.Forms.Keys.Right 
     
                                ' -- If Root Template Does NOT Allow Editing,  
                                If Not .MasterGridViewTemplate.AllowEditRow Then 
     
                                    ' -- If Not Mulitple Rows Selected (<vs. = cause if on Group Header Row, no SelectedRows) 
                                    If .SelectedRows.Count <= 1 Then 
                                        ' -- If Current Row Exists (i.e. not in an empty Template) 
                                        If .CurrentRow IsNot Nothing Then 
                                            .CurrentRow.IsExpanded = True 
                                        End If 
                                    End If ' -- Not Mulitple Rows Selected
     
                                    ' -- Don't allow Column selection on Master Template 
                                    Return True 
                                End If ' -- Root Template Does NOT Allow Editing 
     
                                ' -- End Case Windows.Forms.Keys.Left 
     
                        End Select ' -- keys.KeyCode 
     
                    End If ' -- Else Not Keys.Control, .Shift or .Alt  
     
                End With ' -- Me.GridControl 
     
                Return MyBase.ProcessKey(keys) 
            End Function 
        End Class 
     
    ... 
     
    .GridBehavior = New MyRadGridBehavior 

    3. Since this implements a pretty common feature of tree- / hierarchical- lists and I don't see the solution anywhere in the docs, forums, etc., could I please get some posting this solution.
  8. Jack
    Admin
    Jack avatar
    2335 posts

    Posted 07 Oct 2009 Link to this post

    Hi Tom Chien,

    Regarding your questions:

    1. You should cast CurrentRow to GridViewDataRowInfo which contains the ParentRow property. This property contains the DataGroup which owns the row. GridViewInfo.ParentRow is not nothing when the row is a part of a child view.

    2. Please, could you confirm that the issue is now resolved or you need further assistance with this?

    3. I am not sure that I understand your question correctly. Please, could you be more specific? I added the question as a feature request and we will consider it when planning our upcoming releases.

    If there is something more that I can do, I will be glad to assist you.

    All the best,
    Jack
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  9. Tom Chien
    Tom Chien avatar
    125 posts
    Member since:
    Jun 2009

    Posted 13 Oct 2009 Link to this post

    Sorry, I was out of the office for a few days.

    1. I can no longer reproduce getting Nothing for the CurrentRow.ViewInfo.ParentRow Property.

    2. Yes, it's resolved after my additional adjustments to your initial solution.

    3. I meant to say: "Since this is a non-trivial implementation of a pretty common feature of tree- / hierarchical- lists and I don't see the solution anywhere else in the docs, forums, etc., could I please get some points for posting this solution?"

    Thanks
  10. Jack
    Admin
    Jack avatar
    2335 posts

    Posted 15 Oct 2009 Link to this post

    Hi Tom,

    Yes, we give points when our customers implement custom scenarios and publish them. However, you have to make a demonstration project and write a short description. This way our customers could easily use the solution. Also you should upload the project as a CodeLibrary. We will give you points after that.

    I am looking forward to your reply.

    Greetings,
    Jack
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  11. Tom Chien
    Tom Chien avatar
    125 posts
    Member since:
    Jun 2009

    Posted 15 Oct 2009 Link to this post

    WhaaaTTTT?

    Ok, I understand that Telerik gives points when "customers implement custom scenarios and publish them" and that my solution does not meet the submission requirements.

    However:

    a. That discourages users from taking the extra time to post easier - to - comprehend code of their solutions in forums when they could've simply posted a more difficult - to - understand summary description.  If a users feel the need to post a code solution in the forum, then not only did Telerik probably not solve the issue they were posting about, it was probably not posted elsewhere (even in the same forum thread) by users or Telerik staff at least not in a form that solved the issue to the extent that user's posting does, so they're doing Telerik and its users a favor by doing so.

    b. I had a previous post where I simply inquired about how to turn on or implement some other navigation shortcut keys (namely Ctrl -Page Up / -Page Down for top / bottom of grid) and you yourself gave me points simply for making the "suggestion" that Telerik adds those keys as features.  In that case, I didn't even post any code, much less "publish" them.  You posted all the code.  So, could I please points for making the "suggestion" that Telerik add shortcut keys to expand / collapse Rows and move to the Parent Row?

    Thanks. ;)
  12. Tom Chien
    Tom Chien avatar
    125 posts
    Member since:
    Jun 2009

    Posted 19 Oct 2009 Link to this post

    I just installed Telerik 2009Q3 Beta (2009.2.9.1016) over 2009Q2 (2009.2.9.729) and my Left Key to go to Group / Temlate's Parent Row when pressed on a Collapsed Row stopped working using the solution I described above and the only RadGridView change mentioned was combined Vertical Scroll Bar for Grids with ChildTemplateView's.  It appears instead of returning the Index relative to the 1st Row in the Current Group / ChildTemplateView, Me.GridControl.CurrentRow.ViewInfo.CurrentIndex is returning 0.

    Telerik 2009Q3 Beta (2009.2.9.1016), VS 2005 (v8.0.50727.762 SP.050727-7600), XP SP3 on Core2Duo 2.99GHZ with 3GB.
  13. Nikolay
    Admin
    Nikolay avatar
    1803 posts

    Posted 20 Oct 2009 Link to this post

    Hi Tom Chien,

    Thank you for getting back to us.

    Maybe, my colleague Jack did not express himself correctly. Of course we will give you Telerik points for posting your solution in the code snippet in this forum thread. We encourage our users to give their solutions to an issue or an implementation of a feature that will be useful for the community.

    However, we believe that it is much more convenient for the community to download a ready-to-run project if the implementation of the feature concerns a bigger code snippet. This will allow the users that run the project to decide easily if the implemented feature can suit their needs. In addition if some changes have to be made, it is easier to debug a runnable sample project than to look at the code snippet. Not to mention that the Code Library section is indented for ready solutions with descriptions, so when the user browse this section, he knows that he will find a solution behind the title of the article. Browsing a forum for a solution is harder, especially if the response containing the solution is not marked as an answer.

    Because of the reasons above, we evaluate the code library projects with a bigger amount of points as you can see here. I have updated your Telerik points for posting the final snippet in this forum thread, and for the feature request. In case you decide to create a Code library project, we will be happy to add additional 1000 points to your account.

    Thank you for your community effort. We  will investigate your newest report shortly

    Regards,
    Nikolay
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  14. Jack
    Admin
    Jack avatar
    2335 posts

    Posted 20 Oct 2009 Link to this post

    Hi Tom Chien,

    I would appreciate it if you open a new support ticket and send us your project. This will allow us to test all cases and make sure that the solution will work with our upcoming release.

    I am looking forward to your reply.

    Greetings,
    Jack
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  15. Tom Chien
    Tom Chien avatar
    125 posts
    Member since:
    Jun 2009

    Posted 04 Nov 2009 Link to this post

    1. Thank you for the points.  My point exactly.  Better to have a Big Carrot vs. Little Carrot policy instead of Big Carrot vs. No Carrot.  I agree.  It's obviously more, if not much more useful to publish, but posting snippets inside a Forum thread is also signifcantly more useful than not posting snippets at all.

    2. The "whole" project?  My SQL Server DB too?  If not, it's a major undertaking for me to extract it out to a separate test app that compiles and runs and has data that hopefully will still reproduce the error.

    For now, could you please just check to see if the RadGridView.CurrentRow.ViewInfo.CurrentIndex is still working.  It used to return a 0-based index of the CurrentRow relative to the 1st Visible Row of whatever MasterGridView or ChildGridView the CurrentRow is in.  Now it's always returning 0.  This is the only issue that's causing the workaround to no longer work completely in Q3 2009 Beta.

    For example, place the following Statement inside the RadGridView's KeyDown Event for some unused Key and see what you get: "MsgBox("CurrentRowIdx=" & rgrdProdsProjs.CurrentRow.ViewInfo.CurrentIndex)".
  16. Tom Chien
    Tom Chien avatar
    125 posts
    Member since:
    Jun 2009

    Posted 05 Nov 2009 Link to this post

    I've verified that RadGridView.CurrentRow.ViewInfo.CurrentIndex is always returning 0 (vs. 0-based index of the CurrentRow relative to the 1st Row of the Expanded portion of the ChildGridViewTemplate of the CurrentRow that it was returning in Q2 2009) in the final release of Q3 2009.

    Telerik WinForms 2009Q3 (2009.3.9.1103), VB, VS 2005 (v8.0.50727.762 SP.050727-7600), .Net 2.0 (2.0.50727), XP SP3, 3GB, 2.99GHZ, Core2Duo.



  17. Vassil Petev
    Admin
    Vassil Petev avatar
    1765 posts

    Posted 06 Nov 2009 Link to this post

    Hello Tom,

    Regarding your questions:

    1. Yes, I confirm the issue with the CurrentIndex property. It is logged and we will address it in our upcoming service pack. You can use the IndexOf method of the GridViewTemplate.Rows collection instead:

    Dim index As Integer = Me.radGridView1.MasterGridViewTemplate.Rows.IndexOf(myRow)

    1. Yes,  posting code snippets is useful when they represent simple and common scenarios which could be used by most of our customers. However, when the complexity raises we encourage posting the solution (compiled stand-alone project with [dummy] data) in the code library.

    2. Actually we don't need the database. We can use a sample data. However, with a working application it will be easier and faster to pinpoint and resolve the issue. We believe that this is more convenient both for us and for our customers.


    Greetings,
    Vassil
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  18. Tom Chien
    Tom Chien avatar
    125 posts
    Member since:
    Jun 2009

    Posted 06 Nov 2009 Link to this post

    I tried "Dim iCurrRowIdx As Integer = .MasterGridViewTemplate.Rows.IndexOf(.CurrentRow)" and "Dim iCurrRowIdx As Integer = .MasterGridViewTemplate.Rows.IndexOf(DirectCast(.CurrentRow, Telerik.WinControls.UI.GridViewDataRowInfo))".  I was surprised the first one did, but they both compile and both always return -1.
  19. Jack
    Admin
    Jack avatar
    2335 posts

    Posted 09 Nov 2009 Link to this post

    Hello Tom Chien,

    MasterGridViewTemplate is responsive for the first level in RadGridView when using hierarchy. If the CurrentRow is part of a child view, you should use the corresponding child view template to get the row index. For example:

    RadGridView1.CurrentRow.ViewTemplate.Rows.IndexOf(RadGridView1.CurrentRow)

    I hope this helps.

    All the best,
    Jack
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  20. Tom Chien
    Tom Chien avatar
    125 posts
    Member since:
    Jun 2009

    Posted 09 Nov 2009 Link to this post

    ".CurrentRow.ViewTemplate.Rows.IndexOf(.CurrentRow)" returns the index of the CurrentRow relative to the 1st Row of the ChildGridViewTemplate that the CurrentRow is in which is probably exactly what it was designed to do and I'm sure has its uses.  However, what I need is something that returns the index of the CurrentRow relative to the 1st Child Row of the Parent of the CurrentRow which is what ".CurrentRow.ViewInfo.CurrentIndex" did in Q2 2009 and you confirmed (in your Nov. 6 post) is no longer working.

    In the example below, I have a MasterGridViewTemplate with 4 Rows and a ChildGridViewTemplate 7 Rows.  The CurrentRow is on 3rd Child Row of the 2nd MasterGridViewTemplate Row.  I need a 0-based ondex to return 2.  ".CurrentRow.ViewTemplate.Rows.IndexOf(.CurrentRow)" is returning 4 (0-based). 

    Thanks for trying, but I don't think you'll be able to reproduce what ".CurrentRow.ViewInfo.CurrentIndex" did (and is supposed to do) without using some kind of loop.

    Viewable RadGridView
    Hiercharchy Level # (, ChildGridViewTemplate Row #)
    -1
     1.1.1, 7
     1.1.2, 2
    -2
     2.1.1, 6
     2.1.1, 3
     2.1.2, 5 <--- CurrentRow.
    -3
     3.1.1, 1
    -4
     4.1.1, 4

    MasterGridViewTemplate Rows
    1
    2
    3
    4

    MasterGridViewTemplate.ChildGridViewTemplates(0) Rows
    Index, Relation to MasterGridViewTemplate
    1, 3
    2, 1
    3, 2
    4, 4
    5, 2
    6, 2
    7, 1

  21. Jack
    Admin
    Jack avatar
    2335 posts

    Posted 12 Nov 2009 Link to this post

    Hello Tom Chien,

    The following method returns the row index relative to the current child view:

    Private Function GetCurrentIndex(ByVal rowInfo As GridViewRowInfo) As Integer
        Dim dataGroup As DataGroup = rowInfo.ViewInfo.RootGroup
        Dim traverser As New GridTraverser(dataGroup)
        Dim index As Integer = 0
        While traverser.MoveNext()
            If traverser.Current = rowInfo Then
                Return index
            End If
            index = index + 1
        End While
        Return -1
    End Function

    Please tell me whether it helps. I will be glad to assist you further.

    All the best,
    Jack
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  22. Tom Chien
    Tom Chien avatar
    125 posts
    Member since:
    Jun 2009

    Posted 18 Nov 2009 Link to this post

    Thanks, that workaround worked.  I look forward to the fix in Q3 2009 SP1 you promised in your Nov. 6 post.
  23. Tom Chien
    Tom Chien avatar
    125 posts
    Member since:
    Jun 2009

    Posted 18 Nov 2009 Link to this post

    I had to add "index -= rowInfo.ViewTemplate.SummaryRowsTop.Count" between "If traverser.Current Is rowInfo Then" and "Return index".

  24. Jack
    Admin
    Jack avatar
    2335 posts

    Posted 19 Nov 2009 Link to this post

    Hello Tom Chien, thank you for sharing your solution. We will take this info into account when addressing the issue.
     

    Kind regards,
    Jack
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Back to Top
UI for WinForms is Visual Studio 2017 Ready