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

Selecting GridCells Programmatically

6 Answers 45 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Glenn
Top achievements
Rank 1
Glenn asked on 18 Feb 2015, 11:00 PM
Hi Telerik Folks,

We've overridden our "ProcessKey(KeyEventArgs keys) in a customized BaseGridBehavior class that we're using.  In doing this, the default keys for selecting a block of cells (Shift + the arrow keys) are no longer working.

To overcome this we're trying to put in custom code to explicitly do the same thing.  It looks like this...

01.    public class MyGridBehavior : BaseGridBehavior
02.    {
03. 
04. 
05.        public void SelectCellBlock(GridViewCellInfo SelectedCellTopLeft,GridViewCellInfo SelectedNewCell)
06.        {
07.            this.GridControl.ClearSelection();
08. 
09. 
10.            int TopRowIndex = SelectedCellTopLeft.RowInfo.Index <= SelectedNewCell.RowInfo.Index ? SelectedCellTopLeft.RowInfo.Index : SelectedNewCell.RowInfo.Index;
11.            int BottomRowIndex = SelectedCellTopLeft.RowInfo.Index >= SelectedNewCell.RowInfo.Index ? SelectedCellTopLeft.RowInfo.Index : SelectedNewCell.RowInfo.Index;
12. 
13.            int LeftColumnIndex = SelectedCellTopLeft.ColumnInfo.Index <= SelectedNewCell.ColumnInfo.Index ? SelectedCellTopLeft.ColumnInfo.Index : SelectedNewCell.ColumnInfo.Index;
14.            int RightColumnIndex = SelectedCellTopLeft.ColumnInfo.Index >= SelectedNewCell.ColumnInfo.Index ? SelectedCellTopLeft.ColumnInfo.Index : SelectedNewCell.ColumnInfo.Index;
15. 
16.            //this.GridControl.GridNavigator.BeginSelection(new GridNavigationContext() { InputType = InputType.Keyboard, ModifierKeys = Keys.Shift });
17. 
18.            for (int rowIndex = TopRowIndex; rowIndex <= BottomRowIndex; rowIndex++)
19.            {
20.                for (int columnIndex = LeftColumnIndex; columnIndex <= RightColumnIndex; columnIndex++)
21.                {
22.                    this.GridControl.Rows[rowIndex].Cells[columnIndex].IsSelected = true;
23.                }
24.            }
25.        }
26. 
27.        public override bool ProcessKey(KeyEventArgs keys)
28.        {
29. 
30.            if (keys.Shift && keys.KeyCode ==Keys.Down)
31.            {               
32.                GridViewCellInfo SelectedCellTopLeft = this.GridControl.SelectedCells.OrderBy(r => r.RowInfo.Index).ThenBy(c => c.ColumnInfo.Index).FirstOrDefault();
33.                this.GridControl.GridNavigator.SelectNextRow(1);
34.                GridViewCellInfo SelectedNewCell = this.GridControl.SelectedCells.OrderBy(r => r.RowInfo.Index).ThenBy(c => c.ColumnInfo.Index).FirstOrDefault();
35.                SelectCellBlock(SelectedCellTopLeft, SelectedNewCell);
36.                return false;
37.                     
38.            }
39. 
40.            if (keys.Shift && keys.KeyCode == Keys.Up)
41.            {
42.                GridViewCellInfo SelectedCellTopLeft = this.GridControl.SelectedCells.OrderBy(r => r.RowInfo.Index).ThenBy(c => c.ColumnInfo.Index).FirstOrDefault();
43.                this.GridControl.GridNavigator.SelectPreviousRow(1);
44.                GridViewCellInfo SelectedNewCell = this.GridControl.SelectedCells.OrderBy(r => r.RowInfo.Index).ThenBy(c => c.ColumnInfo.Index).FirstOrDefault();
45.                SelectCellBlock(SelectedCellTopLeft, SelectedNewCell);
46.                return false;
47. 
48.            }
49. 
50.            if (keys.Shift && keys.KeyCode == Keys.Left)
51.            {               
52.                GridViewCellInfo SelectedCellTopLeft = this.GridControl.SelectedCells.OrderBy(r => r.RowInfo.Index).ThenBy(c => c.ColumnInfo.Index).FirstOrDefault();
53.                this.GridControl.GridNavigator.SelectPreviousColumn();
54.                GridViewCellInfo SelectedNewCell = this.GridControl.SelectedCells.OrderBy(r => r.RowInfo.Index).ThenBy(c => c.ColumnInfo.Index).FirstOrDefault();
55.                SelectCellBlock(SelectedCellTopLeft, SelectedNewCell);
56.                return false;
57.            }
58. 
59.            if (keys.Shift && keys.KeyCode == Keys.Right)
60.            {
61.                GridViewCellInfo SelectedCellTopLeft = this.GridControl.SelectedCells.OrderBy(r => r.RowInfo.Index).ThenBy(c => c.ColumnInfo.Index).FirstOrDefault();
62.                this.GridControl.GridNavigator.SelectNextColumn();
63.                GridViewCellInfo SelectedNewCell = this.GridControl.SelectedCells.OrderBy(r => r.RowInfo.Index).ThenBy(c => c.ColumnInfo.Index).FirstOrDefault();
64.                SelectCellBlock(SelectedCellTopLeft, SelectedNewCell);
65.                return false ;
66.            }
67.      }
68.}


