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

WPF DataGrid中如何在不新增行的前提下为默认新行填充数据

实现方案

核心逻辑说明

  • WPF DataGrid绑定DataTable时开启CanUserAddRows后,底部的默认空行是DataTable的临时新增对象(属于DataView.AddNew()生成的未提交行),直接修改该对象的字段值不会正式写入DataTable的Rows集合,完全满足你填充时不正式添加的需求
  • 需要先将绑定用的DataTable声明为全局字段,方便各个事件方法访问操作

完整修改代码

XAML部分

<Grid  Margin="59,59,89,0">
    <!-- 显式开启允许新增行,关闭自动生成列可自行控制列顺序 -->
    <DataGrid x:Name="dataGrid" Margin="10,33,10,37" 
              PreviewKeyDown="dataGrid_PreviewKeyDown"
              CanUserAddRows="True" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="No" Binding="{Binding No}"/>
            <DataGridTextColumn Header="Barcode" Binding="{Binding Barcode}"/>
            <DataGridTextColumn Header="Item" Binding="{Binding Item}" IsReadOnly="True"/>
            <DataGridTextColumn Header="Qty" Binding="{Binding Qty}"/>
            <DataGridTextColumn Header="Mrp" Binding="{Binding Mrp}" IsReadOnly="True"/>
            <DataGridTextColumn Header="Discount" Binding="{Binding Discount}" IsReadOnly="True"/>
            <DataGridTextColumn Header="Cgst" Binding="{Binding Cgst}" IsReadOnly="True"/>
            <DataGridTextColumn Header="Sgst" Binding="{Binding Sgst}" IsReadOnly="True"/>
            <DataGridTextColumn Header="Amount" Binding="{Binding Amount}" IsReadOnly="True"/>
            <DataGridTextColumn Header="Salesman" Binding="{Binding Salesman}" IsReadOnly="True"/>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

C#部分

public partial class MainWindow : Window
{
    // 声明全局DataTable,所有方法共享访问
    private DataTable _saleDt;
    public MainWindow()
    {
        InitializeComponent();           
    }

    void CreateDataTable()
    {
        _saleDt = new DataTable();
        DataColumn No = new DataColumn("No",typeof(double));
        DataColumn Barcode = new DataColumn("Barcode", typeof(string));
        DataColumn Item = new DataColumn("Item", typeof(string));
        DataColumn Qty = new DataColumn("Qty", typeof(double));
        DataColumn Mrp = new DataColumn("Mrp", typeof(double));
        DataColumn Discount = new DataColumn("Discount", typeof(double));
        DataColumn Cgst = new DataColumn("Cgst", typeof(double));
        DataColumn Sgst = new DataColumn("Sgst", typeof(double));
        DataColumn Amount = new DataColumn("Amount", typeof(double));
        DataColumn Salesman = new DataColumn("Salesman", typeof(string));

        _saleDt.Columns.Add(No);
        _saleDt.Columns.Add(Barcode);
        _saleDt.Columns.Add(Item);
        _saleDt.Columns.Add(Qty);
        _saleDt.Columns.Add(Mrp);
        _saleDt.Columns.Add(Discount);
        _saleDt.Columns.Add(Cgst);
        _saleDt.Columns.Add(Sgst);
        _saleDt.Columns.Add(Amount);
        _saleDt.Columns.Add(Salesman);
       
        dataGrid.ItemsSource = _saleDt.DefaultView;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        this.CreateDataTable();
    }
   
    private void dataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key != Key.Enter || dataGrid.CurrentCell.Column == null) 
            return;

        var currentColIndex = dataGrid.CurrentCell.Column.DisplayIndex;
        var currentRow = dataGrid.CurrentItem as DataRowView;
        if (currentRow == null) return;

        e.Handled = true;
        // 1. 当前在Barcode列(索引1),填充条码对应数据
        if (currentColIndex == 1)
        {
            FillBarcodeData(currentRow);
            // 跳转至Qty列(索引3)
            dataGrid.CurrentCell = new DataGridCellInfo(currentRow, dataGrid.Columns[3]);
            dataGrid.BeginEdit();
        }
        // 2. 当前在Qty列(索引3),提交行并生成新的空行
        else if (currentColIndex == 3)
        {
            // 结束编辑,提交当前行到DataTable
            dataGrid.CommitEdit();
            currentRow.EndEdit();
            // 自动生成新的空新增行,定位到新行的Barcode列
            var newRow = _saleDt.DefaultView.AddNew();
            dataGrid.ScrollIntoView(newRow);
            dataGrid.CurrentCell = new DataGridCellInfo(newRow, dataGrid.Columns[1]);
            dataGrid.BeginEdit();
        }
    }

    public void FillBarcodeData(DataRowView currentRow)
    {
        string barcode = currentRow["Barcode"]?.ToString();
        if (string.IsNullOrWhiteSpace(barcode)) return;

        // 这里替换为你实际拉取条码对应数据的逻辑
        // 示例模拟数据:
        currentRow["Item"] = "测试商品" + barcode;
        currentRow["Mrp"] = 100;
        currentRow["Discount"] = 10;
        currentRow["Cgst"] = 9;
        currentRow["Sgst"] = 9;
        currentRow["Amount"] = 90;
        currentRow["Salesman"] = "默认销售员";
    }
}

注意事项

  • 不需要新增行时手动操作DataTable的Rows.Add,编辑临时行并调用EndEdit后会自动加入Rows集合
  • 非新增行的编辑不会触发新增逻辑,如果需要限制仅底部空行触发该逻辑,可以加判断:if(dataGrid.Items.IndexOf(currentRow) == dataGrid.Items.Count -1) 确认是最后一行新增行再执行操作
  • 自动填充的列设置了IsReadOnly="True"避免用户手动修改,不需要可以删除该属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 12:54:00