question

JunYoungLee-5266 avatar image
0 Votes"
JunYoungLee-5266 asked cooldadtx commented

I want to move cells with keyboard arrow keys while editing WPF datagrid.

I have created a datagrid in WPF. But I want to move with keyboard arrow left, right keys, but there is a problem.
For example I want to move right by pressing the right arrow key while editing a cell in row 1 column 1.
However, while the cell is being edited, the cell does not move in either direction. Is there a way to make the cell move in that direction when the keyboard arrow key is pressed while editing?

dotnet-csharpwindows-wpfdotnet-wpf-xaml
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

cooldadtx avatar image
0 Votes"
cooldadtx answered JunYoungLee-5266 commented

That's because when you're in edit mode the editing control is getting the keyboard input, not the grid. You need to move it out of edit mode.

Off the top of my head I'd say do the following. Handle the keyboard KeyUp event. When the desired key(s) are pressed then check to see if the cell is currently being edited using the IsEditing property. Depending upon your desired behavior either CancelEdit or CommitEdit to exit edit mode. Then give the corresponding cell focus.

This is predicated on the grid actually getting the keyboard event though. It is possible the edit control being used doesn't let it tunnel up. You also might need to handle the boundary cases like the user being on the first/last row/column, the cell being out of view, etc.

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you for your reply!!!
And I attach my code in comment.

0 Votes 0 ·
JunYoungLee-5266 avatar image
0 Votes"
JunYoungLee-5266 answered cooldadtx commented

Thank you cooldadtx.
Referring to your answer, I added a keyup handler to the datagrid to create a code that saves the text being edited and moves the cell when the arrow key is pressed while editing.
This may not be the best workaround, but it still works. I attached my code below.

         private void datagrid_eqp_KeyUp(object sender, KeyEventArgs e)
         {
             //key event
             DataGrid dg = sender as DataGrid;
             DataGridCellInfo cellinfo = dg.CurrentCell;
             DataGridCell cell = TryToFindGridCell(dg, cellinfo);
             var columnIndex = dg.Columns.IndexOf(dg.CurrentColumn);
             var rowIndex = dg.Items.IndexOf(dg.CurrentItem);
    
             if (cell.IsEditing == true && e.Key == Key.Right)
             {                     
                 //cancel edit, save current text, move cell
                 cell.Content = "dummy";         //when press arrow, "dummy" deleted and current text is saved
                 this.datagrid_eqp.CancelEdit();
                 try
                 {
                     this.datagrid_eqp.CurrentCell = new DataGridCellInfo(datagrid_eqp.Items[rowIndex], datagrid_eqp.Columns[columnIndex + 1]);
                 }
                 catch (System.ArgumentOutOfRangeException)
                 {
                     //last column exception
                     this.datagrid_eqp.CurrentCell = new DataGridCellInfo(datagrid_eqp.Items[rowIndex], datagrid_eqp.Columns[columnIndex]);
                 }
             }
             else if (cell.IsEditing == true && e.Key == Key.Left)
             {
                 //cancel edit, save current text, move cell
                 cell.Content = "dummy";
                 this.datagrid_eqp.CancelEdit();
                 try
                 {
                     this.datagrid_eqp.CurrentCell = new DataGridCellInfo(datagrid_eqp.Items[rowIndex], datagrid_eqp.Columns[columnIndex - 1]);
                 }
                 catch (System.ArgumentOutOfRangeException)
                 {
                     //first column exception
                     this.datagrid_eqp.CurrentCell = new DataGridCellInfo(datagrid_eqp.Items[rowIndex], datagrid_eqp.Columns[columnIndex]);
                 }
             }
             else if (cell.IsEditing == true && e.Key == Key.Up)
             {
                 //cancel edit, save current text, move cell
                 cell.Content = "dummy";
                 this.datagrid_eqp.CancelEdit();
                 try
                 {
                     this.datagrid_eqp.CurrentCell = new DataGridCellInfo(datagrid_eqp.Items[rowIndex - 1], datagrid_eqp.Columns[columnIndex]);
                 }
                 catch (System.ArgumentOutOfRangeException)
                 {
                     //first row exception
                     this.datagrid_eqp.CurrentCell = new DataGridCellInfo(datagrid_eqp.Items[rowIndex], datagrid_eqp.Columns[columnIndex]);
                 }
             }
             else if (cell.IsEditing == true && e.Key == Key.Down)
             {
                 //cancel edit, save current text, move cell
                 cell.Content = "dummy";
                 this.datagrid_eqp.CancelEdit();
                 try
                 {
                     this.datagrid_eqp.CurrentCell = new DataGridCellInfo(datagrid_eqp.Items[rowIndex + 1], datagrid_eqp.Columns[columnIndex]);
                 }
                 catch (System.ArgumentOutOfRangeException)
                 {
                     //last row exception
                     this.datagrid_eqp.CurrentCell = new DataGridCellInfo(datagrid_eqp.Items[rowIndex], datagrid_eqp.Columns[columnIndex]);
                 }
             }
    
         }
 
         static DataGridCell TryToFindGridCell(DataGrid grid, DataGridCellInfo cellInfo)
         {
             DataGridCell result = null;
             DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromItem(cellInfo.Item);
             if (row != null)
             {
                 int columnIndex = grid.Columns.IndexOf(cellInfo.Column);
                 if (columnIndex > -1)
                 {
                     DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);
                     result = presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex) as DataGridCell;
                 }
             }
             return result;
         }
    
         static T GetVisualChild<T>(Visual parent) where T : Visual
         {
             T child = default(T);
             int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
             for (int i = 0; i < numVisuals; i++)
             {
                 Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
                 child = v as T;
                 if (child == null)
                 {
                     child = GetVisualChild<T>(v);
                 }
                 if (child != null)
                 {
                     break;
                 }
             }
             return child;
         }
     }


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you for sharing your code so that others can use it if they have a similar need.

0 Votes 0 ·