Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ComboBoxCell en DataGridView

488 views
Skip to first unread message

pev

unread,
Aug 2, 2008, 3:48:00 AM8/2/08
to
Hola A Todos!!!

Estoy tratando de poner una DataGridViewComboBoxCell en una DataGridView
pero cuando la fila y la columna son iguales se cae entregando el siguiente
error:

"Operation is not valid because it results in a reentrant call to the
SetCurrentCellAddressCore function."

Alguien sabe como solucionar este problema?

Muchas Gracias.

Atte.
pev

SoftJaén

unread,
Aug 2, 2008, 5:51:48 AM8/2/08
to
"pev" escribió:

>
> Estoy tratando de poner una DataGridViewComboBoxCell en una DataGridView
> pero cuando la fila y la columna son iguales se cae entregando el
> siguiente error:
>
> "Operation is not valid because it results in a reentrant call to the
> SetCurrentCellAddressCore function."
>
> Alguien sabe como solucionar este problema?

Sin saber lo que estás haciendo, y cómo lo estás haciendo, para que obtengas
ese mensaje de error, es un poco complicado intentar solucionar el problema.
¿Qué quieres decir «cuando la fila y la columna son iguales»?

Cuando se obtiene ese error, generalmente es debido a que estás ejecutando
el código fuente en un evento que se desencadena cada vez que se modifica,
explícita o implícitamente, la propiedad «CurrentCell» del control
DataGridView, por lo que el evento no pararía de desencadenarse. Si éste es
tu caso, deberás de procurar establecer el valor de la propiedad
«CurrentCell» fuera de cualquier evento del control DataGridView que
conlleve llamadas reentrantes al mismo procedimiento de evento.

Insisto en que no quiero decir que tú expresamente establezcas el valor de
la propiedad «CurrentCell». Puede darse el caso que el código fuente que se
está ejecutando, modifique indirectamente el valor de la mencionada
propiedad.

--
Enrique Martínez
[MS MVP - VB]

Nota informativa: La información contenida en este mensaje, así como el
código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin
garantías de ninguna clase, y no otorga derecho alguno. Usted asume
cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o
sugerido en el presente mensaje.

SoftJaén

unread,
Aug 2, 2008, 6:02:12 AM8/2/08
to
> ... que conlleve llamadas reentrantes al mismo procedimiento de evento.

Quería decir que NO CONLLEVE llamadas reentrantes al mismo procedimiento de
evento.

--

pev

unread,
Aug 2, 2008, 8:35:01 PM8/2/08
to
"¿Qué quieres decir «cuando la fila y la columna son iguales»?"

Cuando me posiciono en la fila 3,columna 3 de la grilla.

en todo caso estube buscando en internet y este error es bastante
recurrente......

Otra Vez: ¿alguien que le hayya ocurrido lo ha solucionado?

Gracias.
Atte.
pev

SoftJaén

unread,
Aug 2, 2008, 11:03:41 PM8/2/08
to
"pev" escribió:

>
> Cuando me posiciono en la fila 3,columna 3 de la grilla.

Porque te posiciones en dicha celda, no es motivo para que obtengas el error
que nos comentas. En condicones normales no tienes por qué obtener el error
"La operación no es válida porque origina una llamada reentrante a la
función SetCurrentCellAddressCore" cuando te posicionas en la fila 3 columna
3, o en la fila 5 columna 5, o en cualquier otra celda del control
DataGridView.

> en todo caso estube buscando en internet y este error es bastante
> recurrente......

Es bastante frecuente en aquellos proyectos donde el código fuente
indirectamente está efectuando de una manera constante llamadas a la función
SetCurrentCellAddressCore. Si deseas provocar el error, simplemente tienes
que seleccionar la celda actual en el evento «RowEnter» del control
DataGridView de la siguiente manera:

Private Sub DataGridView1_RowEnter(ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs) _
Handles DataGridView1.RowEnter

If Me.DataGridView1.CurrentCell Is Nothing Then Return

Me.DataGridView1.CurrentCell = _
Me.DataGridView1.Rows(3).Cells(3)

End Sub

Pero no se produce simplemente porque te posiciones en la fila 3 columna 3,
porque también sucede cuando te posiciones en cualquier otra celda.

> Otra Vez: ¿alguien que le haya ocurrido lo ha solucionado?

