如何在DataGridView控件中取消选择所有选定的行?

68

当用户单击控件的空白(非行)部分时,我希望取消选择 DataGridView 控件中的所有已选择行。
我应该如何做到这一点?

7个回答

145

要取消 DataGridView 中所有行和单元格的选择,可以使用 ClearSelection 方法

myDataGridView.ClearSelection()

如果您不想让第一行/单元格被选择,您可以CurrentCell属性设置为Nothing/null,这将暂时隐藏焦点矩形直到控件再次获得焦点:

myDataGridView.CurrentCell = Nothing

要确定用户何时单击了 DataGridView 的空白部分,您需要处理其 MouseUp 事件。在该事件中,您可以HitTest点击位置,并观察是否指示为HitTestInfo.Nowhere。例如:

Private Sub myDataGridView_MouseUp(ByVal sender as Object, ByVal e as System.Windows.Forms.MouseEventArgs)
    ''# See if the left mouse button was clicked
    If e.Button = MouseButtons.Left Then
        ''# Check the HitTest information for this click location
        If myDataGridView.HitTest(e.X, e.Y) = DataGridView.HitTestInfo.Nowhere Then
            myDataGridView.ClearSelection()
            myDataGridView.CurrentCell = Nothing
        End If
    End If
End Sub
当然,您也可以通过继承现有的DataGridView控件来将所有功能组合成一个自定义控件。您需要覆盖它的OnMouseUp方法,类似于上面所示的方式。为方便起见,我还喜欢提供一个名为DeselectAll的公共方法,它既调用了ClearSelection方法,又将CurrentCell属性设置为Nothing。(代码示例都是任意的VB.NET,因为问题没有指定语言 - 如果这不是您的母语,请谅解。)

这对我似乎没有起作用,我让它工作了,但我的 datagridview 没有 =HitTestInfo.Nowhere,我不得不将其更改为..... If myDataGridView.HitTest(e.X, e.Y) Is myDataGridView.HitTest(e.X, e.Y) Then...按预期工作,但不确定为什么会起作用。首先实现了 HitTest 代码。 - nora
1
@nora 你写的代码没有任何意义。它不应该工作。Is运算符比较两个引用变量的类型。所以你在那里做的只是检查HitTest属性返回与...HitTest属性相同类型的值。这就像说 If True = True - Cody Gray
之前我在想,是不是存在两种“HitTest”,一种用于空白区域,另一种用于单元格占用的区域?所以上面的HitTest语句意思是“如果空白区域是空白区域,则……”而单元格版本则可能是“如果单元格区域是单元格区域,则……”。不知道为什么我的代码中出现了“True = True”的情况,但当我点击一个单元格时,高亮保留;点击空白处时高亮消失。 - nora
2
@TaW 如果您能具体说明“太早”的含义,那么这条评论会更有帮助。 - Cody Gray
3
我发现在构造函数中填充DGV后,ClearSelection的执行时间过早。将ClearSelection移动到Form_Shown中可以正常工作。不确定确切的规则是什么,也许是“布局之后”?我添加了这个注释,因为有很多类似帖子的评论指出ClearSelection对他们无效。因此,将其添加到这个高票答案中似乎是一个好主意。 - TaW
显示剩余3条评论

10

C#版本:

if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            DataGridView.HitTestInfo hit = dgv_track.HitTest(e.X, e.Y);
            if (hit.Type == DataGridViewHitTestType.None)
            {
                dgv_track.ClearSelection();
                dgv_track.CurrentCell = null;
            }
        }

3

我发现为什么我的第一行被默认选中,并找到了如何不默认选择它的方法。

默认情况下,我的DataGridView是Windows表单上第一个可使用Tab键选择的对象。将另一个对象设置为第一个Tab键停止点(或者完全禁用DataGridView的Tab键)会禁止选择第一行。


这实际上也解决了我的问题。由于某种奇怪的原因,将“TabStop”属性更改为“false”似乎会在不选择“DataGridView”单元格/索引的情况下加载表单。 - Apostrofix
这个不起作用。如果在SelectionChanged事件上设置断点并启用.NET Framework源代码步进,您可以看到从OnHandleCreated()调用MakeFirstDisplayedCellCurrentCell()。这就是为什么会发生这种情况,而不是因为它可以“tab”进入。 - computerGuyCJ

1

设置

dgv.CurrentCell = null;

当用户单击dgv的空白部分时。

0

在VB.net中用于Sub:

    Private Sub dgv_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dgv.MouseUp
    ' deselezionare se click su vuoto
    If e.Button = MouseButtons.Left Then
        ' Check the HitTest information for this click location
        If Equals(dgv.HitTest(e.X, e.Y), DataGridView.HitTestInfo.Nowhere) Then
            dgv.ClearSelection()
            dgv.CurrentCell = Nothing
        End If
    End If
End Sub

0

gridView1.ClearSelection();

gridView1.FocusedColumn = null;
在你的情况下使用这个,希望能起作用。

0

我遇到了同样的问题,并找到了解决方案(不完全是靠自己,但有互联网在)

Color blue  = ColorTranslator.FromHtml("#CCFFFF");
Color red = ColorTranslator.FromHtml("#FFCCFF");
Color letters = Color.Black;

foreach (DataGridViewRow r in datagridIncome.Rows)
{
    if (r.Cells[5].Value.ToString().Contains("1")) { 
        r.DefaultCellStyle.BackColor = blue;
        r.DefaultCellStyle.SelectionBackColor = blue;
        r.DefaultCellStyle.SelectionForeColor = letters;
    }
    else { 
        r.DefaultCellStyle.BackColor = red;
        r.DefaultCellStyle.SelectionBackColor = red;
        r.DefaultCellStyle.SelectionForeColor = letters;
    }
}

这是一个小技巧,你能看到哪一行被选中的唯一方法是通过第一列(不是column[0],而是那个)。当你点击另一行时,你将不再看到蓝色的选择,只有箭头指示哪一行被选中。正如你所理解的,我在我的网格视图中使用了rowSelection。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接