Home Page
Articoli
Tips & Tricks
News
Forum
Archivio Forum
Blogs
Sondaggi
Rss
Video
Utenti
Chi Siamo
Contattaci
Username:
Password:
Login
Registrati ora!
Recupera Password
Home Page
Stanze Forum
App. WinForms / WPF .NET
Inherits DataGridView_CellValidated
mercoledì 13 febbraio 2008 - 11.44
Elenco Threads
Stanze Forum
Aggiungi ai Preferiti
Cerca nel forum
albedo
Profilo
| Junior Member
59
messaggi | Data Invio:
mer 13 feb 2008 - 11:44
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
993
messaggi | Data Invio:
ven 15 feb 2008 - 20:29
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
59
messaggi | Data Invio:
sab 16 feb 2008 - 14:43
>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
993
messaggi | Data Invio:
sab 16 feb 2008 - 15:22
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
59
messaggi | Data Invio:
sab 16 feb 2008 - 22:27
>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.
Torna su
Stanze Forum
Elenco Threads
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 !