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
相关产品推荐
相关产品推荐

