Inherits DataGridView_CellValidated

mercoledì 13 febbraio 2008 - 11.44

albedo Profilo | Junior Member

Ciao,
Chiedo venia per il titolo.

Dunque il mio problema è il seguente:
Ho una Classe copiata pari pari da msdn che mi permette di gestire la pressione del tasto 'Enter' in una DataGridView come se fosse la pressione del tasto 'Freccia Destra' e fin qui tutto ok.

Una volta digitato 'Enter' ,una query va a verificare se un determinato articolo è presente in anagrafica e se c'è riempie un altro campo della DataGridView, viceversa un messaggio avvisa l'utente che il codice non è associato ad alcun articolo e se si desidera crearlo; la stessa cosa accade se si digita enter lasciando la cella relativa al codice vuota.

Bene, in questi due ultimi casi vorrei che il focus tornasse sulla cella in cui va inserito il codice e vorrei che non fosse in alcun modo possibile lasciarla senza aver digitato un codice relativo ad un articolo esistente.

Se cerco di gestire il tutto mediante l'evento 'CellValidated', se la query non riporta alcun valore, mi lascia un campo vuoto e mi fa apparire il messaggio... etc etc... ma intanto la pressione del tasto enter è stata gestita ed il focus si sarà spostato di due celle in avanti.

Se provo a gestire il tutto direttamente dalla Classe, quindi dall'evento pressione del tasto 'Enter', tutto funziona a meraviglia, ma si presenta il problema che se l'utente digita il tasto 'Freccia Deestra' o 'Freccia Su', o 'Giù' o 'Sinistra' o il Tasto 'Tab', il focus si sposta, la cella rimane vuota e un record correrebbe il rischio di non venire registrato.

Allora avevo pensato di gestire l'Evento 'CellValidated' direttamente dalla Classe, ma proprio non so come si fa o se è possibile farlo.

Grazie

aiedail92 Profilo | Expert

Ciao

forse ti risulta più utile gestire l'evento CellValidating, in quanto quest'evento è scatenato PRIMA che la cella sia convalidata, quindi sei ancora in tempo ad annullare la convalida se non sono soddisfatti alcuni criteri. Quindi ti consiglio di intercettare l'evento CerrValidating, anche senza creare nessuna classe personalizzata, e lì inserire un blocco If Then nel quale controlli se devi rimanere sulla cella o no; e se devi annullare la convalida basta impostare la proprietà e.Cancel su False.

Successivamente nell'evento CellValidated inserisci il resto dol codice, ossia quello che riempie l'altro campo della DataGridView e fa tutto il resto.

In questo modo, poichè la non immissione dei dati annulla la convalida, il focus rimane sulla cella finchè non vengono inseriti dei dati validi, e l'evento validated non viene generato fino a che non viene portata a termine la convalida, ossia quando sono stati inseriti i dati corretti.

Se qualcosa non funziona, o hai qualche perplessità chiedi pure

Luca

albedo Profilo | Junior Member

>Ciao
>
>forse ti risulta più utile gestire l'evento CellValidating, in
>quanto quest'evento è scatenato PRIMA che la cella sia convalidata,
>quindi sei ancora in tempo ad annullare la convalida se non sono
>soddisfatti alcuni criteri. Quindi ti consiglio di intercettare
>l'evento CerrValidating, anche senza creare nessuna classe personalizzata,
>e lì inserire un blocco If Then nel quale controlli se devi rimanere
>sulla cella o no; e se devi annullare la convalida basta impostare
>la proprietà e.Cancel su False.
>
>Successivamente nell'evento CellValidated inserisci il resto
>dol codice, ossia quello che riempie l'altro campo della DataGridView
>e fa tutto il resto.
>
>In questo modo, poichè la non immissione dei dati annulla la
>convalida, il focus rimane sulla cella finchè non vengono inseriti
>dei dati validi, e l'evento validated non viene generato fino
>a che non viene portata a termine la convalida, ossia quando
>sono stati inseriti i dati corretti.
>
>Se qualcosa non funziona, o hai qualche perplessità chiedi pure
>
>
>Luca

Ciao, Luca.

Purtroppo non è così semplice.
Questa DatagridView, come dicevo, gestisce la pressione del tasto Enter come se si fosse premuto il tasto 'Freccia Destra', ma questo è subordinato alla condizione di esistenza di un record.
Ti scrivo il codice:

Dim key As Keys = keyData And Keys.KeyCode


cl = CurrentCell.ColumnIndex
rw = CurrentCell.RowIndex

If key = Windows.Forms.Keys.Enter Then
Select Case cl

Case Is = 1
CurrentCell = Item(2, rw)

