将焦点设置在DataGrid内部

6

我有一个已经加载了一些数据的DataGrid。我需要将焦点设置在这个表格的第一行。

我将从一个按钮的onClick事件中调用这个方法。

myGrid.Focus()不能将焦点集中在表格内的行上。

4个回答

6
这是WPF中最困难的任务之一,原因在于虚拟化和UI渲染线程与运行我们代码的线程不同(您不能确定UI渲染何时完成)。 如果需要完整的参考,请查看此处: http://social.technet.microsoft.com/wiki/contents/articles/21202.wpf-programmatically-selecting-and-focusing-a-row-or-cell-in-a-datagrid.aspx 使用Dispatcher.Invoke可能适用于某些情况(相信我,在WPF中,Dispatcher.Invoke既是您最好的朋友,也是最大的敌人)。
dgGrid.ItemsSource = new List<object>() { new { I = 10, J = 20 }, new { I = 10, J = 20 }, new { I = 10, J = 20 }, new { I = 10, J = 20 }, new { I = 10, J = 20 } };
        Dispatcher.Invoke(new Action(delegate()
        {
            grd.SelectedIndex = 0;
            grd.Focus();
        }
    ), System.Windows.Threading.DispatcherPriority.Background);

或者从链接文章中选择最健壮的一个

public static DataGridCell GetCell(DataGrid dataGrid, DataGridRow rowContainer, int column)
{
    if (rowContainer != null)
    {
        DataGridCellsPresenter presenter = FindVisualChild<DataGridCellsPresenter>(rowContainer);
        if (presenter == null)
        {
            /* if the row has been virtualized away, call its ApplyTemplate() method
             * to build its visual tree in order for the DataGridCellsPresenter
             * and the DataGridCells to be created */
            rowContainer.ApplyTemplate();
            presenter = FindVisualChild<DataGridCellsPresenter>(rowContainer);
        }
        if (presenter != null)
        {
            DataGridCell cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
            if (cell == null)
            {
                /* bring the column into view
                 * in case it has been virtualized away */
                dataGrid.ScrollIntoView(rowContainer, dataGrid.Columns[column]);
                cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
            }
            return cell;
        }
    }
    return null;
}

  public 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();
        /* set the SelectedItem property */
        object item = dataGrid.Items[rowIndex]; // = Product X
        dataGrid.SelectedItem = item;

        DataGridRow row = dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
        if (row == null)
        {
            /* bring the data item (Product object) into view
             * in case it has been 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();
    }
 }

你需要添加这些静态方法来调用第二个方法,它首先尝试查找(或绘制)行,如果还没有绘制,则设置焦点在该行上。


1

试试这个:

if (e.Key == Key.Up || e.Key == Key.Down) 
{ 
    var uiElement = e.OriginalSource as UIElement; 
    dgvRoute.Focus(); //Datagrid 
    uiElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}

-2
mygrid.SelectedItem = mygrid.Items.Count > 0 ? mygrid.Items[0] : null;

在StackOverflow上,不欣赏单句回答。请查看帮助中心的如何撰写好的答案?页面获取更多信息。 - Sheridan

-3
如果您想将焦点放在网格的第一个值上,请尝试以下操作。
myGrid.SelectedIndex = 0;

这并不是关注于网格本身,实际上我们需要关注于单元格,就像上面的例子一样。 - Beetlejuice

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接