代码之家  ›  专栏  ›  技术社区  ›  Kerwen

MVVM DataGrid如何在刷新内容后设置焦点

  •  0
  • Kerwen  · 技术社区  · 7 年前

    我有一个 DataGrid 如下所示:

    <DataGrid ItemsSource="{Binding GridSource}" CanUserAddRows="False"
              AutoGenerateColumns="False"
              SelectedItem="{Binding SelectedRow, Mode=TwoWay}">
    ...
    </DataGrid>
    

    我有个计时器 ViewModel 刷新的内容 数据网格 ,更新内容后,使用 SelectedRow 要重置当前行,请选择行。

    检查UI结果,所选行正常,但没有蓝色背景。我想我错过了设置焦点,但如何实现这一点?

    1 回复  |  直到 3 年前
        1
  •  2
  •   Toni rai nalasa    3 年前

    我想我错过了设置焦点,但如何实现这一点?

    以编程方式聚焦 DataGrid 要获得与使用鼠标单击行时完全相同的行为,需要付出一些努力。详情请参阅以下博文。

    How to programmatically select and focus a row or cell in a DataGrid in WPF

    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();
        /* 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();
        }
    }
    
    private 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;
    }
    
    private static T FindVisualChild<T>(DependencyObject obj)
        where T : DependencyObject
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(obj, i);
            if (child != null && child is T)
                return (T)child;
            else
            {
                T childOfChild = FindVisualChild<T>(child);
                if (childOfChild != null)
                    return childOfChild;
            }
        }
        return null;
    }