使用 ms visual studio 和 csharp .net4 。
这是我必须检查重复的代码
public void CheckForDuplicate()
{
DataGridViewRowCollection coll = ParetoGrid.Rows;
DataGridViewRowCollection colls = ParetoGrid.Rows;
List<string> listParts = new List<string>();
int count = 0;
foreach (DataGridViewRow item in coll)//379
{
foreach (DataGridViewRow items in colls)//143641
{
if (items.Cells[5].Value == item.Cells[5].Value)
{
if (items.Cells[2].Value != item.Cells[2].Value)
{
listParts.Add(items.Cells["Keycode"].Value.ToString());
count++;
dupi = true;
//txtDupe.Text = items.Cells["Keycode"].Value.ToString();
//this.Refresh();
}
}
}
}
MyErrorGrid.DataSource = listParts;
}
在允许用户保存之前,这是检查。
private void butSave_Click(object sender, EventArgs e)
{
CheckForDuplicate();
if (dupi == true)
{
txtDupe.Clear();
dupi = false;
}
else
{
SaveMyWorkI();
dupi = false;
}
}
这是它正在查看的数据:
现在,我知道逻辑必须有缺陷,因为无论如何都要保存。 我基本上搜索 pareto1 上的每个单元格,看看用户是否已经创建了任何重复项,如果是,它将不会保存,而是在另一个datagridview中显示部件号等......那就是计划。
所以有人可以看一看并告诉我
1) 逻辑中失败的位置,如果检查结果正确怎么办?
2)列表是否可以添加信息,如果是这样,一个简单的绑定到数据网格视图就足以显示结果了?
3)如果这只是一种非常糟糕的搜索方式,有人会提供反映我想要实现的内容的代码。
非常感谢您将来的评论。
UPDATE ::好的感谢您的帮助,我的算法现在可以正常工作,但我的最后一个问题是显示在帕累托列上重复的部件号,而不是显示长度。
public void CheckForDuplicate()
{
DataGridViewRowCollection coll = ParetoGrid.Rows;
DataGridViewRowCollection colls = ParetoGrid.Rows;
List<string> listParts = new List<string>();
int count = 0;
foreach (DataGridViewRow item in coll)//379
{
foreach (DataGridViewRow items in colls)//143641
{
count++;
if ((items.Cells[5].Value != null))
{
if ((items.Cells[5].Value != null) && (items.Cells[5].Value.Equals(item.Cells[5].Value)))
{
if ((items.Cells[2].Value != null) && !(items.Cells[2].Value.Equals(item.Cells[2].Value)))
{
listParts.Add(items.Cells["Keycode"].Value.ToString());
dupi = true;
}
}
}
}
}
MyErrorGrid.DataSource = listParts;
var message = string.Join(Environment.NewLine, listParts);
//MyErrorGrid.DataSource = message;
MessageBox.Show(message);
}
即使消息框正确显示结果?是绑定到我的数据网格时错过的东西吗?
答案 0 :(得分:3)
这是一个简单的示例,说明如何在dataentry期间执行验证。您可以通过多种方式自定义错误的显示方式(包括某种自定义对话框以解决错误),这些方法可能会为您提供更好的解决方案。
public partial class Form1 : Form
{
BindingSource bs;
DataTable dt; public Form1()
{
InitializeComponent();
BindingList<BindingClass> data = new BindingList<BindingClass>
{
new BindingClass{ Name = "one" },
new BindingClass { Name = "two"}
};
dataGridView1.DataSource = data;
dataGridView1.CellValidating += new DataGridViewCellValidatingEventHandler(dataGridView1_CellValidating);
}
void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Index != e.RowIndex & !row.IsNewRow)
{
if (row.Cells[0].Value.ToString() == e.FormattedValue.ToString())
{
dataGridView1.Rows[e.RowIndex].ErrorText =
"Duplicate value not allowed";
e.Cancel = true;
return;
}
}
}
dataGridView1.Rows[e.RowIndex].ErrorText = string.Empty;
}
}
public class BindingClass
{
public string Name { get; set; }
}
}
当然,这并不总是符合您对用户喜欢使用的要求,但我认为可以帮助您查看其他选项。
答案 1 :(得分:1)
您正在与 == 和!= 进行比较。
items.Cells[5].Value
公开了一个对象。
在您的情况下,这很可能是基于引用相等性进行相等性检查,这可能不是您想要的。尝试使用items.Cells[5].Value.Equals(item.Cells[5].Value)
请考虑用最简单的抽象方法解决这些问题。例如。如果您将网格绑定到对象集合,那么您可以对该对象集合执行清理操作,而忽略您在其上固定的任何UI。
您还可以考虑使用LINQ命名空间中的 Distinct 扩展方法,并为其提供IEqualityComparer
* ,以确保删除重复项的最有效代码您可以使用.NET Framework中提供的。
*) IEqualityComparer是一种抽象,允许您在考虑两个对象相等时在一个地方定义。 Distinct 提供了一个重载,您可以指定这样的比较器。
答案 2 :(得分:0)
看看这是否适合你
var dup = dataGridView1.Rows.Cast<DataGridViewRow>().Distinct().Where(g => g.Index != 0);
排除索引为0的行。它是标题行。