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

如何让绑定DataTable的DataGrid空行首单元格显示闪烁光标及回车定位

解决方案:DataGrid空行光标闪烁与回车新增行自动聚焦

针对你提出的两个需求,我会一步步给出具体的实现方案,完美适配你当前的DataTable绑定场景:

1. 让默认空行的第一个单元格显示闪烁光标

默认情况下,WPF DataGrid不会自动聚焦到CanUserAddRows=true生成的空行,我们可以在DataGrid加载完成后,主动定位并聚焦这个空行的第一个单元格。

修改View.xaml

先给DataGrid添加Loaded事件,并确保单元格处于可编辑状态:

<DataGrid x:Name="MyGrid" 
          ItemsSource="{Binding MyDataTable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
          VerticalAlignment="Top" Height="400" Width="Auto" 
          SelectionMode="Single" AutoGenerateColumns="True" 
          GridLinesVisibility="Vertical" Background="Transparent" 
          CanUserResizeColumns="True" CanUserReorderColumns="False" 
          CanUserResizeRows="False" BorderThickness="0" 
          CanUserAddRows="True" RowHeaderWidth="0"
          Loaded="MyGrid_Loaded"
          IsReadOnly="False"> <!-- 必须开启可编辑才能聚焦输入 -->
</DataGrid>

实现后台加载事件(View.xaml.cs)

在DataGrid加载完成后,找到空行并强制聚焦第一个单元格:

private void MyGrid_Loaded(object sender, RoutedEventArgs e)
{
    // 获取DataGrid自动生成的空行(Items集合最后一项)
    var newItemRow = MyGrid.ItemContainerGenerator.ContainerFromItem(MyGrid.Items[MyGrid.Items.Count - 1]) as DataGridRow;
    if (newItemRow != null)
    {
        // 选中该行并聚焦
        MyGrid.SelectedItem = MyGrid.Items[MyGrid.Items.Count - 1];
        newItemRow.Focus();
        // 获取第一个单元格的输入控件并聚焦,进入编辑状态
        var firstCell = MyGrid.Columns[0].GetCellContent(newItemRow) as TextBox;
        if (firstCell != null)
        {
            firstCell.Focus();
            firstCell.SelectAll(); // 可选:选中单元格内容,方便直接覆盖输入
        }
    }
}

2. 回车键新增空行并自动聚焦第一个单元格

接下来处理回车键事件,当用户在当前编辑单元格按回车时,自动添加新行并直接聚焦新行的第一个单元格。

修改View.xaml添加PreviewKeyDown事件

<DataGrid x:Name="MyGrid" 
          <!-- 保留原有所有属性 -->
          PreviewKeyDown="MyGrid_PreviewKeyDown">
</DataGrid>

实现PreviewKeyDown事件处理(View.xaml.cs)

private void MyGrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter)
    {
        // 阻止默认回车行为(避免在单元格内换行)
        e.Handled = true;

        // 获取绑定的DataTable
        var dataTable = (DataTable)MyGrid.ItemsSource;
        if (dataTable != null)
        {
            // 向DataTable添加新空行
            var newRow = dataTable.NewRow();
            dataTable.Rows.Add(newRow);

            // 等待UI渲染完成后再聚焦新行(必须用Dispatcher延迟执行)
            Dispatcher.BeginInvoke(new Action(() =>
            {
                var newItemRow = MyGrid.ItemContainerGenerator.ContainerFromItem(MyGrid.Items[MyGrid.Items.Count - 1]) as DataGridRow;
                if (newItemRow != null)
                {
                    MyGrid.SelectedItem = MyGrid.Items[MyGrid.Items.Count - 1];
                    newItemRow.Focus();
                    var firstCell = MyGrid.Columns[0].GetCellContent(newItemRow) as TextBox;
                    if (firstCell != null)
                    {
                        firstCell.Focus();
                        firstCell.SelectAll();
                    }
                }
            }), System.Windows.Threading.DispatcherPriority.Render);
        }
    }
}

注意事项

  • 确保你的DataTable至少定义了一列,否则自动生成列后没有可聚焦的单元格
  • 如果DataTable存在必填列,需要在newRow创建后设置默认值,避免因数据验证失败导致无法添加行
  • 上述代码默认第一个列是TextBox类型,如果是ComboBox等其他控件,需要调整GetCellContent后的类型转换逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:32:01