Principale utente con più risposte
gestire pressione tasti datagridview visual c#

Domanda
-
Salve, grazie al Vostro Forum ho potuto sviluppare una piccola applicazione contenente un datagridview che visualizza dati da un database sql server.
Volevo sapere se era possibile riprodurre l'evento di pressione dei tasti Ctrl + ' per poter copiare il contenuto della cella superiore rispetto a quella selezionata del datagridview, senza fare copia e incolla, così come funziona con Excel.
Un saluto, Nando!
Risposte
-
Certo, ti basta intercettare l'evento KeyUp della griglia e giocare con gli indici di riga:
private void dataGridView1_KeyUp(object sender, KeyEventArgs e) { if (e.KeyValue == 219 && e.Modifiers == Keys.Control) // Combinazione CTRL+' { int prevRow = dataGridView1.CurrentCell.RowIndex - 1; if (prevRow >= 0) { var value = dataGridView1[dataGridView1.CurrentCell.ColumnIndex, prevRow].Value; dataGridView1.CurrentCell.Value = value; } } }
Sempre a disposizione.
Marco Minerva, marco.minerva@gmail.com- Proposto come risposta Marco MinervaMVP, Moderator martedì 29 novembre 2011 08:37
- Contrassegnato come risposta mana973 mercoledì 30 novembre 2011 11:55
-
Allora prova a salvarti l'indice di riga e colonna della cella, quindi a reimpostare esplicitamente quei valori:
var columnIndex = dataGridView1.CurrentCell.ColumnIndex; var rowIndex = dataGridView1.CurrentCell.RowIndex; (dataGridView1.DataSource as BindingSource).ResetBindings(false); dataGridView1.CurrentCell = dataGridView1[columnIndex, rowIndex];
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom- Contrassegnato come risposta mana973 mercoledì 30 novembre 2011 11:39
-
17 è il codice del tasto Control, quindi l'evento KeyUp di dice che è stato rilasciato quel tasto (in pratica, quando rilasci la tua combinazione di tasti, vengono generati due eventi KeyUp, uno per ogni tasto rilasciato). Puoi aggirare il problema utilizzando l'evento KeyDown al posto di KeyUp: ti basta cambiare l'handler dell'evento, il codice rimane lo stesso.
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom- Contrassegnato come risposta mana973 mercoledì 30 novembre 2011 11:39
-
Ho risolto così: private void tArchivioDataGridView_KeyDown(object sender, KeyEventArgs e) { if ((e.KeyCode == Keys.Z) && (e.Modifiers == Keys.Control)) // Combinazione CTRL+S { int prevRow = tArchivioDataGridView.CurrentCell.RowIndex - 1; if (prevRow >= 0) { var value = tArchivioDataGridView[tArchivioDataGridView.CurrentCell.ColumnIndex, prevRow].Value; tArchivioDataGridView.CurrentCell.Value = value; var columnIndex = tArchivioDataGridView.CurrentCell.ColumnIndex; var rowIndex = tArchivioDataGridView.CurrentCell.RowIndex; (tArchivioDataGridView.DataSource as BindingSource).ResetBindings(false); tArchivioDataGridView.CurrentCell = tArchivioDataGridView[columnIndex, rowIndex]; } } else if (e.KeyCode==Keys.Escape) { int selectindex = tArchivioDataGridView.CurrentCell.RowIndex; tArchivioDataGridView.Rows.RemoveAt(selectindex); } }
Grazie!- Contrassegnato come risposta Irina Turcu mercoledì 30 novembre 2011 17:05
Tutte le risposte
-
Certo, ti basta intercettare l'evento KeyUp della griglia e giocare con gli indici di riga:
private void dataGridView1_KeyUp(object sender, KeyEventArgs e) { if (e.KeyValue == 219 && e.Modifiers == Keys.Control) // Combinazione CTRL+' { int prevRow = dataGridView1.CurrentCell.RowIndex - 1; if (prevRow >= 0) { var value = dataGridView1[dataGridView1.CurrentCell.ColumnIndex, prevRow].Value; dataGridView1.CurrentCell.Value = value; } } }
Sempre a disposizione.
Marco Minerva, marco.minerva@gmail.com- Proposto come risposta Marco MinervaMVP, Moderator martedì 29 novembre 2011 08:37
- Contrassegnato come risposta mana973 mercoledì 30 novembre 2011 11:55
-
Ciao Marco, grazie per la soluzione, era proprio quello che chiedevo.
Adesso però ho notato che durante l'inserimento di un nuovo record nel datagrid, se immetto i dati manualmente tutto funziona, cioè all'immisione del primo dato nella prima cella subito mi inerisce la nuova riga sottostante e alla pressione del tasto salva (update) mi aggiorna il dataset collegato al datagrid, invece quando immetto con la combinazione dei tasti CTRL+' se provo a salvare (aggiornare) le modifiche, la riga che ho appena inserito scompare il contenuto appena immesso come per magia, ma il tutto se esco e faccio ripartire l'applicazione è aggiornato. Anche se dopo aver aggiunto nella nuova riga dei dati in varie celle e poi mi sposto al di sopra per modificare un'altra cella, il contenuto appena immesso scompare come per magia, ma se clicco sulla riga ricompaiono i dati immessi....
Boh, forse bisogna migliorare il codice, o forse rimane il focus sulla cella superiore?
Aiuto!
- Proposto come risposta Marco MinervaMVP, Moderator mercoledì 30 novembre 2011 14:14
-
Non conosco come è strutturato il tuo programma, ma forse quello che devi fare è forzare l'aggiornamento del DataSet quando si preme la combinazione CTRL+', quindi effettuare nuovamente il bind con la griglia: in questo modo, i dati dovrebbero essere sincronizzati.
Marco Minerva, marco.minerva@gmail.com -
Il mio programma è strutturato con una form al cui interno ha un toobar predefinito e un datagridview che attinge i dati daun databindingsource che a sua volta da un dataset (semplicissimo). Il fatto strano è che quando inserisco i dati manualmente quando lascio la cella del datagrid subito si imposta una nuova riga, mentre se inserisco i dati con la combinazione CTRL +' non si aggiunge la nuova riga sottostante per un nuovo inserimento.
Se la soluzione fosse quella da te suggerita, mi puoi postare il codice, questo è il mio:
public
partial class FInserimento : Form
{
public
FInserimento()
{
InitializeComponent();
}
private void FInserimento_Load(object sender, EventArgs
e)
{
// TODO: questa riga di codice carica i dati nella tabella 'archivioDataSet.TUffici'. È possibile spostarla o rimuoverla se necessario.
this.tUfficiTableAdapter.Fill(this
.archivioDataSet.TUffici);
// TODO: questa riga di codice carica i dati nella tabella 'archivioDataSet.TArchivio'. È possibile spostarla o rimuoverla se necessario.
this.tArchivioTableAdapter.Fill(this
.archivioDataSet.TArchivio);
}
private void tArchivioBindingNavigatorSaveItem_Click(object sender, EventArgs
e)
{
this
.Validate();
this
.tArchivioBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this
.archivioDataSet);
}
private void toolStripButton1_Click(object sender, EventArgs
e)
{
Application
.Exit();
}
private void tArchivioDataGridView_KeyUp(object sender, KeyEventArgs
e)
{
if(e.KeyValue == 219 && e.Modifiers == Keys.Control)
// Combinazione CTRL+'
{
int
prevRow = tArchivioDataGridView.CurrentCell.RowIndex - 1;
if
(prevRow >= 0)
{
var
value = tArchivioDataGridView[tArchivioDataGridView.CurrentCell.ColumnIndex, prevRow].Value;
tArchivioDataGridView.CurrentCell.Value = value;
}
}
}
}
}
-
-
-
Hai provato a ripetere il bind con la sorgente, ovvero rifare la stessa operazione che fai in fase di inizializzazione? Se il DataSet è aggiornato, rifacendo il bind, dovresti rivedere immediatamente tutti i dati inseriti.
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom -
Il problema si verifica quando inserisco un valore in una colonna di un record nuovo, se mi sposto nell'altra colonna non si aggiunge il nuovo record sottostante, come si verifica quando inserisco i dati manualmente.
Cioè è come se nel momento in cui si lascia il focus della prima colonna dopo aver inserito il testo, non capisce di inserire il nuovo record sotto immediatamente.
-
-
-
Perché, nel momento in cui inizi a digitare qualcosa, la cella entra in modalità di editing, ed il comportamento di default della griglia, quando si fa in fase di editing, è di inserire un nuovo record sottostante. Invece, se utilizzi CTRL+', non vai in edit, infatti il valore viene inserito dal codice (non sei tu che lo digiti).
Per questo motivo ti consigliavo di provare a creare a mano una nuova riga.
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom -
-
-
-
-
-
-
Il metodo newrow non lo trovo, invece dataGridView1.Rows.Add() mi restiruisce l'errore.
Stavo pensando se io chiamo l'evento CellBeginEdit del datagridview si può ottenere lo stesso risultato, però con la pressione dei tasti CTRL+'.
Mi sa di n o vero?
-
E invece hai provato ad aggiungere la riga al DataTable che è in bind con la DataGridView?
L'evento CellBeginEdit, se premi la combinazione CTRL+', non viene generato perché, come ti ho detto prima, la cella non entra in modalità di editing.
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom -
-
Sì, forse ti stai un po' perdendo :-)Allora, cerchiamo di fare il punto della situazione: se tu usi CTRL+' per copiare il contenuto della riga precedente, non entri in modalità di editing, quindi di fatto non viene aggiunta una nuova riga alla griglia. Per forzare l'aggiornamento della griglia, quando intercetti la pressione di CTRL+', puoi provare ad utilizzare l'istruzione
(dataGridView1.DataSource as BindingSource).ResetBindings(false);
Che forza il refresh della sorgente dati.
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom -
-
Giocando con gli indici di riga e gli eventi di spostamento all'interno della griglia, dovresti riuscire facilmente a capire quando è la prima volta che premi CTRL+' all'interno di una riga (e si tratta dell'ultima riga della griglia), quindi puoi decidere se rileggere la fonte dati oppure no, con l'istruzione che ti ho indicato prima.
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom -
private void dataGridView1_KeyUp(object sender, KeyEventArgs e) { if (e.KeyValue == 219 && e.Modifiers == Keys.Control) // Combinazione CTRL+' { int prevRow = dataGridView1.CurrentCell.RowIndex - 1; if (prevRow >= 0) { var value = dataGridView1[dataGridView1.CurrentCell.ColumnIndex, prevRow].Value; dataGridView1.CurrentCell.Value = value;
(dataGridView1.DataSource as BindingSource).ResetBindings(false); } } }
Buongiorno Marco, grazie sempre per il Tuo aiuto, piano piano sto riuscendo a venirne fuori.Adesso però quando forzo l'aggiornamento e inserisco nel nuovo record in qualsiasi cella, mi inserisce la nuova riga sottostante, ma il focus si riporta sul record dove stavo inserendo sulla prima colonna.
Come faccio a fargli capire di rimanere nella colonna dove ho inserito il nuovo valore?
-
Ciao!Prima di richiamare il metodo ResetBindings, salva in una variabile il valore di dataGridView1.CurrentCell, quindi riassegnalo dopo l'aggiornamento. Ovvero:
var currentCell = dataGridView1.CurrentCell; (dataGridView1.DataSource as BindingSource).ResetBindings(false); dataGridView1.CurrentCell = currentCell;
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom -
Ho provato ma non funziona, mi restituisce il seguente errore "La cella specificata non appartiene a questo controllo DataGridView."
Quando esegue l'istruzione (dataGridView1.DataSource as BindingSource).ResetBindings(false); il valore current cell diventa
"currentCell = {DataGridViewTextBoxCell { ColumnIndex=1, RowIndex=-1 }}" perchè mi imposta il rowindex a -1
-
Allora prova a salvarti l'indice di riga e colonna della cella, quindi a reimpostare esplicitamente quei valori:
var columnIndex = dataGridView1.CurrentCell.ColumnIndex; var rowIndex = dataGridView1.CurrentCell.RowIndex; (dataGridView1.DataSource as BindingSource).ResetBindings(false); dataGridView1.CurrentCell = dataGridView1[columnIndex, rowIndex];
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom- Contrassegnato come risposta mana973 mercoledì 30 novembre 2011 11:39
-
-
-
Si ok, ti volevo chiedere un'ultima cosa (si fa per dire) dopo che mi hai aiutato diventerai il mio punto di riferimento.
Stavo notanto che se cambio la combinazione dei tasti tipo:
if
(e.KeyCode == Keys.S && e.Modifiers == Keys.Control) // Combinazione CTRL+S
non funziona tanto, la prima volta va bene ma le successive devo digitare più volte per far partire la procedura.
Come mai?
-
Prova a mettere un punto di interruzione all'inizio della routine dataGridView1_KeyUp, così da verificare se viene richiamata ogni volta oppure no. Controlla anche i valori di e.KeyCode e e.Modifiers, così da assicurarti che siano esattamente quelli che ti aspetti.
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom -
-
Oppure cambiando
(e.KeyValue == 83 && e.Modifiers == Keys.Control) // Combinazione CTRL+S
alla prima pressione mi da e.KeyCode = 17 non inserendo niente, alla seconda pressione e.KeyCode = 83 inserendo il valore, oppure l'inverso.
Mi dici come formattare questo testo?
-
-
Formattare il testo dove? Intendi all'interno di un post nel forum? Devi usare il pulsante "Inserisci codice" della barra degli strumenti (la seconda da destra), dopodiché puoi scrivere tutto il codice che vuoi, sarà formattato in automatico.
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom -
-
-
-
17 è il codice del tasto Control, quindi l'evento KeyUp di dice che è stato rilasciato quel tasto (in pratica, quando rilasci la tua combinazione di tasti, vengono generati due eventi KeyUp, uno per ogni tasto rilasciato). Puoi aggirare il problema utilizzando l'evento KeyDown al posto di KeyUp: ti basta cambiare l'handler dell'evento, il codice rimane lo stesso.
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom- Contrassegnato come risposta mana973 mercoledì 30 novembre 2011 11:39
-
-
-
-
-
OK, nessun problema :-)
Ne approfitto per suggerirti che dovresti segnare come risposta anche il mio primo post, così leggendo quei tre messaggi è possibile ricostruire l'intera soluzione al tuo problema.
A presto!
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom -
-
-
Ciao Marco, scusa ancora...dovrei risolvere un'altro problemino...
Mettiamo che l'utente mentre sta inserendo i dati vuole annullare l'inserimento, normalmente inserendo i dati manualmente e premendo il tasto ESC annulla in automatico il record che l'utente stava inserendo, riportando tutto come all'inizio cioè con l'utimo record vuoto in attesa che venga inserito qualcosa.
Nel mio caso invece se premo ESC non succede nulla perchè ho forzato il refresh del datagrid.
C'è un modo per annullare i dati che l'utente stava inserendo, visualizzando l'utimo record vuoto in modalità di inserimento?
Nando! -
Avendo forzato il refresh della griglia, la semplice pressione di ESC non può annullare l'inserimento. Quello che dovresti fare è intercettare il tasto ESC e cancellare dal dataset la nuova riga.
Marco Minerva [MCPD], http://blogs.ugidotnet.org/marcom -
-
Ho risolto così: private void tArchivioDataGridView_KeyDown(object sender, KeyEventArgs e) { if ((e.KeyCode == Keys.Z) && (e.Modifiers == Keys.Control)) // Combinazione CTRL+S { int prevRow = tArchivioDataGridView.CurrentCell.RowIndex - 1; if (prevRow >= 0) { var value = tArchivioDataGridView[tArchivioDataGridView.CurrentCell.ColumnIndex, prevRow].Value; tArchivioDataGridView.CurrentCell.Value = value; var columnIndex = tArchivioDataGridView.CurrentCell.ColumnIndex; var rowIndex = tArchivioDataGridView.CurrentCell.RowIndex; (tArchivioDataGridView.DataSource as BindingSource).ResetBindings(false); tArchivioDataGridView.CurrentCell = tArchivioDataGridView[columnIndex, rowIndex]; } } else if (e.KeyCode==Keys.Escape) { int selectindex = tArchivioDataGridView.CurrentCell.RowIndex; tArchivioDataGridView.Rows.RemoveAt(selectindex); } }
Grazie!- Contrassegnato come risposta Irina Turcu mercoledì 30 novembre 2011 17:05