You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在DataGrid文本单元格编辑时自动填充并选中文本?

解决方案

你遇到的核心问题是BeginningEdit事件触发时机过早——此时DataGrid还未完成编辑控件(TextBox)的实例化,所以无法直接操作选中文本。可以通过监听PreparingCellForEdit事件结合原有填充逻辑来解决,这个事件会在编辑控件创建完成后触发,刚好适合执行文本选中操作。

修改后的完整Behavior代码

public class AutoFillBehavior : Behavior<DataGrid>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.BeginningEdit += OnBeginEdit;
        // 新增PreparingCellForEdit事件监听
        AssociatedObject.PreparingCellForEdit += OnPreparingCellForEdit;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.BeginningEdit -= OnBeginEdit;
        AssociatedObject.PreparingCellForEdit -= OnPreparingCellForEdit;
        base.OnDetaching();
    }

    private void OnBeginEdit(object sender, DataGridBeginningEditEventArgs e)
    {
        if (e.Column.Header.ToString() == "Name")
        {
            var grid = sender as DataGrid;
            var rowId = (grid.Columns[0].GetCellContent(e.Row) as TextBlock).Text;
            if (DLL.FieldNames.TryGetValue(rowId, out string name) && !string.IsNullOrWhitespace(name))
            {
                var rowData = grid.Items.OfType<IDataTable>().First(item => item.Id == rowId);
                rowData.Name = name;
            }
        }
    }

    // 新增处理文本选中的方法
    private void OnPreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
    {
        if (e.Column.Header.ToString() == "Name")
        {
            // 获取已创建的编辑TextBox并选中全部文本
            var textBox = e.EditingElement as TextBox;
            textBox?.SelectAll();
        }
    }
}

方案说明

  1. BeginningEdit事件:负责完成文本预填充逻辑,此时单元格还是显示用的TextBlock,只能处理数据绑定的更新。
  2. PreparingCellForEdit事件:DataGrid在创建好编辑控件(这里是TextBox)后会触发该事件,通过e.EditingElement可以直接获取到TextBox实例,调用SelectAll()即可选中全部文本。

备选方案(Dispatcher延迟执行)

如果不想新增事件监听,也可以在BeginningEdit的填充逻辑后,通过Dispatcher延迟执行选中操作,确保TextBox已生成:

private void OnBeginEdit(object sender, DataGridBeginningEditEventArgs e)
{
    if (e.Column.Header.ToString() == "Name")
    {
        var grid = sender as DataGrid;
        var rowId = (grid.Columns[0].GetCellContent(e.Row) as TextBlock).Text;
        if (DLL.FieldNames.TryGetValue(rowId, out string name) && !string.IsNullOrWhitespace(name))
        {
            var rowData = grid.Items.OfType<IDataTable>().First(item => item.Id == rowId);
            rowData.Name = name;

            // 延迟到UI渲染完成后执行选中操作
            Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() =>
            {
                var textBox = e.Column.GetCellContent(e.Row) as TextBox;
                textBox?.SelectAll();
            }));
        }
    }
}

不过第一种方案(监听PreparingCellForEdit)更可靠,因为它是DataGrid专门为编辑控件准备完成提供的事件,不会受UI渲染时机的影响。

内容的提问来源于stack exchange,提问作者Los2000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:50:38