C#搜索datagridview以获取重复项

时间:2012-04-24 09:06:59

标签: c# .net winforms datagridview

使用 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;
        }
    }

这是它正在查看的数据: enter image description here

现在,我知道逻辑必须有缺陷,因为无论如何都要保存。 我基本上搜索 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);

    }

即使消息框正确显示结果?是绑定到我的数据网格时错过的东西吗?

3 个答案:

答案 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的行。它是标题行。