【问题标题】:C# Determine how a row/data is added to a DataGridViewC# 确定如何将行/数据添加到 DataGridView
【发布时间】:2022-01-25 08:38:38
【问题描述】:

我有一个用例,我在 DataGridView 中显示来自数据库的数据,但是当我在 UI 上添加新行时(没有添加新行的代码,当我单击按钮时,我从 DataGridView 中获取所有行 - 旧来自数据库的行和在 UI 上添加的新行),我需要知道从 UI 中添加了哪些行。有没有办法在不检查数据库并进行比较的情况下知道它?我想从 UI 中了解它。我尝试过使用 ISNewRow(),但仅适用于最后一行。

【问题讨论】:

  • 最好是一小部分涉及加载 DataGridView 的代码将有助于回答您的问题,因为加载 DataGridView 有几种不同的方法。
  • DataGridView 有几个事件会在向网格中添加新行时触发……DataGridView.RowsAdded Event……可能就是您要找的。目前尚不清楚网格是如何填充的,我假设DataTable 可能会用作网格的DataSource。在这种情况下,DataTable 有一个可能有效的GetChanges 方法。你看过DataAdapter吗?
  • 我建议您仔细阅读 SO tour 部分,因为它显示了 SO 的工作原理。 How to Ask 部分可能会有所帮助。此外,您可能会发现 SO Asking 部分很有用。

标签: c# winforms datagridview


【解决方案1】:

当使用 DataGridView 时,人们倾向于直接摆弄行和单元格。虽然这是可能的,但通过属性 DataSource 使用数据绑定要容易得多。

使用 Visual Studio 设计器,您已经添加了 DataGridView 和要显示的列。虽然可以定义哪个列应该显示哪个属性,但在构造函数中更容易做到这一点。

可惜你忘了告诉我们你想显示什么项目,所以假设你想显示Product的几个属性:

class Product
{
    public int Id {get; set;}
    public string Description {get; set;}
    public decimal Price {get; set;}
    public int Stock {get; set;}
    ...
}

假设您想在 DataGridView 中将这些值显示为列。在构造函数中,您将编写:

public MyForm()
{
    InitializeComponent();  // Creates the DataGridView and the columns

    // define which column should show which property
    this.ColumnId.DataPropertyName = nameof(Product.Id);
    this.ColumnDescription.DataPropertyName = nameof(Product.Description);
    this.ColumnPrice.DataPropertyName = nameof(Product.Price);
    this.ColumnStock.DataPropertyName = nameof(Product.Stock);
    ... // etc, for all Product properties that you want to show
}

在某个地方,您将有一种从数据库中获取产品的方法:

private IEnumerable<Product> FetchProductsToDisplay()
{
    ... // TODO: implement; out of scope of this question
}

要显示产品:通过 BindingList&lt;Product&gt; 将它们分配给 DataGridView 的数据源:

private BindingList<Product> DisplayedProducts
{
    get => (BindingList<Product>)this.DataGridView1.DataSource;
    set => this.DataGridView1.DataSource = value;
}

在加载表单时,或在某些其他事件之后,您需要使用 Products 填充 datagridview:

private void InitializeTableProducts()
{
    IEnumerable<Product> productsToDisplay = this.FetchProductsToDisplay();
    this.DisplayedProducts = new BindingList<Product>(productsToDisplay.ToList());
}

这足以显示产品。操作员可以根据您在列和数据网格视图中定义的可编辑性添加/删除产品和编辑单元格。如果允许,他甚至可以重新排列行和列。

当操作员完成编辑后,他会通知软件,例如按下 OK 按钮:

private void OnButtonOk_Clicked(object sender, ...)
{
    this.ProcessEditedProducts();
}

private void ProcessEditedProducts()
{
    ICollection<Product> editedProducts = this.DisplayedProducts;
    this.ProcessProducts(editedProducts);
}

在 ProcessProducts 中,您必须找出添加/删除/更改了哪些产品。我假设您会通过零 ID 识别已编辑的产品。

要确定一个产品是否被删除:它将在原始数据库中有一个 Id,但在editedProducts 中没有。

更改产品更难:您需要按价值进行比较。为此,您需要创建一个IEqualityComparer&lt;Product&gt;

我假设您知道如何检查产品是否被添加/删除/更改的技术。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多