Как получить местоположение ячейки в 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 Это опробовано и проверено