...It works, pretty much but it's performance gets exponentially slower the larger the block of cells that is selected holding down the Shift key.  It does this most likely because it loops through every cell and individually selects and flips the "IsSelected" property.

Is there a more efficient way to select blocks of cells, like using the GridNavigator.BeginSelection?  Is there a sample for using the GridNavigationContext parameter to do it this way given two cell addresses?

Are we going about this the wrong way?  Is there a more efficient way to make it opt out of our ProcessKey override and have it use the default behavior?

Thanks for any help you can provide...

6 Answers, 1 is accepted

Sort by
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 23 Feb 2015, 01:16 PM
Hello Glenn,

Thank you for writing.

I am not familiar with the complete scenario. However, note that grid selection is performed in the GridDataRowBehavior. When you replace the BaseGridBehavior with your custom implementation and override the ProcessKey method, you stop the basic logic for selection. Afterwards, you clear the entire selection and perform it again iterating through the cells. It is normal in this situation to experience some selection delay. Could you please give us  more detailed explanation about the exact functionality that you are trying to achieve and why it is necessary to clear the selection and perform it again with processing arrow keys?

By default, when arrow keys are used with Shift the SelectNextRow, SelectPreviousRow, SelectPreviousColumn, SelectNextColumn methods are wrapped around Navigator.BeginSelection ‚Äčand Navigator.EndSelection block. Here is a sample code snippet demonstrating how to keep the default selection logic without noticing any slow down execution. Feel free to extend it on a way to accomplish your requirement:
public Form1()
{
    InitializeComponent();
 
    this.radGridView1.MultiSelect = true;
    this.radGridView1.SelectionMode = Telerik.WinControls.UI.GridViewSelectionMode.CellSelect;
 
    //register the custom row  behavior
    BaseGridBehavior gridBehavior = radGridView1.GridBehavior as BaseGridBehavior;
    gridBehavior.UnregisterBehavior(typeof(GridViewDataRowInfo));
    gridBehavior.RegisterBehavior(typeof(GridViewDataRowInfo), new CustomGridDataRowBehavior());
}
 