A mí no me ha ocurrido, pero en mi anterior mensaje ya te he comentado lo
que tienes que procurar evitar para que no se produzca dicho error: procurar

establecer el valor de la propiedad «CurrentCell» fuera de cualquier evento

del control DataGridView que no conlleve llamadas reentrantes al mismo
procedimiento de evento.

Continuando con el ejemplo anterior, evitaríamos el error ejecutando el
código de la siguiente manera:

Private Sub DataGridView1_RowEnter(ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs) _
Handles DataGridView1.RowEnter

If Me.DataGridView1.CurrentCell Is Nothing Then Return

' Eliminamos la selección de la celda actual.
'
Me.DataGridView1.Rows(e.RowIndex).Selected = False

' Cuando seleccionemos una fila, quedar seleccionada
' la celda correspondiente a su cuarta columna.
'
Dim textBoxCell As DataGridViewTextBoxCell = _
TryCast(Me.DataGridView1.Item(3, e.RowIndex), _
DataGridViewTextBoxCell)

textBoxCell.Selected = True

End Sub

Pero, en fín, como todavía no has dicho lo que estás haciendo y cómo lo
estás haciendo, pues ignoro cómo te puedo ayudar para evitar el error.

pev

unread,
Aug 3, 2008, 2:19:02 PM8/3/08
to
Este es el código de mi proyecto.......

Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.DataGridView1.Rows.Add(4)
End Sub

Private Sub DataGridView1_CellEnter(ByVal sender As Object, ByVal e As
System.Windows.Forms.DataGridViewCellEventArgs) Handles
DataGridView1.CellEnter
Dim COMBO = New DataGridViewComboBoxCell
Debug.WriteLine(e.ColumnIndex.ToString & " " & e.RowIndex.ToString)
If (e.ColumnIndex = 3) Then
DataGridView1.Item(e.ColumnIndex, e.RowIndex) = COMBO
End If
End Sub
End Class

Y este es el resultado:

0 0
0 0
1 0
2 0
3 0
3 1
3 2
3 3
A first chance exception of type 'System.InvalidOperationException' occurred
in System.Windows.Forms.dll

y me da el error ya conocido.

Saludos
pev.

SoftJaén

unread,
Aug 4, 2008, 12:51:20 AM8/4/08
to
"pev" escribió:

> Private Sub DataGridView1_CellEnter( ...)


>
> Dim COMBO = New DataGridViewComboBoxCell
> Debug.WriteLine(e.ColumnIndex.ToString & " " & e.RowIndex.ToString)
> If (e.ColumnIndex = 3) Then
> DataGridView1.Item(e.ColumnIndex, e.RowIndex) = COMBO
> End If
> End Sub


Tal y como te indiqué en mis anteriores mensajes, es normal que obtengas el
error que estás obteniendo, porque en el evento «CellEnter» le estás
indicando que se sitúe en una determinada celda cuando el valor de
«ColumnIndex» sea igual a 3, por lo que el evento «CellEnter» no pararía de
ejecutarse, de ahí que obtengas la excepción "La operación no es válida

porque origina una llamada reentrante a la función

SetCurrentCellAddressCore", y se produce cuando entras en la celda 3 - 3,
porque así se lo estás indicando:

> If (e.ColumnIndex = 3) Then
> DataGridView1.Item(e.ColumnIndex, e.RowIndex) = COMBO
> End If

Le estás diciendo que cuando el índice de la columna sea 3 se establezca en
la celda situada en la intersección de la fila 3 y la columna 3, que
precisamente es donde se encuentra situada la celda actual del control
DataGridView, es decir, el valor devuelto por la propiedad CurrentCell, por
tanto, como lo estás ejecutando dentro del evento «CellEnter», éste evento
no pararía de ejecutarse, de ahí que obtengas el error.

Si al código le quitaras

If (e.ColumnIndex = 3) Then

Entonces obtendrías el error cada vez que seleccionaras cualquier celda.

La solución pasa por ejecutar el código fuera de cualquier evento que no
produzca llamadas reentrantes al mismo procedimiento de evento que está
ejecutando el código, tal y como así te indiqué en mi primera respuesta.

pev

unread,
Aug 4, 2008, 1:59:00 PM8/4/08
to
y entonces por qué no da el error en las demás filas de la misma columna?
Como te mostré en un post anterior este es el resultado:

