Datagrid 将焦点设置在新添加的行上 [英] Datagrid Set focus on newly added row

查看:28
本文介绍了Datagrid 将焦点设置在新添加的行上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个绑定到可观察集合的数据网格.当用户按下添加按钮"时,它会添加一个新行,我通过向 observablecollection 添加一个新元素来实现这一点.

I have a datagrid bound to an observable collection. When the user press the "add button" it adds a new row and I do this by adding a new element to the observablecollection.

我不知道如何使新添加的行的第一个单元格成为焦点,就像我们在编辑一样.我使用的是 MVVM 模式.

I cannot figure out how to make the newly added row with the first cell in focus as if we were editing. I am using a MVVM pattern.

有什么想法或建议吗?

推荐答案

高斯给出的答案是正确的方法,但是加上一些代码,就更清楚了:

The answer given by Gauss is the right approach, but with some code, it is clearer:

void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
    e.Row.Loaded += Row_Loaded;
}

void Row_Loaded(object sender, RoutedEventArgs e)
{        
    var row = (DataGridRow) sender;
    row.Loaded -= Row_Loaded;
    DataGridCell cell = GetCell(dataGrid, row, 0);
    if (cell != null) cell.Focus();
    dataGrid.BeginEdit();        
}

static DataGridCell GetCell(DataGrid dataGrid, DataGridRow row, int column)
{
    if (dataGrid == null) throw new ArgumentNullException("dataGrid");
    if (row == null) throw new ArgumentNullException("row");
    if (column < 0) throw new ArgumentOutOfRangeException("column");

    DataGridCellsPresenter presenter = FindVisualChild<DataGridCellsPresenter>(row);
    if (presenter == null)
    {
        row.ApplyTemplate();
        presenter = FindVisualChild<DataGridCellsPresenter>(row);
    }
    if (presenter != null)
    {
        var cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
        if (cell == null)
        {
            dataGrid.ScrollIntoView(row, dataGrid.Columns[column]);
            cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
        }
        return cell;
    }
    return null;
}

static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
    {
        DependencyObject child = VisualTreeHelper.GetChild(obj, i);
        var visualChild = child as T;
        if (visualChild != null)
            return visualChild;
        var childOfChild = FindVisualChild<T>(child);
        if (childOfChild != null)
            return childOfChild;
    }
    return null;
}

您在 DataGrid.LoadingRow 事件中检索了行,但该单元格尚不可用.因此,您在 Loaded 事件上放置了一个处理程序,以等待此事件发生,然后您可以检索单元格并将焦点放在它上面.

You retrieve the row in the DataGrid.LoadingRow event, but the cell is not yet available. So you put an handler on the Loaded event in order to wait for this event to occur and then you can retrieve the cell and put the focus on it.

移除处理程序以避免新的触发.

The handler is removed to avoid a new triggering.

编辑会话也可以用 dataGrid.BeginEdit() 开始.

The editing session can also be started with dataGrid.BeginEdit().

所有这些都在代码隐藏中,因为它属于视图.

All of this is in the code-behind, because it belongs to the view.

这篇关于Datagrid 将焦点设置在新添加的行上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