Try
sql = "select FORNITORE from FORNITORI where ID_FOR=?"
Dim cmd As New OleDb.OleDbCommand(sql, cn)
cmd.Parameters.AddWithValue("ID_FOR", Item(1, rw).Value)
dr = cmd.ExecuteReader

If dr.HasRows And Item(11, rw).Value = 0 Then
Do While dr.Read
Item(2, rw).Value = dr.Item("FORNITORE")
Return Me.ProcessRightKey(keyData)
Loop

ElseIf dr.HasRows And Item(11, rw).Value > 0 Then
Do While dr.Read
Item(2, rw).Value = dr.Item("FORNITORE")
Loop
cmd = New OleDb.OleDbCommand("UPDATE VENDITE SET ID_FOR = " & Item(1, rw).Value & ", FORNITORE = '" & Item(2, rw).Value & "' WHERE ID_VEN = " & Item(11, rw).Value, cn)
dr = cmd.ExecuteReader
dr.Close()
Return Me.ProcessRightKey(keyData)
Else
MsgBox("ci scriverò qualcosa")
CurrentCell = Item(0, rw)
Return Me.ProcessRightKey(keyData)
End If

Catch
MsgBox("la cella non può contenere valori nulli")
CurrentCell = Item(0, rw)
Return Me.ProcessRightKey(keyData)
End Try


Per me andrebbe anche bene così, il fatto è che se per errore mi sposto tra le celle usando altri tasti in vece che Enter (I tasti direzionali o iltasto Tab) la query non parte o non aggiorna i record. Per questo chiedevo se fosse possibile implementare l'evento CellValidated direttamente nella classe.

Grazie

aiedail92 Profilo | Expert

Certo che si può fare

Quello che dicevo io era, invece che gestire il CellValidated, di gestire il CellValidating, ma da come hai scritto il codice il risultato è pressochè lo stesso. Per gestire gli eventi in una classe derivata la cosa migliore è eseguire l'override delle sub che richiamano l'evento.

Quindi per gestire l'evento Validated, tu inizi a scrivere overrides, poi appare un menu, tu scegli OnCellValidated e viene generato automaticamente il codice di base. Nota la chiamata a MyBase.OnCellValidated(e), senza la quale l'evento non viene generato.

Quindi tu davanti a OnCellValidated(e) aggiungi il codice per gestire l'evento Validated, così nella tua form tutto il procedimento resta invisibile, e in fondo la chiamata a OnCellValideted genera il vero e proprio evento CellValidated.

Luca

albedo Profilo | Junior Member

>Certo che si può fare
>
>Quello che dicevo io era, invece che gestire il CellValidated,
>di gestire il CellValidating, ma da come hai scritto il codice
>il risultato è pressochè lo stesso. Per gestire gli eventi in
>una classe derivata la cosa migliore è eseguire l'override delle
>sub che richiamano l'evento.
>
>Quindi per gestire l'evento Validated, tu inizi a scrivere overrides,
>poi appare un menu, tu scegli OnCellValidated e viene generato
>automaticamente il codice di base. Nota la chiamata a MyBase.OnCellValidated(e),
>senza la quale l'evento non viene generato.
>
>Quindi tu davanti a OnCellValidated(e) aggiungi il codice per
>gestire l'evento Validated, così nella tua form tutto il procedimento
>resta invisibile, e in fondo la chiamata a OnCellValideted genera
>il vero e proprio evento CellValidated.
>
>Luca

Grazie mille, Luca... sei stato davvero prezioso...

Posso approfittare della tua diusponibilità?

___________________________________________________________________

Protected Overrides Function ProcessDataGridViewKey( _
ByVal e As System.Windows.Forms.KeyEventArgs) As Boolean

cl = CurrentCell.ColumnIndex
rw = CurrentCell.RowIndex


If e.KeyCode = Keys.Enter Then
Try
Select Case cl
Case Is = 1
sql = "select FORNITORE from FORNITORI where ID_FOR=?"
Dim cmd As New OleDb.OleDbCommand(sql, cn)
cmd.Parameters.AddWithValue("ID_FOR", Item(1, rw).Value)
dr = cmd.ExecuteReader
If dr.HasRows Then
Do While dr.Read
CurrentCell = Item(2, rw)
Return Me.ProcessRightKey(e.KeyData)
Loop
dr.Close()
End If
End Select
Catch
End Try
End If

Return MyBase.ProcessDataGridViewKey(e)

End Function
___________________________________________________________________

Come mai al primo inserimento di un valore nella cella 1 la query fa il suo dovere, ma il focus non si sposta, poi se vado a cambiare il valore tutto funziona? Ovvero se modifico il valore della cella inserendo un codice cui non corrispondo record, il focus si sposta e poi, come nell'eesmpio precedente, se reinserisco un codice errato si comporta come dovrebbe (non sposta il focus)?

Grazie ancora.
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2023
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5