(columna, fila
0, 0
0, 0
1, 0
2, 0
3, 0 (columna=3, fila=0) no pasa nada
3, 1 (columna=3, fila=1) no pasa nada
3, 2 (columna=3, fila=2) no pasa nada
3, 3 (columna=3, fila=0) SOLO EN ESTA CELDA SE CAE!!!!!!!

A first chance exception of type 'System.InvalidOperationException' occurred
in System.Windows.Forms.dll

Gracias.
pev

SoftJaén

unread,
Aug 5, 2008, 1:37:52 AM8/5/08
to
"pev" preguntó:

> y entonces por qué no da el error en las demás filas de la misma columna?

¡Jeje! Seguramente, no he sabido explicarme bien.

¡Vamos a ver! Ejecuta el código de la siguiente manera, y observarás que en
todas las celdas obtendrás el mismo error. ¡Es más! Vas a obtener el error
una vez que pulses F5, es decir, cuando inicies la ejecución del código en
el IDE de Visual Studio:

Private Sub DataGridView1_CellEnter( _


ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs) _

Handles DataGridView1.CellEnter


Dim COMBO = New DataGridViewComboBoxCell
Debug.WriteLine(e.ColumnIndex.ToString & " " & e.RowIndex.ToString)

' If (e.ColumnIndex = 3) Then
DataGridView1.Item(e.ColumnIndex, e.RowIndex) = COMBO
' End If

End Sub

Una vez que observes que obtienes el error nada más iniciar la depuración
del proyecto, elimina los comentarios de las líneas If ... End If, y
observarás que entonces sólo se produce la excepción cuando seleccionas la
celda 3-3, porque TÚ MISMO LE ESTÁS DICIENDO QUE ASÍ SEA:

If (e.ColumnIndex = 3) Then

Es decir, cuando el índice de la columna sea 3 ejecuta

DataGridView1.Item(e.ColumnIndex, e.RowIndex) = COMBO

La excepción ÚNICAMENTE SE PRODUCIRÁ cuando el índice de la celda sea Fila
3, Columna 3, que se corresponde con la celda que ACTUALMENTE se encuentra
seleccionada, es decir, cuando el valor de la propiedad «CurrentCell» sea
ColumnIndex = 3 y RowIndex = 3; no se producirá el error cuando el índice de
la fila (RowIndex) sea distinto de 3, aunque el índice de la columna sea 3,
ya que le estás indicando el valor de la variable objeto COMBO, que tal y
como se encuentra definida en el evento «CellEnter», el índice de sus
propiedades RowIndex y ColumnIndex son -1, por tanto, ¿donde deseas que se
sitúe la celda situada en la intersección de la columna y la fila con los
índices -1?

Realmente no sé el motivo de utilizar la propiedad «Item» con un valor
«DataGridViewComboBoxCell». Si tu intención es seleccionar una celda en
concreto, para eso está la propiedad «CurrentCell» del control DataGridView.
Por ejemplo, en el mismo evento «CellEnter» puedes ejecutar lo siguiente,
aunque poco sentido tiene ejecutarlo en dicho evento:

Private Sub DataGridView1_CellEnter( _


ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs) _

Handles DataGridView1.CellEnter

If Me.DataGridView1.CurrentCell Is Nothing Then Return

' Eliminamos la selección de la celda actual.
'
Me.DataGridView1.Rows(e.RowIndex).Selected = False

' Cuando seleccionemos una fila, quedará seleccionada


' la celda correspondiente a su cuarta columna.
'
Dim textBoxCell As DataGridViewTextBoxCell = _
TryCast(Me.DataGridView1.Item(3, e.RowIndex), _
DataGridViewTextBoxCell)

If textBoxCell IsNot Nothing Then
textBoxCell.Selected = True
End If

End Sub

Digo que tiene poco sentido, porque estarás seleccionando la misma celda que
actualmente se encuentra seleccionada. Este código es para ejecutarlo fuera
del evento «CellEnter», porque este evento se produce cuando cambia el valor
de la celda actual, o cuando el control DataGridView recibe el foco de
entrada.

pev

unread,
Aug 5, 2008, 10:53:01 AM8/5/08
to
> ¡Es más! Vas a obtener el error
> una vez que pulses F5, es decir, cuando inicies la ejecución del código en
> el IDE de Visual Studio:

Eso es verdad, ya que la primera celda que toma la grilla al iniciar es la
0,0 (condición que puse en el primer post "cuando la fila y la columna son
iguales, se cae".

Este es el codigo que probé ahora:

Public Class Form1

Private Sub DataGridView1_CellEnter( _
ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellEnter

Dim COMBO = New DataGridViewComboBoxCell

Try


Debug.WriteLine(e.ColumnIndex.ToString & " " &
e.RowIndex.ToString)
' If (e.ColumnIndex = 3) Then
DataGridView1.Item(e.ColumnIndex, e.RowIndex) = COMBO
' End If

Catch ex As Exception
Debug.WriteLine(ex.Message.ToString.Trim)
Finally
End Try
End Sub

Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles
Me.Load

Me.DataGridView1.Rows.Add(4)

End Sub

End Class

Y este es su resultado:


0 0


A first chance exception of type 'System.InvalidOperationException' occurred
in System.Windows.Forms.dll

La operación no es válida porque origina una llamada reentrante a la función

SetCurrentCellAddressCore.
0 0
0 0


A first chance exception of type 'System.InvalidOperationException' occurred
in System.Windows.Forms.dll

La operación no es válida porque origina una llamada reentrante a la función

SetCurrentCellAddressCore.


1 0
2 0
3 0

0 1
1 1


A first chance exception of type 'System.InvalidOperationException' occurred
in System.Windows.Forms.dll

La operación no es válida porque origina una llamada reentrante a la función

SetCurrentCellAddressCore.
2 1
3 1
0 2
1 2
2 2


A first chance exception of type 'System.InvalidOperationException' occurred
in System.Windows.Forms.dll

La operación no es válida porque origina una llamada reentrante a la función

SetCurrentCellAddressCore.
3 2


0 3
1 3
2 3

3 3


A first chance exception of type 'System.InvalidOperationException' occurred
in System.Windows.Forms.dll

La operación no es válida porque origina una llamada reentrante a la función

SetCurrentCellAddressCore.


Como puedes seguir observando el error sólo se produce cuando la fila y
columna son iguales.

¿Existe solución para este problema?

Atte.
pev

SoftJaén

unread,
Aug 5, 2008, 11:28:07 AM8/5/08
to
"pev" escribió:

> Como puedes seguir observando el error sólo se produce cuando
> la fila y columna son iguales.

¡Yo, me rindo! ¡Me doy por vencido! :-(

> ¿Existe solución para este problema?

Sí, no efectuar llamadas reentrantes. No sé si es la tercera o cuarta vez
que te digo que procures establecer el valor de la propiedad «CurrentCell»
fuera de cualquier evento del control DataGridView que no conlleve llamadas
reentrantes al mismo procedimiento de evento.

Pero, ¡nada! Como parece ser que te empeñas en utilizar el evento
«CellEnter» para establecer el valor de la propiedad «Item», no pararás de
obtener la excepción «la operación no es válida porque origina una llamada
reentrante a la función SetCurrentCellAddressCore».

Ignoro si existe una solución para lo que pretendes hacer sin obtener la
excepción comentada.

SoftJaén

unread,
Aug 5, 2008, 1:30:42 PM8/5/08
to
> ¿Existe solución para este problema?

La única solución que veo por ahora para no obtener la excepción, pasa por
especificar expresamente la propiedad «Value» de la variable objeto COMBO a
la propiedad «Value» de la propiedad «Item» del control DataGridView:

Private Sub DataGridView1_CellEnter( _
ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellEnter

Dim COMBO = New DataGridViewComboBoxCell

Debug.WriteLine(e.ColumnIndex.ToString & " " & e.RowIndex.ToString)

If (e.ColumnIndex = 3) Then

DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value = _
COMBO.Value
End If

End Sub

Pero, ¡claro! Como la variable objeto COMBO no tiene ningún valor, el valor
de la celda será «Nothing». Su tuviera un valor adecuado a los elementos
existentes en la columna tipo ComboBox, le podrías asignar un valor a la
propiedad «Value» de cualquier elemento existente:

COMBO.Value = "Valor elemento existente en la columna ComboBox."

Por ahora, no veo otra solución, salvo que digas claramente qué es lo que
realmente deseas hacer.

0 new messages