2009-06-08 1 views
8

Sto utilizzando il controllo DataGridView per la lettura e la scrittura di un file XML tramite la serializzazione XML.DataGridView -Value non viene salvato se la selezione non viene persa da una cella

Ho un problema come spiegato di seguito:

  1. ho letto un file XML e popolano i controlli DataGridView con l'oggetto deserializzato.
  2. Aggiorna tutti i valori su DataGridView sulla cella.
  3. Scelgo l'opzione Salva con nome senza perdere l'attenzione sull'ultima cella.

Dopo questo, il valore della cella particolare non viene aggiornato. Se sposto intenzionalmente lo spostamento (ad esempio clicco su un'altra cella sulla stessa griglia) il valore viene aggiornato.

Qualcuno può suggerire una soluzione per questo?

risposta

4

Se ho capito bene, una cella è in modalità di modifica e stai cercando di interrompere la modifica a livello di codice e passare il valore all'origine dati sottostante?

Io sto usando un approccio un po ' "sporco" per farlo in una delle mie applicazioni:

if (dataGridView1.CurrentCell.IsInEditMode)  
{  
    int y = dataGridView1.CurrentCellAddress.Y;  
    int x = dataGridView1.CurrentCellAddress.X;  
    if (y > 0)  
     dataGridView1.CurrentCell = dataGridView1.Rows[y - 1].Cells[x];  
    else  
     dataGridView1.CurrentCell = dataGridView1.Rows[y + 1].Cells[x];  
    dataGridView1.CurrentCell = dataGridView1.Rows[y].Cells[x];  
} 

Quel pezzo di codice prima controlla se la cella corrente è in modalità di modifica. Quindi cambia la cella corrente a livello di programmazione (o nella riga precedente o nella riga successiva nel caso in cui ci troviamo nella prima riga). Successivamente, ripristina la selezione corrente della cella.

Si chiamerà questo codice nel gestore "File Salva con nome".

+0

Grazie per la soluzione. –

+0

Contento di aver potuto aiutare. Potresti contrassegnarlo come soluzione accettata? –

15

È perché il valore della cella modificato non è impegnato in DataSource finché non viene convalidato, cosa che accade quando la cella perde lo stato attivo. Se si vuole impegnare subito delle modifiche, è possibile gestire l'evento CurrentCellDirtyStateChanged, e chiamare il metodo CommitEdit nel gestore:

void dataGridView1_CurrentCellDirtyStateChanged(object sender, 
    EventArgs e) 
{ 
    if (dataGridView1.IsCurrentCellDirty) 
    { 
     dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit); 
    } 
} 
+1

Questo ha funzionato incredibilmente, grazie! –

+2

Funziona perfettamente con il mio metodo di salvataggio. Grazie!! –

+0

Anche questo ha funzionato molto bene con me. Grazie – Abdullah

0

È possibile ottenere il valore di una cella che non è ancora impegnata con la proprietà EditedFormattedValue per la cella corrente, come sotto

dataGridView1.CurrentCell.EditedFormattedValue 
16

il modo migliore (anche se veloce e sporco) è assegnare il valore CurrentCell a Nothing.

Per esempio, nel metodo salvare, effettuate:

dgvMyGrid.CurrentCell = Nothing 

e poi procedere ulteriormente.

+0

Ho la stessa situazione e la tua soluzione ha funzionato perfettamente. Mi sto ancora chiedendo come sia possibile. – JPReddy

0

Ho avuto la stessa situazione e utilizzavo anche i tasti di scelta rapida per il pulsante di salvataggio per il salvataggio dei valori della griglia. Quando faccio clic sul pulsante Salva, il focus viene perso da DGV e quindi il valore della cella viene commesso, ma quando uso i tasti di scelta rapida, l'attenzione non viene persa da DGV, quindi non si commette il valore della cella.

Dopo aver esaminato la risposta di Amit Karmakar per curiosità ho provato quella risposta e ha funzionato. Per scoprire maggiori dettagli sono andato in debugging del DGV e ho scoperto che è davvero la stessa cosa di commitedit che in qualche modo non funziona se lo usi nel pulsante di salvataggio clic.

Quando impostiamo CurrentCell di DGV su null, prima di impostarlo su null DGV ottiene prima il valore modificato e lo inserisce nel valore di cella e quindi imposta CurrentCell REFERENCE su null. Qui non significa che sta impostando la cella DGV sottostante su null. Quindi questo funziona perfettamente per il problema di cui sopra.

Nota: Questa soluzione potrebbe non funzionare perfettamente quando hai la convalida eventi per la cellula e se l'utente inserisce i dati non validi che non superano la convalida. In questo caso anche l'impostazione della cella corrente su null non riesce poiché non può spingere il valore nella cella.

ho dato questa spiegazione come ho sollevato questione su Amit Karmakar risposta chiedendo come può essere possibile. Ho pensato che potesse essere d'aiuto ad altri, quindi ho lasciato cadere questa spiegazione come risposta.

0

OK, questo è brutto ma funziona per ottenere le modifiche finali dalla rete senza dover spostare in un'altra riga:

With DataGridView1 
    .DataSource = Nothing 
    .DataSource = gridDataTable 
    Dim changedFoo As DataTable = gridDataTable.GetChanges 
End With 

Tuttavia mi piace ancora la risposta da Amit Karmakar il migliore. Ho aggiunto il 'DataGridView1.CurrentCell = Nothing' alla manifestazione DataGridView1 LostFocus.