2012-04-24 76 views
1

使用ms visual studiocsharp .net4C#搜索datagridview重复项

这是代码我必须检查重复

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)将安排名单的工作添加信息,如果是的话是一个简单的绑定到DataGrid视图足以显示结果?

3)如果这只是一个非常糟糕的搜索方式,有人可以提供反映我正试图实现的代码。

非常感谢您的宝贵意见。

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

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

    } 

即使消息框正确显示结果?它绑定到我的datagrid时是否错过了一些东西?

+0

几个问题 - 为什么你不能在数据输入过程中这样做,警告用户,因为他们即将进入一个重复的行?你在网格中有多少数据?此外,这个问题看起来与您最后一个问题非常相似,您是否可以说明新问题是什么,回到旧问题。最后,如果你有更多的问题需要像你这样问,那么在单独的问题中提问几乎总是更好。 – 2012-04-24 09:14:55

+0

感谢您清理它。我希望能够检查数据输入,但不确定该过程是什么以及使用哪个事件处理程序。这就是为什么我有一个更新按钮。这个问题是相似的,但一个新问题是逻辑不起作用。我问了这些问题试图概述问题和可能的答案,但是检查数据输入是非常好的。 – lemunk 2012-04-24 09:17:21

+0

听起来好像即使在数据输入验证时重复检查仍然存在问题,因为您的逻辑不太正确(没有时间仔细阅读)。但是,一旦您对此进行排序,请查看datagridview验证事件 - 这些事件在单元格和行尝试提交时都会触发。在这我会检查底层的数据源(而不是单元格)重复。 http://msdn.microsoft.com/en-us/library/ykdxa0bc.aspx – 2012-04-24 13:21:48

回答

3

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

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

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

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

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

也请考虑解决这些问题上最简单的抽象可用。例如。如果您将网格绑定到一组对象,那么您可以针对该对象集合执行清理操作,忽略任何插入其上的UI。

您也可以考虑使用鲜明扩展方法从LINQ命名空间和提供给它的IEqualityComparer*确保去除在.NET Framework可重复最有效的代码由你。


*)IEqualityComparer是一种抽象,它允许你在一个地方定义,当你考虑两个对象是相等的。 独特提供了一个重载,您可以指定这样一个比较器。

+0

关于对象的等式,你如何要求一个不平等的条件,或者你会简单地把你的代码放在else之后的if中? – lemunk 2012-04-24 09:24:27

+0

'!obj.Equals(obj2)'? – flq 2012-04-24 09:26:08

+0

所以价值是比较的对象?所以:items.Cells [5]。!Value.Equals(item.Cells [5] .Value)??这样做的工作,对我来说似乎很奇怪 – lemunk 2012-04-24 09:33:55

0

见这是否可以为你工作

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

剔除一行指数为0。这是标题行。

+0

我敢打赌,这将无法正常工作,因为DataGridViewRow的默认相等比较最可能是引用相等。 – flq 2012-04-24 09:23:54

+0

他的复制条件是不同的。 – Akanksha 2012-04-24 09:28:35

+0

我更喜欢使用LINQ来达到我对重复的检查,但我从未有过任何运气。这就是为什么即时通讯使用嵌套循环,但如果你有一个LINQ版本的即时通讯试图做的IM比更乐意测试它 – lemunk 2012-04-24 09:54:24