A mi me funciona perfectamente el evento
DataGridView.Click, al seleccionar múltiples celdas la propiedad
DataGridView.SelectedCells.Count devuelve el valor esperado y tú código funciona correctamente, así como si lo pruebo a hacer cuando se dispara el evento
DataGridView.CellClick. La deselección y selección de elementos ocurre ANTES de que se dispare el evento Click/Cellclick.
Supongo que lo que te ocurre será algún fallo de diseño de alguna versión anterior de los controles de WindowsForms que ya corrijieron en algún update de .NET Framework. Por si te sirve de algo, esto lo he probado en Visual Studio 2015 bajo .NET Framework 4.0, 4.5 y 4.6
Con respecto al código que has mostrado, si por el motivo que sea realmente no puedes recurrir a la propiedad
DataGridView.SelectedCells para especiificar lso valores de las celdas seleccionadas:
For Each cell As DataGridViewCell In Me.DataGridView1.SelectedCells
cell.Value = ...
Next cell
Entonces yo modificaría un poco el código para utilizar un tipo más versatil que una lista desordenada como estás usando... por ejemplo:
Dim cellsDict As New SortedDictionary(Of Integer, SortedSet(Of Integer))(Comparer(Of Integer).Default)
For Each cell As DataGridViewCell In DirectCast(sender, DataGridView).SelectedCells
If Not cellsDict.ContainsKey(cell.ColumnIndex) Then
cellsDict.Add(cell.ColumnIndex, New SortedSet(Of Integer))
End If
cellsDict.Item(cell.ColumnIndex).Add(cell.RowIndex)
Next cell
Dim sb As New StringBuilder()
For Each kvp As KeyValuePair(Of Integer, SortedSet(Of Integer)) In cellsDict
sb.AppendLine(String.Format("{0}, {{{1}}}", kvp.Key, String.Join(", ", kvp.Value)))
Next
MessageBox.Show(sb.ToString())
' sb.Clear()
' cellsDict.Clear()
Y entonces...
For Each kvp As KeyValuePair(Of Integer, SortedSet(Of Integer)) In cellsDict
For Each value As Integer In kvp.Value
Dim cell As DataGridViewCell = Me.DataGridView1.Rows(value).Cells(kvp.Key)
cell.Value = ...
Next value
Next kvp
¡Saludos!
Elektro el problema ye está solucionado ya que di con la solución, como ya comenté. De todos modos gracias por el interés, el esfuerzo y el aporte.
Te explico. El evento que utilicé no fue
DataGridView1_Click, si no DataGridView1_CellMouseClick.
Quizá no me expliqué bien o no me entendiste. Lo que yo me refería era esto.
PRIMERO: Arrastrar y seleccionar un grupo de celdas, entonces estas celdas por defecto quedan de color azul marino indicando que están seleccionadas.
SEGUNDO: Una vez hecho esto hago clic de nuevo sobre cualquier celda de las que han quedado seleccionadas, me devuelve las celdas que hay seleccionadas y luego relleno las celdas.
El evento
DataGridView1_Click, como dices si que devuelve el total las celdas seleccionadas, pero en el momento de arrastrar y soltar. Una vez seleccionadas al hacer clic la segunda vez en cualquiera de las celdas seleccionadas devuelve 1. Esto es porque al clicar de nuevo en UNA, todas se deseleccionan excepto la celda seleccionada la segunda vez y lógicamente devuelve 1.
Private Sub DataGridView1_Click(sender As Object, e As EventArgs) Handles DataGridView1.Click
MessageBox.Show(CStr(Me.DataGridView1.SelectedCells.Count))
End Sub
De modo que lo que pedía era primero seleccionar y que no ocurra nada, de nada.
Y en el segundo clic en cualquier celda seleccionada me devuelva la colección.Si aplicas el mismo código en
DataGridView1.CellClick, no devuelve la colección ni cuando seleccionas y cuando haces clic la segunda vez.
La solución ha sido obtener la colección desde el evento
MyDataGridView_CellMouseUp guardar la colección en un array y ahora si la dimensión del array es mayor de 1 entonces rellena las celdas de la colección desde el evento
DataGridView1_CellMouseClick:
Public Class Form1
Dim CellColection As New List(Of String)
Dim WithEvents MyDataGridView As New DataGridView
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Controls.Add(MyDataGridView)
With MyDataGridView
.Width = 406
.Height = 200
.ReadOnly = True
.ColumnCount = 3
.RowCount = 5
.Columns(0).Name = "Columna 1"
.Columns(1).Name = "Columna 2"
.Columns(2).Name = "Columna 3"
End With
End Sub
Private Sub MyDataGridView_CellMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles MyDataGridView.CellMouseClick
If e.Button = Windows.Forms.MouseButtons.Left Then
If CellColection.Count > 1 Then
For Each Item In CellColection
Dim Columna As Integer = CInt(Item.Substring(0, 2))
Dim Fila As Integer = CInt(Item.Substring(2, 2))
If String.IsNullOrWhiteSpace(CStr(MyDataGridView.Item(Columna, Fila).Value)) Then
MyDataGridView.Item(Columna, Fila).Value = String.Format("{0:00}{1:00}", Columna, Fila)
Else
MyDataGridView.Item(Columna, Fila).Value = ""
End If
Next
End If
End If
End Sub
Private Sub MyDataGridView_CellMouseUp(sender As Object, e As DataGridViewCellMouseEventArgs) Handles MyDataGridView.CellMouseUp
'Obtiene la colección
CellColection.Clear()
For Each Cell As DataGridViewCell In Me.MyDataGridView.SelectedCells
CellColection.Add(String.Format("{0:00}{1:00}", Cell.ColumnIndex, Cell.RowIndex))
Next
End Sub
End Class
Como podrás comprobar al hacer clic la primera vez y arrastrar no ocurrirá nada, pero al hacer clic de nuevo en cualquiera de las cedas seleccionadas éstas se rellenan.
Así que selecciono un grupo de celdas sin que ocurra nada, ¿que no me gustan? vuelvo a seleccionar otras, cuando estoy de acuerdo, hago clic sobre cualquiera de las celdas seleccionadas y entonces se rellenan.
Saludos.