gpt4 book ai didi

c# - 清除datagridview重复行并保留唯一行

转载 作者:行者123 更新时间:2023-12-03 03:02:42 27 4
gpt4 key购买 nike

所以当填充我的 datagridview 时我通常会做类似的事情

    public void FillTable(CoBRAMetaField[] metaFields)
{
dataGridView.Rows.Clear();

// do something with metaFields
}

重要:

  • CoBRAMetaField是一个带有 ID 和其他内容的对象

  • 网格中的每一行都包含一个元字段对象

我的网格填写正确(抱歉,语言是德语)

enter image description here

当我再次填充网格时,我只想删除新元字段数组中不存在的元字段行。我想要这种行为,因为当用户为此行选择一个值时,我不希望它被删除并再次创建,因为这样选定的值也会被删除。

我想出了这个

    public void FillTable(CoBRAMetaField[] metaFields)
{
for (int i = 0; i < dataGridView.Rows.Count; i++) // loop through the grid rows
{
double metaFieldID = (dataGridView.Rows[i].Cells[0].Tag as CoBRAMetaField).ID; // get the ID from the row metaField

if (metaFields.Any(field => field.ID == metaFieldID)) // Does it exist?
metaFields = metaFields.Where(field => field.ID != metaFieldID).ToArray(); // Remove it from the new array
else // it doesn't exist
dataGridView.Rows.Remove(dataGridView.Rows[i]); // remove the row
}

// Fill the grid with the remaining metaFields
}

第一次运行正确初始化

enter image description here

第二次运行似乎崩溃了,某些字段仍为空

enter image description here

当我按下该行上的按钮时,出现空指针异常。我只在使用“新代码”时收到此错误,所以我错过了什么吗?有什么我没有想到的吗?

<小时/>

我将在此处提供完整的示例

首先创建一个DataGridViewButton表格上。为所有必需的类创建一个文件并获取此代码段

https://pastebin.com/BFmr2ps9

之后用一些测试数据填充表单代码

https://pastebin.com/Yz84Akkj

现在设置 DataGridView逻辑

https://pastebin.com/qH6kZKZv

我添加

dataGridView.AllowDrop = false;
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.AllowUserToOrderColumns = false;
dataGridView.AllowUserToResizeRows = false;

如果您只想复制粘贴,但也可以通过表单设计器来完成。看看dataGridView.Rows.Clear();这提供了一个工作示例。 将其注释掉并使用上面的代码来测试不正确的示例

最佳答案

主要问题在于添加行的代码(取自链接):

// Fill the grid with the remaining metaFields
for (int i = 0; i < metaFields.Length; i++)
{
MetaField currentMetaField = metaFields[i];

dataGridView.Rows.Add(currentMetaField.Name, null);

DataGridViewRow newRow = dataGridView.Rows[i]; // <-- Problem!

DataGridViewCell metaFieldCell = newRow.Cells[0];
metaFieldCell.Tag = currentMetaField;

(newRow.Cells[1] as DataGridViewAllocationCell).Initialize(releaseSetupData);
}

在标记行中,您假设添加的行的索引与 i 相同,当您从空网格开始时,这是正确的,但当网格更新和一些旧网格时则不然。保留记录。

处理它的正确方法是不假设新的行索引 - 它由 Add 返回。方法:

int rowIndex = dataGridView.Rows.Add(currentMetaField.Name, null);

DataGridViewRow newRow = dataGridView.Rows[rowIndex];

这将解决问题中的原始问题。

代码的删除部分也存在一个问题 - for 循环将错过检查已删除行旁边的行。每当您想要迭代某些列表并在迭代期间删除项目时,请使用 reverse for 循环和 RemoveAt:

for (int i = dataGridView.Rows.Count - 1; i >= 0; i--) // <--
{
double metaFieldID = (dataGridView.Rows[i].Cells[0].Tag as MetaField).ID;

if (metaFields.Any(field => field.ID == metaFieldID))
metaFields = metaFields.Where(field => field.ID != metaFieldID).ToArray();
else
dataGridView.Rows.RemoveAt(i); // <--
}

删除代码还可以进一步改进(目前使用这些 AnyWhere + ToArray 看起来效率很低),但至少使用上面的代码更改后它将正常工作。

关于c# - 清除datagridview重复行并保留唯一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53396499/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com