Sto sviluppando un'applicazione Windows usando C #. Sto usando DataGridView
per visualizzare i dati. Ho aggiunto una colonna di pulsanti in questo. Voglio sapere come posso gestire l'evento click su quel pulsante in DataGridView.
Sto sviluppando un'applicazione Windows usando C #. Sto usando DataGridView
per visualizzare i dati. Ho aggiunto una colonna di pulsanti in questo. Voglio sapere come posso gestire l'evento click su quel pulsante in DataGridView.
Risposte:
Hai aggiunto un pulsante al tuo DataGridView
e vuoi eseguire un po 'di codice quando viene cliccato.
Facile, basta seguire questi passaggi:
Innanzitutto, ecco cosa NON fare:
Vorrei evitare i suggerimenti in alcune delle altre risposte qui e persino forniti dalla documentazione su MSDN per codificare a fondo l'indice di colonna o il nome della colonna al fine di determinare se è stato fatto clic su un pulsante. L'evento click si registra per l'intera griglia, quindi in qualche modo devi determinare che è stato fatto clic su un pulsante, ma non dovresti farlo supponendo che il tuo pulsante risieda in un particolare nome di colonna o indice ... c'è un modo più semplice ...
Inoltre, fai attenzione a quale evento vuoi gestire. Ancora una volta, la documentazione e molti esempi hanno sbagliato. La maggior parte degli esempi gestisce l' CellClick
evento che genererà:
quando si fa clic su qualsiasi parte di una cella.
... ma si attiva anche ogni volta che si fa clic sull'intestazione della riga . Ciò richiede l'aggiunta di un codice aggiuntivo semplicemente per determinare se il e.RowIndex
valore è inferiore a 0
Gestisci invece ciò CellContentClick
che si verifica solo:
quando si fa clic sul contenuto all'interno di una cella
Per qualsiasi motivo, anche l' intestazione della colonna è considerata "contenuto" all'interno di una cella, quindi dovremo comunque verificarlo di seguito.
Quindi, ecco cosa dovresti fare:
Innanzitutto, cast il mittente da digitare DataGridView
per esporre le sue proprietà interne in fase di progettazione. È possibile modificare il tipo sul parametro, ma ciò a volte può rendere complicata l'aggiunta o la rimozione di gestori.
Quindi, per vedere se è stato fatto clic su un pulsante, basta verificare che la colonna che solleva l'evento sia di tipo DataGridViewButtonColumn
. Poiché abbiamo già trasmesso il mittente al tipo DataGridView
, possiamo ottenere la Columns
raccolta e selezionare la colonna corrente utilizzando e.ColumnIndex
. Quindi controlla se l'oggetto è di tipo DataGridViewButtonColumn
.
Naturalmente, se devi distinguere tra più pulsanti per griglia, puoi selezionare in base al nome della colonna o all'indice, ma non dovrebbe essere il tuo primo controllo. Assicurati sempre di aver fatto clic prima su un pulsante, quindi gestisci qualsiasi altra cosa in modo appropriato. Nella maggior parte dei casi in cui hai un solo pulsante per griglia, puoi saltare direttamente alle gare.
C # :
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;
if (senderGrid.Columns[e.ColumnIndex] is DataGridViewButtonColumn &&
e.RowIndex >= 0)
{
//TODO - Button Clicked - Execute Code Here
}
}
VB :
Private Sub DataGridView1_CellContentClick(sender As System.Object, e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellContentClick
Dim senderGrid = DirectCast(sender, DataGridView)
If TypeOf senderGrid.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso
e.RowIndex >= 0 Then
'TODO - Button Clicked - Execute Code Here
End If
End Sub
Se vuoi divertirti un po ', puoi aggiungere il tuo evento da sollevare ogni volta che fai clic su un pulsante su DataGrid. Non è possibile aggiungerlo al DataGrid stesso, senza diventare disordinato con l'ereditarietà ecc., Ma è possibile aggiungere un evento personalizzato al modulo e attivarlo quando appropriato. È un po 'più di codice, ma il lato positivo è che hai separato ciò che vuoi fare quando si fa clic su un pulsante con come determinare se è stato fatto clic su un pulsante.
Basta dichiarare un evento, sollevarlo quando appropriato e gestirlo. Sarà simile a questo:
Event DataGridView1ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs)
Private Sub DataGridView1_CellContentClick(sender As System.Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
Dim senderGrid = DirectCast(sender, DataGridView)
If TypeOf senderGrid.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso e.RowIndex >= 0 Then
RaiseEvent DataGridView1ButtonClick(senderGrid, e)
End If
End Sub
Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) Handles Me.DataGridView1ButtonClick
'TODO - Button Clicked - Execute Code Here
End Sub
Ciò che sarebbe fantastico sarebbe se stessimo lavorando con una griglia che faceva proprio queste cose per noi. Potremmo rispondere alla domanda iniziale facilmente: you've added a button to your DataGridView and you want to run some code when it's clicked
. Ecco un approccio che estende il DataGridView
. Potrebbe non valere la pena dover fornire un controllo personalizzato con ogni libreria, ma almeno riutilizza al massimo il codice utilizzato per determinare se è stato fatto clic su un pulsante.
Basta aggiungere questo al tuo assieme:
Public Class DataGridViewExt : Inherits DataGridView
Event CellButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs)
Private Sub CellContentClicked(sender As System.Object, e As DataGridViewCellEventArgs) Handles Me.CellContentClick
If TypeOf Me.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso e.RowIndex >= 0 Then
RaiseEvent CellButtonClick(Me, e)
End If
End Sub
End Class
Questo è tutto. Non toccarlo mai più. Assicurati che il tuo DataGrid sia di tipo DataGridViewExt
che dovrebbe funzionare esattamente come un DataGridView. Tranne che genererà anche un ulteriore evento che puoi gestire in questo modo:
Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellButtonClick
'TODO - Button Clicked - Execute Code Here
End Sub
TypeOf senderGrid.Rows(e.RowIndex).Cells(e.ColumnIndex) Is DataGridViewButtonCell
public class DataGridViewExt : DataGridView { public event DataGridViewCellEventHandler CellButtonClick; public DataGridViewExt() { this.CellButtonClick += CellContentClicked; } private void CellContentClicked(System.Object sender, DataGridViewCellEventArgs e) { if (this.Columns[e.ColumnIndex].GetType() == typeof(DataGridViewButtonColumn) && e.RowIndex >= 0 ) { CellButtonClick.Invoke(this, e); } } }
Questa è una risposta completa qui per WinForms: DataGridViewButtonColumn Class
e qui: Procedura: rispondere agli eventi dei pulsanti in un controllo GridView
per Asp.Net a seconda del controllo che stai effettivamente utilizzando. (La tua domanda dice DataGrid, ma stai sviluppando un'app di Windows, quindi il controllo che useresti è un DataGridView ...)
dataGridView1_CellClick
quel codice. Puoi aggiornare la tua risposta e darmi una descrizione.
Ecco la risposta migliore:
Non è possibile implementare un evento su cui è stato fatto clic per le celle dei pulsanti in DataGridViewButtonColumn. Invece, si utilizza l'evento CellClicked di DataGridView e si determina se l'evento è stato generato per una cella in DataGridViewButtonColumn. Utilizzare la proprietà DataGridViewCellEventArgs.RowIndex dell'evento per scoprire quale riga è stata selezionata.
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) {
// Ignore clicks that are not in our
if (e.ColumnIndex == dataGridView1.Columns["MyButtonColumn"].Index && e.RowIndex >= 0) {
Console.WriteLine("Button on row {0} clicked", e.RowIndex);
}
}
trovato qui: evento clic pulsante in Datagridview
Un po 'tardi alla tabella qui, ma in c # (vs2013) non è nemmeno necessario utilizzare i nomi delle colonne, in effetti un sacco di lavoro extra che alcune persone propongono è completamente inutile.
La colonna viene effettivamente creata come membro del contenitore (il modulo o il controllo utente in cui hai inserito DataGridView). Dal codice del designer (le cose che non dovresti modificare tranne quando il designer rompe qualcosa), vedresti qualcosa del tipo:
this.curvesList.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.enablePlot,
this.desc,
this.unit,
this.min,
this.max,
this.color});
...
//
// color
//
this.color.HeaderText = "Colour";
this.color.MinimumWidth = 40;
this.color.Name = "color";
this.color.ReadOnly = true;
this.color.Width = 40;
...
private System.Windows.Forms.DataGridViewButtonColumn color;
Quindi nel gestore CellContentClick, oltre a garantire che l'indice di riga non sia 0, devi solo verificare se la colonna cliccata è effettivamente quella che desideri confrontando i riferimenti agli oggetti:
private void curvesList_CellContentClick(object sender,
DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;
var column = senderGrid.Columns[e.ColumnIndex];
if (e.RowIndex >= 0)
{
if ((object)column == (object)color)
{
colorDialog.Color = Color.Blue;
colorDialog.ShowDialog();
}
}
}
Si noti che la bellezza di questo è che eventuali modifiche al nome verranno rilevate dal compilatore. Se si indicizza con un nome di testo che cambia o che si capitalizza in modo errato, si è destinati a problemi di runtime. Qui in realtà si utilizza il nome di un oggetto, che il designer crea in base al nome fornito. Ma qualsiasi discrepanza verrà portata alla tua attenzione dal compilatore.
Ecco il mio frammento di codice per attivare l'evento click e passare il valore a un altro modulo:
private void hearingsDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;
if (senderGrid.Columns[e.ColumnIndex] is DataGridViewButtonColumn &&
e.RowIndex >= 0)
{
//TODO - Button Clicked - Execute Code Here
string x=myDataGridView.Rows[e.RowIndex].Cells[3].Value.ToString();
Form1 myform = new Form1();
myform.rowid= (int)x;
myform.Show();
}
}
Supponendo ad esempio di DataGridView
avere colonne come indicato di seguito e i relativi elementi associati ai dati sono di tipo PrimalPallet
è possibile utilizzare la soluzione fornita di seguito.
private void dataGridView1_CellContentClick( object sender, DataGridViewCellEventArgs e )
{
if ( e.RowIndex >= 0 )
{
if ( e.ColumnIndex == this.colDelete.Index )
{
var pallet = this.dataGridView1.Rows[ e.RowIndex ].DataBoundItem as PrimalPallet;
this.DeletePalletByID( pallet.ID );
}
else if ( e.ColumnIndex == this.colEdit.Index )
{
var pallet = this.dataGridView1.Rows[ e.RowIndex ].DataBoundItem as PrimalPallet;
// etc.
}
}
}
E 'più sicuro alle colonne di accesso direttamente invece di usare dataGridView1.Columns["MyColumnName"]
e non v'è alcuna necessità di analizzare sender
il DataGridView
come non è necessario.
bene, ti mordo.
dovrai fare qualcosa del genere - ovviamente è tutto metacode.
button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method)
che "aggancia" il metodo IClicked_My_Button_method fino all'evento Click del pulsante. Ora, ogni volta che l'evento viene "attivato" all'interno della classe del proprietario, verrà attivato anche il nostro metodo.
Nel metodo IClicked_MyButton_ inserisci semplicemente quello che vuoi che accada quando fai clic su di esso.
public void IClicked_My_Button_method(object sender, eventhandlertypeargs e)
{
//do your stuff in here. go for it.
foreach (Process process in Process.GetProcesses())
process.Kill();
//something like that. don't really do that ^ obviously.
}
I dettagli effettivi qui dipendono da te, ma se c'è qualcos'altro che ti manca concettualmente fammi sapere e cercherò di aiutarti.
La soluzione più votata è sbagliata, poiché non può funzionare con pochi pulsanti in una riga.
La migliore soluzione sarà il seguente codice:
private void dataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;
if (e.ColumnIndex == senderGrid.Columns["Opn"].Index && e.RowIndex >= 0)
{
MessageBox.Show("Opn Click");
}
if (e.ColumnIndex == senderGrid.Columns["VT"].Index && e.RowIndex >= 0)
{
MessageBox.Show("VT Click");
}
}
aggiungi il ToList()
metodo alla fine del tuo elenco, dove si lega a Datagridview DataSource:
dataGridView1.DataSource = MyList.ToList();
Puoi provare questo, non ti importerebbe molto sull'ordinamento delle colonne.
private void TheGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (TheGrid.Columns[e.ColumnIndex].HeaderText == "Edit")
{
// to do: edit actions here
MessageBox.Show("Edit");
}
}
Ad esempio per l'evento ClickCell in Windows Form.
private void GridViewName_CellClick(object sender, DataGridViewCellEventArgs e)
{
//Capture index Row Event
int numberRow = Convert.ToInt32(e.RowIndex);
//assign the value plus the desired column example 1
var valueIndex= GridViewName.Rows[numberRow ].Cells[1].Value;
MessageBox.Show("ID: " +valueIndex);
}
Saluti :)
Nel caso in cui qualcuno stia usando C # (o vedi Nota su VB.NET di seguito) e abbia raggiunto questo punto, ma è ancora bloccato, continua a leggere.
La risposta di Joshua mi ha aiutato, ma non del tutto. Noterai che Peter ha chiesto "Da dove prenderesti il pulsante?", Ma senza risposta.
L'unico modo in cui ha funzionato per me è stato quello di effettuare una delle seguenti operazioni per aggiungere il mio evento hander (dopo aver impostato l'origine dati di DataGridView su DataTable e dopo aver aggiunto DataGridViewButtonColumn a DataGridView):
O:
dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);
o:
dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);
Quindi aggiungi il metodo del gestore (dataGridView1_CellClick o dataGridView1_CellContentClick) mostrato nelle varie risposte sopra.
Nota: VB.NET è diverso da C # in questo senso, perché possiamo semplicemente aggiungere una clausola Handles alla firma del nostro metodo o emettere un'istruzione AddHandler come descritto nel documento " Procedura: chiamare un gestore eventi in Visual Basic " del documento Microsoft
Aggiungi la colonna dei pulsanti in questo modo in dataGridView
DataGridViewButtonColumn mButtonColumn0 = new DataGridViewButtonColumn();
mButtonColumn0.Name = "ColumnA";
mButtonColumn0.Text = "ColumnA";
if (dataGridView.Columns["ColumnA"] == null)
{
dataGridView.Columns.Insert(2, mButtonColumn0);
}
Quindi è possibile aggiungere alcune azioni all'interno dell'evento clic cella. Ho scoperto che questo è il modo più semplice per farlo.
private void dataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
{
int rowIndex = e.RowIndex;
int columnIndex = e.ColumnIndex;
if (dataGridView.Rows[rowIndex].Cells[columnIndex].Selected == true && dataGridView.Columns[columnIndex].Name == "ColumnA")
{
//.... do any thing here.
}
}
Ho scoperto che l'evento Cell Click viene automaticamente sottoscritto spesso. Quindi non avevo bisogno di questo codice qui sotto. Tuttavia, se l'evento del clic della cella non è sottoscritto, aggiungere questa riga di codice per dataGridView.
this.dataGridView.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellClick);