winforms 完全排除DataGridView中的列

mm5n2pyu  于 2022-11-17  发布在  其他
关注(0)|答案(2)|浏览(191)

我有一个DataTable,我想将其用作DataGridViewDataSource,但需要进行一些修改:由于下面的原因,我需要从DataGridView中排除一列(不仅仅是隐藏它,而是真正排除),理想的情况是防止它一起生成。理论上,我可以在适当的时候调用Columns.RemoveAt(这是DataBindingComplete事件处理程序- docs),但对我来说太晚了(由于原因)。
一个明显的解决方案是设置AutoGenerateColumns = false并手动完成。在没有研究这个细节的情况下,我担心我需要在这个场景中重新发明轮子(以保持数据绑定工作等)。
我的理由是,有一个巨大的遗留应用程序,最初是用VB 6编写的,任何字节数组列都被 *MS分层网格 * 忽略。我试图在一个从DataGridView派生的自定义控件中模拟这种行为,大多数东西都能工作。

更新/回答只需设置dt.Columns[0].ColumnMapping = MappingType.Hidden;(由https://stackoverflow.com/a/31282356/5263865提供)

e5njpo68

e5njpo681#

在现代编程中,有一种趋势是将数据(=Model)与数据显示给操作员(=View)的方式分离。需要一个适配器类(=ViewModel)将模型连接到视图。缩写为MVVM。如果你不熟悉这种分离的概念,可以考虑做一些背景阅读。
您的数据位于DataTable中。您没有提到DataTable中有哪些类型的项。为了便于讨论,我假设DataTable包含一个序列Products

class Product
{
    ...
}

您可以使用一些方法将产品放入DataTable中并访问它们。例如:

interface IProductRepository
{
    IEnumerable<Product> AllProducts {get;}
    Product GetProductById(int productId);

    void AddProductAtEnd(Product product);
    void ReplaceProduct(Product product, int index);
    ...
}

确切的方法对于答案并不重要。我试图解释的是,当使用此接口时,您隐藏了产品存储在DataTable中的情况。这给予您可以自由地更改产品的存储位置:数据库?列表?或者文件,甚至互联网。
我使用一个通用术语仓库(仓库)来表示您可以在其中存储项目,然后检索它们,用其他项目替换它们,或者从仓库中删除它们的东西。这可以是一个DataTable,或者一个数据库,或者一个文件,一个字典,等等。好的地方是我隐藏了产品在DataTable中。

数据网格视图

当访问DataGridView中的数据时,人们倾向于直接摆弄DataGridViewCells和DataGridViewRows。
好吧,不要!
请改用数据绑定。
在几乎所有具有DataGridViews的表单中,我都具有以下属性:

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

Product CurrentProduct => this.DataGridView1.CurrentRow as Product;

IEnumerable<Product> SelectedProducts => this.DataGridView1.SelectedRows
    .Select(row => row.DataboundItem)
    .Cast<Product>();

返回您的问题

出于下面的原因,我需要从DataGridView中排除一个列(不仅仅是隐藏它,而是真正排除),理想情况下是防止它生成
如果我从字面上理解你的问题:您不希望生成位于被排除的列中的DataGridViewCells。
这不会影响每一列所代表的“产品”,只会影响这些“产品”的显示。例如:即使每个产品都有一个Id,您也可能不希望显示此ID。
最简单的方法是使用Visual Studio Designer来实现这一点。不必使用DataBinder定义列,只需逐个添加列,并使用每个列的属性作为列的名称、必须显示的属性的名称以及用于显示值的格式。
代码如下所示:

DataGridView dataGridView1 = new DataGridView();

// Column to show Product.Id
DataGridViewColumn columnProductId = new DataGridViewColumn();
columnProductId.HeaderText = "ID";
columnProductId.DataPropertyName = nameof(Product.Id);

// Column to show Product.Name
DataGridViewColumn columnProductName = new DataGridViewColumn();
columnProductName.HeaderText = "Name";
columnProductName.DataPropertyName = nameof(Product.Name);

// etc. for all columns that you want to show

注意:在DataPropertyName中,您存储了必须在此列中显示的属性的名称。我使用了关键字nameof,因此如果以后属性的名称发生更改,这不会是一个问题。
当然,如果你想要一些特殊的格式,例如数字或日期,你也需要设置适当的属性。这也可以在visual studio设计器中完成。
定义列后,将它们添加到DataGridView。
To Display the Products是一个两行程序:

IDataTableProducts ProductRepository {get;} // initialize in constructor

void ShowProducts()
{
    IEnumerable<Product> productsToDisplay = this.ProductRepository.AllProducts;
    this.DisplayedProducts = new BindingList<Product>(productsToDisplay.ToList());
}
qij5mzcb

qij5mzcb2#

我偶然发现了一个答案:https://stackoverflow.com/a/31282356/5263865
设置column.ColumnMapping = MappingType.Hidden正好满足了我的需要:该列不再自动生成。

DataTable data;
data.Columns[0].ColumnMapping = MappingType.Hidden;

相关问题