【问题标题】:C# Search datagridview for duplicatesC#在datagridview中搜索重复项
【发布时间】:2012-05-04 21:54:09
【问题描述】:

使用 ms visual studiocsharp .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)如果这只是一种非常糟糕的搜索方式,是否有人可以提供反映我想要实现的目标的代码。

非常感谢您未来的 cmets。

更新:: 好的,感谢您的帮助,我的算法现在可以工作了,但我的最后一个问题是显示在帕累托列上重复的零件编号,而不是显示长度。

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);

    }

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

【问题讨论】:

  • 几个问题 - 为什么你不能在数据输入过程中这样做,在用户即将输入行时警告用户它是重复的?网格中有多少数据?此外,这个问题看起来与您的上一个问题非常相似,您能否明确指出新问题是什么,并参考旧问题。最后,如果您像这里一样要问一个以上的问题,最好分开提问。
  • 感谢您清理它。我希望能够检查数据输入,但不确定该过程是什么以及使用什么事件处理程序。这就是为什么我有一个更新按钮。这个问题很相似,但一个新问题是逻辑不起作用。我已经提出这些问题来尝试概述问题和可能的答案,但是对数据输入进行检查会非常好。
  • 听起来即使在验证数据输入时,重复检查仍然存在问题,因为您的逻辑不太正确(没有时间正确阅读)。但是,一旦您对其进行排序,请查看 datagridview 验证事件——这些事件在单元格和行尝试提交时都会触发。在此我将检查底层数据源(而不是单元格)是否存在重复项。 msdn.microsoft.com/en-us/library/ykdxa0bc.aspx
  • 对于未来的问题,请尽量将每个问题保持为一个明确的问题,而不是将几个问题组合在一起,并尽量避免对原始问题进行太多修改,以免改变问题的意图。这两件事都使得很难很好地回答问题,并限制了帖子对未来人们的有用性。尽管如此,听起来你现在正走在正确的轨道上:)

标签: c# .net winforms datagridview


【解决方案1】:

这是一个简单的示例,展示了如何在数据输入期间执行验证。您可以通过多种方式自定义错误的显示方式(包括某种自定义对话框来解决错误),从而为您提供更好的解决方案。

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

}

当然,这并不总是符合您对用户喜欢使用的内容的要求,但我认为看到另一个选项会有所帮助。

【讨论】:

    【解决方案2】:

    您正在与 ==!= 进行比较。

    items.Cells[5].Value 公开一个对象。

    在您的情况下,这很可能是基于引用相等性进行相等性检查,这可能不是您想要的。尝试使用类似items.Cells[5].Value.Equals(item.Cells[5].Value)

    还请考虑在可用的最简单抽象上解决此类问题。例如。如果您将网格绑定到对象集合,那么您可以针对该对象集合执行清理操作,而忽略您在其上固定的任何 UI。

    您还可以考虑使用 LINQ 命名空间中的 Distinct 扩展方法并为其提供 IEqualityComparer* 以确保最有效的删除重复项的代码在.NET Framework 由您使用。


    *)IEqualityComparer 是一种抽象,当您认为两个对象相等时,它允许您在一个地方进行定义。 Distinct 提供了一个重载,您可以在其中指定这样的比较器。

    【讨论】:

    • 关于对象相等,你如何要求不相等的条件,或者你会简单地将你的代码放在 if 之后的 else 中?
    • !obj.Equals(obj2) 怎么样?
    • 所以值是比较的对象?所以: items.Cells[5].!Value.Equals(item.Cells[5].Value)??这行得通吗,对我来说似乎很奇怪
    • 嗯,您是在比较单元格值,不是吗?只写!比较前:!items.Cells[2].Value.Equals(item.Cells[2].Value)
    • 我把事情复杂化了-.-我认为由于对象 require.equals 作为一种方法,我认为有一个等效的相反方法......:你认为 LINQ 是顺便说一句的方法吗?我只是问,因为我之前从未让它工作,因此我的嵌套循环。会喜欢为了更简洁的逻辑而放弃巢穴
    【解决方案3】:

    看看这是否适合你

     var dup = dataGridView1.Rows.Cast<DataGridViewRow>().Distinct().Where(g => g.Index != 0);
    

    排除索引为0的行。它是标题行。

    【讨论】:

    • 我敢打赌,这是行不通的,因为 DataGridViewRow 的默认相等比较很可能是引用相等。
    • 他的重复条件不同。
    • 我更喜欢使用 LINQ 来实现我的重复检查,但我从来没有运气。这就是我使用嵌套循环的原因,但是如果你有一个 LINQ 版本的我想要做的事情,我很乐意测试它
    猜你喜欢
    • 2011-09-06
    • 1970-01-01
    • 2014-12-05
    • 2012-01-09
    • 2023-03-09
    • 2011-09-20
    • 2019-12-31
    • 1970-01-01
    相关资源
    最近更新 更多