0
votes

I've created a WPF application that includes a datagrid with one editable column. As the user enters values in it, then presses Return, the focus moves to the next row. All works great.

The customer has asked me to add support for the up and down cursor keys so that when a cell in the grid is in edit mode, pressing down gives the same results as pressing Return. Pressing up will be like Return, except that the selected row will become the one above the edited cell, rather than the one below.

I've looked for keypress events on the cell - no joy - and I've captured the keydown event on the datagrid itself but this didn't fire when I press a cursor key.

Can anyone suggest a solution please?

EDIT

Should have mentioned, I'm using an MVVM style context and binding to a filtered set of data in an ICollectionView.

2

2 Answers

2
votes

Use the DataGrid.PreviewKeyDown Event:

<DataGrid PreviewKeyDown="DataGrid_PreviewKeyDown"

with this event handler

private void DataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
    DataGrid grid = sender as DataGrid;
    ICollectionView view = CollectionViewSource.GetDefaultView(grid.ItemsSource);

    switch (e.Key)
    {
        case Key.Up:
            view.MoveCurrentToPrevious();
            e.Handled = true;
            break;
        case Key.Down:
            view.MoveCurrentToNext();
            e.Handled = true;
            break;
    }
}

and it should work.

0
votes

I gave +1 to LPL for his answer, even though it didn't work for me because (I think) of the use of a bound data context. However, LPL pointed me in the right direction.

In the end I used the following code, which works for my bound data. The user can filter the data and this still works. I also only move the selection when in edit mode, as up and down work perfectly when not in edit mode.

    private void OrderGrid_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        var viewModel = this.DataContext as IShopOrderingViewModel;
        var view = viewModel.FilteredOrderLines as IEditableCollectionView;
        if (view.IsEditingItem)
        {
            switch (e.Key)
            {
                case Key.Up:
                    if (OrderGrid.SelectedIndex > 0)
                    {
                        OrderGrid.SelectedIndex--;
                        e.Handled = true;
                    }
                    break;
                case Key.Down:
                    if (OrderGrid.SelectedIndex < (OrderGrid.Items.Count - 1))
                    {
                        OrderGrid.SelectedIndex++;
                        e.Handled = true;
                    }
                    break;
            }
        }