public class CustomGridDataRowBehavior : GridDataRowBehavior
{
    public override bool ProcessKey(KeyEventArgs keys)
    {
        if (keys.Shift && keys.KeyCode == Keys.Down)
        {
            this.GridViewElement.Navigator.BeginSelection(this.GetKeyboardNavigationContext(keys));
            this.GridViewElement.Navigator.SelectNextRow(1);
            this.GridViewElement.Navigator.EndSelection();
            return true;
        }
 
        if (keys.Shift && keys.KeyCode == Keys.Up)
        {
            this.GridViewElement.Navigator.BeginSelection(this.GetKeyboardNavigationContext(keys));
            this.GridViewElement.Navigator.SelectPreviousRow(1);
            this.GridViewElement.Navigator.EndSelection();
            return true;
        }
 
        if (keys.Shift && keys.KeyCode == Keys.Left)
        {
            this.GridViewElement.Navigator.BeginSelection(this.GetKeyboardNavigationContext(keys));
            if (this.GridViewElement.RightToLeft)
            {
                if (!(this.GridViewElement.Navigator.IsLastRow(this.GridViewElement.CurrentRow) &&
                      this.GridViewElement.Navigator.IsLastColumn(this.GridViewElement.CurrentColumn)))
                {
                    this.GridViewElement.Navigator.SelectNextColumn();
                }
            }
            else
            {
                if (!(this.GridViewElement.Navigator.IsFirstRow(this.GridViewElement.CurrentRow) &&
                      this.GridViewElement.Navigator.IsFirstColumn(this.GridViewElement.CurrentColumn)))
                {
                    this.GridViewElement.Navigator.SelectPreviousColumn();
                }
            }
            this.GridViewElement.Navigator.EndSelection();
 
            return true;
        }
 
        if (keys.Shift && keys.KeyCode == Keys.Right)
        {
            this.GridViewElement.Navigator.BeginSelection(this.GetKeyboardNavigationContext(keys));
            if (this.GridViewElement.RightToLeft)
            {
                if (!(this.GridViewElement.Navigator.IsFirstRow(this.GridViewElement.CurrentRow) &&
                      this.GridViewElement.Navigator.IsFirstColumn(this.GridViewElement.CurrentColumn)))
                {
                    this.GridViewElement.Navigator.SelectPreviousColumn();
                }
            }
            else
            {
                if (!(this.GridViewElement.Navigator.IsLastRow(this.GridViewElement.CurrentRow) &&
                      this.GridViewElement.Navigator.IsLastColumn(this.GridViewElement.CurrentColumn)))
                {
                    this.GridViewElement.Navigator.SelectNextColumn();
                }
            }
 
            this.GridViewElement.Navigator.EndSelection();
            return true ;
        }
        return base.ProcessKey(keys);
    }
}

I hope this information helps. Should you have further questions, I would be glad to help.
 
Regards,
Dess
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Glenn
Top achievements
Rank 1
answered on 23 Feb 2015, 04:43 PM
Hello Dess, thanks very much for your reply.  

Your posted solution works great!  

It looks like we can get a lot better control Overriding the ProcessKey() on the GridDataRowBehavior class rather than the BaseGridBehavior class.  ...We migrated our custom Hot-Key code to the GridDataRowBehavior's ProcessKey() override and put it below the code you provided to preserve the default Selection behavior.  

Thanks very much for your help!


0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 26 Feb 2015, 09:54 AM
Hello Glenn,

Thank you for writing back.

I am glad the suggested approach suits your requirement. If you have any additional questions, please let me know.

Regards,
Dess
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Gone2TheDogs
Top achievements
Rank 1
Veteran
answered on 19 Feb 2018, 05:30 PM

The users for my Winform will be using Keyboard only. I have a read-only grid that needs to be traversed using the arrow keys. I'm using VB.Net and tried to convert the C# code listed as a solution in this thread. The code fails at line 5. (keys.KeyCode.Down). How is this piece translated in vb.net?

01.Public Class CustomGridDataRowBehavior
02.    Inherits GridDataRowBehavior
03.     
04.    Public Overrides function ProcessKey(keys As KeyEventArgs) as boolean  
05.        If keys.KeyCode = keys.KeyCode.Down Then
06.            Me.GridViewElement.Navigator.BeginSelection(Me.GetKeyboardNavigationContext(keys))
07.            Me.GridViewElement.Navigator.SelectNextRow(1)
08.            Me.GridViewElement.Navigator.EndSelection
09.            Return True
10.        End If
11.    End function
12. 
13. 
14. 
15. 
16.End Class

 

0
Gone2TheDogs
Top achievements
Rank 1
Veteran
answered on 19 Feb 2018, 05:58 PM

I am also getting an error on the following code in vb.net also:

Line 2 and 3. GridViewDataRowInfo is a class type

1.Dim gridBehavior As BaseGridBehavior = dgvAllPrintQueues.GridBehavior
2.gridBehavior.UnregisterBehavior(TypeOf (GridViewDataRowInfo))
3.gridBehavior.RegisterBehavior(TypeOf (GridViewDataRowInfo), New CustomGridDataRowBehavior())
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 20 Feb 2018, 09:49 AM
Hello, Bob, 

Thank you for writing.  

You can refer to the following help article demonstrating how to unregister and register a custom row behavior : https://docs.telerik.com/devtools/winforms/gridview/rows/row-behaviors

Feel free to use our online code converter to convert C# to VB and vice versa: http://converter.telerik.com/

I hope this information helps. Should you have further questions I would be glad to help. 
 
 Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
GridView
Asked by
Glenn
Top achievements
Rank 1
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Glenn
Top achievements
Rank 1
Gone2TheDogs
Top achievements
Rank 1
Veteran
Share this question
or