DataGridView 上的 Foreach 循环中的其他条件不起作用

Posted

技术标签:

【中文标题】DataGridView 上的 Foreach 循环中的其他条件不起作用【英文标题】:Else Condition in Foreach Loop on DataGridView Not Working 【发布时间】:2021-12-11 12:35:10 【问题描述】:

我想知道您是否可以向我推动正确的方向 - 我有一些 C# 代码和两个 DataGridViews ()dgv1 和 dgv2)。当按下按钮时,dataGridViews 会从两个不同的数据库中填充(通过 Datatable 作为源)。两个 DataGridView 的列数相同,我使用第 4 列(单元格 3)来检查 dgv1 中的行在单元格 3 中是否与 dgv2 中的任何行具有相同的值。我想要实现的是;

如果在 dgv1 中选择了一行并且有匹配的行(单元格 3 中的值相同),则该行在 dgv2 中自动突出显示 当 dgv1 中的选择发生变化时,也会发生同样的情况,即 foreach 循环检查 dgv2 以找到匹配项 如果 dgv1 中的选定行在 dgv2 中不匹配,我想显示一个消息框,说明“不匹配”

现在,我在 dgv1 的 SelectionChanged 事件中编写了代码,并且 foreach 工作正常,并且完全符合我的要求......直到我设置了一个 else 条件。当我放置 else 条件时,每次在 dgv1 中进行选择时都会显示消息框,即使存在匹配项也是如此。我需要的是消息框仅在 dgv1 和 dgv2 不匹配时出现。以下是我的代码;

private void dgv1_SelectionChanged(object sender, EventArgs e)
        

            this.dgv2.ClearSelection();
            this.dgv2.Tag = "";
            txtBxID.Text = "";
            
            foreach (DataGridViewRow dgv2row in dgv2.Rows)
            

                if (dgv1.CurrentRow.Cells[3].Value.ToString() == Convert.ToString(dgv2row.Cells[3].Value))
                
                    
                    dgv2.Selected = true;
                    txtBxID.Text = dgv2.Cells[6].Value.ToString();
                    dgv2.Tag = dgv2row.Cells[6].Value.ToString();
                    MessageBox.Show(Convert.ToString(dgv2.Tag));
                    
                
            
            
               else
                
                    MessageBox.Show("no match");
                
            

        

我希望这一切都是有道理的,如果有人问过同样或类似的问题,我深表歉意。我仍在尝试熟悉 ***。

编辑:根据@KlausGütter 和@KostandinVllahu 的两个答案,我尝试添加一个布尔变量,如下所示。不过,这已经解决了一半的问题。现在发生的情况是 - 当单击按钮(填充 dataGridViews)时,显示“不匹配”的消息框重复显示大约 5 次(大概是要添加到 dataGridViews 的每一行,在这种情况下为 5 次),一旦我在消息框上单击“确定”并且它们消失了,代码就会执行我想要的操作。布尔值哪里出错了?我放错了吗?我已经完成了以下操作;

private void dgv1_SelectionChanged(object sender, EventArgs e)
        

                      
            this.dgv2.ClearSelection();
            this.dgv2.Tag = "";
            txtBxID.Text = "";
            
            Boolean match = false;
            
            foreach (DataGridViewRow dgv2row in dgv2.Rows)
            

                if (dgv1.CurrentRow.Cells[3].Value.ToString() == Convert.ToString(dgv2row.Cells[3].Value))
                
                    match = true;  
                    dgv2.Selected = true;
                    txtBxID.Text = dgv2.Cells[6].Value.ToString();
                    dgv2.Tag = dgv2row.Cells[6].Value.ToString();
                    MessageBox.Show(Convert.ToString(dgv2.Tag));
                    
                
            
            
               if (!match)
                
                    MessageBox.Show("no match");
                
            

        

非常感谢。

【问题讨论】:

您希望仅在检查完所有行之后(即在 foreach 循环之后)才显示“不匹配”消息框。您将需要一个布尔变量来跟踪您是否遇到匹配项。 boolean 很好用,所以你可以在没有记录的时候让它变假并打印消息。 @KostandinVllahu 感谢您的快速响应 - 您能否举个例子说明您需要一个布尔变量是什么意思? @KlausGütter 感谢您的快速响应 - 另一个建议使用布尔变量的答案。我能不能麻烦你举个例子来说明你的意思? 我已经编辑了这个问题,因为我试图添加以下内容 - 希望我理解正确 - 请查看显示我所做的编辑问题。 【参考方案1】:

消息框通常很烦人。当您在网格周围单击时,您很快就会厌倦不得不关闭“不匹配”消息框。想想此刻不得不关闭该框 5 次是多么烦人,这可以通过将鼠标保持在同一个位置并单击单击单击单击单击来实现。当您尝试工作时,它变得更加令人厌烦,单击 dgv1 中的单元格,然后不得不一直跋涉到屏幕中间,关闭“不匹配”,返回并单击另一个单元格,再次关闭“不匹配”

相反,让我们显示和隐藏一个标签,您可以根据需要将其设为粗体大红色。来来往往的标签不会打断用户的工作流程。尽量避免使用消息框...

标签的好处是我们可以在操作开始时显示它,如果我们找到一行就隐藏它,如果我们没有就不要隐藏它。这意味着在操作结束时它始终处于我们想要的状态。它隐含地包含了我们的布尔逻辑

    private void dgv1_SelectionChanged(object sender, EventArgs e)
             
        this.dgv2.ClearSelection();
        this.dgv2.Tag = "";
        txtBxID.Text = "";
        noMatchWarningLabel.Visible = true;

        var lookingFor = dgv1.CurrentRow.Cells[3].Value.ToString();
        
        foreach (DataGridViewRow dgv2row in dgv2.Rows)
        
            if (lookingFor == Convert.ToString(dgv2row.Cells[3].Value))
            
                dgv2row.Selected = true;
                dgv2.Tag = txtBxID.Text = dgv2row.Cells[6].Value.ToString();
                noMatchWarningLabel.Visible = false;
            
        
    

【讨论】:

感谢您的帮助。我已经尝试了上述方法,它只在一定程度上有效。标签在 Form Load 上可见,因此我将 Form Load 上的可见性设置为 false。这一直有效,直到用户单击按钮以填充 DataGridViews - 一旦单击按钮,标签就可见,直到在 dgv1 中进行选择。从那时起,一切正常。您能想出一种方法来在单击按钮时隐藏标签,并且仅在 dgv1 中的行选择中找不到“查找”进行比较时才使其可见。 noMatchWarningLabel.Visible = dgv2.Rows.Count > 0; 怎么样 - 这意味着标签只有在 dgv2 中有要搜索的行时才设置为可见。我怀疑 dgv1 在 dgv2 之前被填充,它的 SelectionChanged 触发,标签设置为始终可见,dgv2 中没有行,循环不运行,它永远不会变得不可见,因为唯一发生不可见的地方是在不可见的循环内'不运行.. 所以让我们让它以循环能够运行并可能隐藏它为条件出现.. 我们需要找到一些合适的条件使其在第一个实例中可见 (即使在 dgv1 之前填充 dgv2 可能就足够了)

以上是关于DataGridView 上的 Foreach 循环中的其他条件不起作用的主要内容,如果未能解决你的问题,请参考以下文章

php foreach为啥比for效率高

winform 窗体退出前判断表单是不是修改过,窗体上的控件有很多个,TextBox,combox,datagridview

C# DataGridView 用法

以编程方式定义DataGridView列类型

动态更改 datagridview 单元格颜色

C# Foreach 循环 - 继续问题