【问题标题】:Change Current Cell, Without Removing the Selection更改当前单元格,而不删除选择
【发布时间】:2015-04-06 07:21:38
【问题描述】:

一旦我在 datagridview 中选择了多个单元格,我希望我的当前单元格等于在 datagridview 中选择的第一个单元格。我遇到的问题是,在做出选择后(鼠标向上),我将当前单元格设置为第一个选定的单元格(me.datagridview.currentcell =),但这会删除 datagridview 中的所有其他选择.有谁知道更改当前单元格的方法,而不删除 datagridview 选择。当前示例代码如下:

    Private Sub DataGridView1_CellMouseUp(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseUp

    a = 0
    Do While a < Me.DataGridView1.RowCount
        b = 0
        Do While b < Me.DataGridView1.ColumnCount
            If Me.DataGridView1.Rows(a).Cells(b).Selected = True Then
                Me.DataGridView1.CurrentCell = Me.DataGridView1.Rows(a).Cells(b)
                GoTo skipstep
            End If
            b += 1
        Loop
        a += 1
    Loop

    skipstep:

    End Sub

【问题讨论】:

    标签: vb.net datagridview selection


    【解决方案1】:

    如果您查看CurrentCell 属性的源代码,您会发现它调用了ClearSelection 之前 SetCurrentCellAddressCore。但是您不能调用“SCCAC”,因为它被定义为Protected。所以我最好的建议是你继承 DGV 并创建一个新的公共方法。

    Public Class UIDataGridView
        Inherits DataGridView
    
        Public Sub SetCurrentCell(cell As DataGridViewCell)
            If (cell Is Nothing) Then
                Throw New ArgumentNullException("cell")
            'TODO: Add more validation:
            'ElseIf (Not cell.DataGridView Is Me) Then
            End If
            Me.SetCurrentCellAddressCore(cell.ColumnIndex, cell.RowIndex, True, False, False)
        End Sub
    
    End Class
    

    如果您不想继承 DGV,那么反射是您唯一的选择。

    Imports System.Reflection
    

    Private Sub HandleCellMouseDown(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseDown
        Me.firstCell = If(((e.ColumnIndex > -1) AndAlso (e.RowIndex > -1)), Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex), Nothing)
    End Sub
    
    Private Sub HandleCellMouseUp(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseUp
        If ((Not Me.firstCell Is Nothing) AndAlso (Me.firstCell.Selected AndAlso (Me.DataGridView1.SelectedCells.Count > 1))) Then
    
            Dim type As Type = GetType(DataGridView)
            Dim flags As BindingFlags = (BindingFlags.Instance Or BindingFlags.Static Or BindingFlags.Public Or BindingFlags.NonPublic)
            Dim method As MethodInfo = type.GetMethod("SetCurrentCellAddressCore", flags)
    
            method.Invoke(Me.DataGridView1, {Me.firstCell.ColumnIndex, Me.firstCell.RowIndex, True, False, False})
    
            Debug.WriteLine("First cell is current: {0}", {(Me.DataGridView1.CurrentCell Is Me.firstCell)})
    
        End If
    End Sub
    
    Private firstCell As DataGridViewCell
    

    PS:您是否忘记了用户可以使用键盘选择单元格? ;)

    【讨论】:

    • 这是一个非常好的答案,谢谢大家。无法让您的第一个选项起作用(我对 VB.NET 还很陌生,我需要多玩一点),但是您的第二个选项就像一个魅力。再次感谢!!!
    • 对于选项 1,您需要执行以下操作:在“解决方案资源管理器窗格”中,右键单击您的应用程序名称并转到“添加 > 类”。将名称更改为“UIDataGridView.vb”并单击添加。用我的答案(第一部分)中的代码替换自动生成的代码。重建您的解决方案。自定义控件现在位于“工具箱窗格”的顶部。您可以将此控件拖放到窗体上。哦,既然你是新手,这里有一个专业提示:将严格的编译器选项设置为On。这非常很重要。 msdn.microsoft.com/en-us/library/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多