简体   繁体   中英

Select first item (in list) in a DataGrid on Key.Down event

I'm trying to select first row in my Datagrid, when users press Arrow key down that is Key.Down event.

It works right now but somehow it's selecting second row even if I pass an index [0]...

I've created method SelectRowByIndex which should select a first row of my Datagrid and it looks like this:

private static void SelectRowByIndex(DataGrid dataGrid, int rowIndex)
        {
            if (!dataGrid.SelectionUnit.Equals(DataGridSelectionUnit.FullRow))
                throw new ArgumentException("The SelectionUnit of the DataGrid must be set to FullRow.");

            if (rowIndex < 0 || rowIndex > (dataGrid.Items.Count - 1))
                throw new ArgumentException(string.Format("{0} is an invalid row index.", rowIndex));

            dataGrid.SelectedItems.Clear();
            object item = dataGrid.Items[rowIndex];
            dataGrid.SelectedItem = item;

            DataGridRow row = dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
            if (row == null)
            {
                //Moram dodati BillItemTemp u slučaju da je virtualized away
                dataGrid.ScrollIntoView(item);
                row = dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
            }
            if (row != null)
            {
                DataGridCell cell = GetCell(dataGrid, row, 0);
                if (cell != null)
                    cell.Focus();
            }
        }

 private static DataGridCell GetCell(DataGrid dataGrid, DataGridRow rowContainer, int column)
        {
            if (rowContainer != null)
            {
                System.Windows.Controls.Primitives.DataGridCellsPresenter presenter
                    = FindVisualChild<System.Windows.Controls.Primitives.DataGridCellsPresenter>(rowContainer);
                if (presenter == null)
                {

                    rowContainer.ApplyTemplate();
                    presenter = FindVisualChild<System.Windows.Controls.Primitives.DataGridCellsPresenter>(rowContainer);
                }
                if (presenter != null)
                {
                    DataGridCell cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
                    if (cell == null)
                    {

                        dataGrid.ScrollIntoView(rowContainer, dataGrid.Columns[column]);
                        cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
                    }
                    return cell;
                }
            }
            return null;
        }

And after that I've called it in my constructor when form is loaded:

 this.PreviewKeyDown += (s, e) =>
 {
        if (e.Key == Key.Down && dtgProducts.HasItems)
          SelectRowByIndex(dtgProducts, 0);
 };

But somehow it's selecting second row? and not first one ... how come?

And I need to be secured when I keep pressing Key.Down not to select same row all the time..

You've made a really bad choice, assuming you mean with down arrow key. Take any datagrid.
Click a row.
Press the down arrow.
Focus moves to the next row.

You're fighting WPF. You won't win. WPF doesn't like it when you do stuff this way. It usually wants you to use databinding.

You could do this with viewmodels and databinding (I can append the previous version of this answer if you're interested) but it's not even that hard.

private static void SelectRowByIndex(DataGrid dataGrid, int rowIndex)
{
    //  Or set this in XAML better yet
    dataGrid.IsSynchronizedWithCurrentItem = true;

    var view = CollectionViewSource.GetDefaultView(dataGrid.ItemsSource);

    view.MoveCurrentToPosition(rowIndex);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM