如何在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(); } } }
方案说明
BeginningEdit事件:负责完成文本预填充逻辑,此时单元格还是显示用的TextBlock,只能处理数据绑定的更新。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
相关产品推荐
相关产品推荐

