0

我在 datagrid 中默认有一个新的空行(充当页脚行)。我想输入页脚行的条形码,然后按回车。然后它会获取一些值并应该填充剩余的单元格 item 、 mrp 、 cgst 、 sgst 、 discount 、 amount 、 salesman (数量除外)。填充字段后,焦点应转到数量单元格。输入数量并按回车,然后此页脚行应添加到数据网格中,并应创建另一个新的空页脚行,重点放在条形码上。这就是我想做的

现在我卡住了,因为我不知道如何用值填充新行(不将该行添加到数据网格)..

XAML

<Grid  Margin="59,59,89,0">
    <DataGrid x:Name="dataGrid" Margin="10,33,10,37" PreviewKeyDown="dataGrid_PreviewKeyDown" />

</Grid>

C#

public partial class MainWindow : Window
{
   
    public MainWindow()
    {
        InitializeComponent();           
    }

    void CreateDataTable()
    {
        DataTable dt = 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));

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

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        this.CreateDataTable();
    }
   
    private void dataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        var currentRowIndex = dataGrid.Items.IndexOf(dataGrid.CurrentItem);

        // move focus to next field

        var uiElement = e.OriginalSource as UIElement;
        if (e.Key == Key.Enter && uiElement != null)
        {
            e.Handled = true;
            FillBarcodeData(currentRowIndex);
            dataGrid.CurrentCell = new DataGridCellInfo(dataGrid.Items[currentRowIndex], dataGrid.Columns[3]);
            dataGrid.BeginEdit();
        }
    }

    public void FillBarcodeData(int currentRowIndex)
    {
        DataTable dt = new DataTable();                     
    }
4

1 回答 1

0

如果在 Debug 中启动应用程序后查看 DataGrid 的可视化树,您将看到最后(空)行的 DataContext 不是集合中的项目,而是静态属性 NewItemPlaceholder的值。

出于这个原因,这一行的单元格不包含一些空数据(可以用您的数据替换),而实际上只包含单元格的边框。由于没有该线所代表的元素,因此不可能改变这个不存在的元素的数据。

但是当您开始编辑此行时可以完成。此时,依次创建了两个事件。

  1. 添加新项目- 在其中您可以自己创建所需的项目。如果返回 null,则默认由 DataGrid 构造函数创建。
  2. InitializingNewItem - 您可以在其中获取已创建的项目并更改其属性。

例子:

using System.Collections.ObjectModel;

namespace NewRowDataTable
{
    public class RowData
    {
        public int Number { get; set; }
        public string Text { get; set; }
    }

    public class RowsViewModel
    {
        public ObservableCollection<RowData> Rows { get; }
            = new ObservableCollection<RowData>()
            {
                new RowData(){Number=1, Text="First"},
                new RowData(){Number=2, Text="Second"}
            };
    }
}
<Window x:Class="NewRowDataTable.NewRowWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:NewRowDataTable"
        mc:Ignorable="d"
        Title="NewRowWindow" Height="450" Width="800">
    <FrameworkElement.DataContext>
        <local:RowsViewModel/>
    </FrameworkElement.DataContext>
    <Grid>
        <DataGrid ItemsSource="{Binding Rows}"
                  AddingNewItem="OnAddingNewRow"
                  InitializingNewItem="OnInitializingNewRow"/>
    </Grid>
    <x:Code><![CDATA[
        private void OnAddingNewRow(object sender, AddingNewItemEventArgs e)
        {
            e.NewItem = new RowData() {Text="Some data", Number=789};
        }

        private void OnInitializingNewRow(object sender, InitializingNewItemEventArgs e)
        {
            RowData data = (RowData) e.NewItem;
            data.Number *= 10;
            data.Text += "+Init";
        }

        ]]></x:Code>
</Window>
于 2021-08-19T10:52:06.670 回答