Как получить местоположение ячейки в DataGridView на control.MouseDown?

В настоящее время у меня есть DataGridView, который пользователь может заполнить набором UserControls. Я прикрепил обработчик для события control.MouseDown к этим элементам управления внутри формы.

У меня проблема с получением индексов x и y ячейки. Мне нужно иметь возможность получить значение столбца и строки, но то, что я пробовал, не работает.

Это соответствующий фрагмент кода.

Private Sub MachineTaskMouseDownHandler(sender As Object, e As MouseEventArgs) Handles eventClass.MachineTaskAttemptMove
    Debug.WriteLine("frmSchedule.MachineTaskMouseDownHandler: Raw: " & e.Location.ToString & " " & Me.ScheduleDataGridView.HitTest(e.X, e.Y).ColumnIndex & " " & Me.ScheduleDataGridView.HitTest(e.X, e.Y).RowIndex & " " & Me.ScheduleDataGridView.HitTest(e.X, e.Y).ColumnX & " " & Me.ScheduleDataGridView.HitTest(e.X, e.Y).RowY)
    Dim p2 As Point = Me.ScheduleDataGridView.PointToClient(e.Location)
    Debug.WriteLine("frmSchedule.MachineTaskMouseDownHandler: ToClient: " & p2.ToString & Me.ScheduleDataGridView.HitTest(p2.X, p2.Y).ColumnIndex & " " & Me.ScheduleDataGridView.HitTest(p2.X, p2.Y).RowIndex & " " & Me.ScheduleDataGridView.HitTest(p2.X, p2.Y).ColumnX & " " & Me.ScheduleDataGridView.HitTest(p2.X, p2.Y).RowY)
    Dim p3 As Point = Me.ScheduleDataGridView.PointToScreen(e.Location)
    Debug.WriteLine("frmSchedule.MachineTaskMouseDownHandler: ToScreen: " & p3.ToString & Me.ScheduleDataGridView.HitTest(p3.X, p3.Y).ColumnIndex & " " & Me.ScheduleDataGridView.HitTest(p3.X, p3.Y).RowIndex & " " & Me.ScheduleDataGridView.HitTest(p3.X, p3.Y).ColumnX & " " & Me.ScheduleDataGridView.HitTest(p3.X, p3.Y).RowY)
    Dim ht As DataGridView.HitTestInfo = Me.ScheduleDataGridView.HitTest(p.X, p.Y)
    from = New Point(ht.ColumnIndex, ht.RowIndex)
    Debug.WriteLine("frmSchedule.MachineTaskMouseDownHandler: Mouse down on control at " & from.ToString)

Приведенный выше код противоречив. В зависимости от того, где я щелкаю в ячейке, вывод меняется. Например, вывод при нажатии в левом верхнем углу ячейки (0,0):

frmSchedule.MachineTaskMouseDownHandler: Raw: {X=10,Y=14} -1 -1 1 1
frmSchedule.MachineTaskMouseDownHandler: ToClient: {X=-228,Y=-92}-1 -1 -1 -1
frmSchedule.MachineTaskMouseDownHandler: ToScreen: {X=248,Y=120}1 1 197 95
frmSchedule.MachineTaskMouseDownHandler: Mouse down on control at {X=-1,Y=-1}

По сравнению с щелчком в правом нижнем углу той же самой точной ячейки:

frmSchedule.MachineTaskMouseDownHandler: Raw: {X=148,Y=53} 0 0 42 22
frmSchedule.MachineTaskMouseDownHandler: ToClient: {X=-115,Y=-78}-1 -1 -1 -1
frmSchedule.MachineTaskMouseDownHandler: ToScreen: {X=411,Y=184}2 2 352 168
frmSchedule.MachineTaskMouseDownHandler: Mouse down on control at {X=0,Y=0}

И просто для полноты, вот результат выполнения mouseDown в правом нижнем углу ячейки (1,0):

frmSchedule.MachineTaskMouseDownHandler: Raw: {X=135,Y=61} 0 0 42 22
frmSchedule.MachineTaskMouseDownHandler: ToClient: {X=-103,Y=-45}-1 -1 -1 -1
frmSchedule.MachineTaskMouseDownHandler: ToScreen: {X=373,Y=167}2 1 352 95
frmSchedule.MachineTaskMouseDownHandler: Mouse down on control at {X=0,Y=0}

Мне просто нужно получить местоположение ячейки (индексы строк / столбцов) на основе значения из MouseEventArgs.

1 ответ

Я думаю, что у меня есть то, что вы ищете. Код ниже был новым проектом; упал два DataGridView контролирует на Form и наполнил их поддельными данными. Пожалуйста, смотрите ниже.

Public Class Form1

    Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

        'Remove the added handlers don't forget...
        For Each ctrl As Control In Me.Controls
            If TypeOf ctrl Is System.Windows.Forms.DataGridView Then
                RemoveHandler ctrl.MouseClick, AddressOf GetDataGridViewCellInfo
            End If
        Next

    End Sub

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        'Test Data ONLY'
        Me.DataGridView1.Columns.Add("FirstName", "First Name")
        Me.DataGridView1.Columns.Add("LastName", "Last Name")

        Me.DataGridView1.Rows.Add("Marilyn", "Manson")
        Me.DataGridView1.Rows.Add("Bobby", "Grants")
        Me.DataGridView1.Rows.Add("Shirley", "Thunderpots")

        'Add any handlers you need...
        For Each ctrl As Control In Me.Controls
            If TypeOf ctrl Is System.Windows.Forms.DataGridView Then
                AddHandler ctrl.MouseClick, AddressOf GetDataGridViewCellInfo
            End If
        Next

    End Sub

    Private Sub GetDataGridViewCellInfo(ByVal sender As Object, ByVal e As MouseEventArgs)
        Try
            Dim dgv As System.Windows.Forms.DataGridView = DirectCast(sender, System.Windows.Forms.DataGridView)
            If dgv IsNot Nothing AndAlso dgv.CurrentCell IsNot Nothing Then
                'The form was just so I could show it by the cell ONLY...
                Dim frm As New Form
                frm.StartPosition = FormStartPosition.Manual
                Dim RowHeight1 As Integer = DataGridView1.Rows(dgv.CurrentCell.RowIndex).Height
                Dim CellRectangle1 As Rectangle = dgv.GetCellDisplayRectangle(dgv.CurrentCell.ColumnIndex, dgv.CurrentCell.RowIndex, False)
                'Uncomment the two pieces at the end to show whatever you need at that point...
                CellRectangle1.X += dgv.Left '+ CellRectangle1.Width
                CellRectangle1.Y += dgv.Top '+ RowHeight1

                Dim DisplayPoint1 As Point = PointToScreen(New Point(CellRectangle1.X, CellRectangle1.Y))
                frm.Left = DisplayPoint1.X
                frm.Top = DisplayPoint1.Y
                frm.ShowDialog()
                frm.Dispose()

                MsgBox("Column Index: " & dgv.CurrentCell.ColumnIndex & " Row Index: " & dgv.CurrentCell.RowIndex & Environment.NewLine & "Cell Location = X:" & DisplayPoint1.X & " Y:" & DisplayPoint1.Y)
            End If

        Catch ex As Exception

        End Try

    End Sub

End Class

Я поместил небольшой комментарий в код. Я использовал Form чтобы населить, чтобы я знал, что это происходит в нужном месте. Вы можете увидеть изображения, отражающие код сверху.

PS Это опробовано и проверено

Другие вопросы по тегам