Ich entwickle eine Windows-Anwendung mit C #. ich benutzeDataGridView
, um Daten anzuzeigen. Ich habe eine Schaltflächenspalte hinzugefügt. Ich möchte wissen, wie ich mit Klickereignissen auf dieser Schaltfläche in DataGridView umgehen kann.
Ich entwickle eine Windows-Anwendung mit C #. ich benutzeDataGridView
, um Daten anzuzeigen. Ich habe eine Schaltflächenspalte hinzugefügt. Ich möchte wissen, wie ich mit Klickereignissen auf dieser Schaltfläche in DataGridView umgehen kann.
Antworten:
Sie haben Ihrer Schaltfläche eine Schaltfläche hinzugefügt DataGridView
und möchten beim Klicken Code ausführen.
Einfach peasy - folgen Sie einfach diesen Schritten:
Zunächst ist Folgendes NICHT zu tun:
Ich würde die Vorschläge in einigen der anderen Antworten hier vermeiden und sogar in der Dokumentation bei MSDN enthalten sein, um den Spaltenindex oder den Spaltennamen fest zu codieren, um festzustellen, ob auf eine Schaltfläche geklickt wurde. Das Klickereignis wird für das gesamte Raster registriert. Sie müssen also irgendwie feststellen, dass auf eine Schaltfläche geklickt wurde. Sie sollten dies jedoch nicht tun, indem Sie davon ausgehen, dass Ihre Schaltfläche in einem bestimmten Spaltennamen oder Index gespeichert ist. Es gibt einen einfacheren Weg.
Achten Sie auch darauf, welches Ereignis Sie behandeln möchten. Auch hier verstehen die Dokumentation und viele Beispiele dies falsch. Die meisten Beispiele behandeln das CellClick
Ereignis, das ausgelöst wird:
Wenn auf einen Teil einer Zelle geklickt wird.
... sondern auch feuern , wenn die Zeile Header geklickt wird. Dies erfordert das Hinzufügen von zusätzlichem Code, um festzustellen, ob der e.RowIndex
Wert kleiner als 0 ist
Behandeln Sie stattdessen das, CellContentClick
was nur auftritt:
wenn auf den Inhalt einer Zelle geklickt wird
Aus irgendeinem Grund wird die Spaltenüberschrift auch als "Inhalt" in einer Zelle betrachtet, daher müssen wir dies unten noch überprüfen.
Folgendes sollten Sie also tun:
Zuerst warf den Absender eingeben DataGridView
es interne Eigenschaften zur Entwurfszeit belichten. Sie können den Typ des Parameters ändern, dies kann jedoch manchmal das Hinzufügen oder Entfernen von Handlern schwierig machen.
Um zu sehen, ob auf eine Schaltfläche geklickt wurde, überprüfen Sie einfach, ob die Spalte, die das Ereignis auslöst, vom Typ ist DataGridViewButtonColumn
. Da wir den Absender bereits in Typ umgewandelt haben DataGridView
, können wir die Columns
Sammlung abrufen und die aktuelle Spalte mit auswählen e.ColumnIndex
. Überprüfen Sie dann, ob dieses Objekt vom Typ ist DataGridViewButtonColumn
.
Wenn Sie zwischen mehreren Schaltflächen pro Raster unterscheiden müssen, können Sie diese natürlich anhand des Spaltennamens oder des Index auswählen. Dies sollte jedoch nicht Ihre erste Prüfung sein. Stellen Sie immer sicher, dass zuerst auf eine Schaltfläche geklickt wurde, und behandeln Sie dann alles andere entsprechend. In den meisten Fällen, in denen Sie nur eine Schaltfläche pro Raster haben, können Sie direkt zu den Rennen springen.
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
Wenn Sie ein bisschen Spaß haben möchten, können Sie Ihr eigenes Ereignis hinzufügen, das ausgelöst wird, wenn auf eine Schaltfläche im DataGrid geklickt wird. Sie können es nicht zum DataGrid selbst hinzufügen, ohne mit Vererbung usw. in Konflikt zu geraten. Sie können Ihrem Formular jedoch ein benutzerdefiniertes Ereignis hinzufügen und es gegebenenfalls auslösen. Es ist etwas mehr Code, aber der Vorteil ist, dass Sie getrennt haben, was Sie tun möchten, wenn auf eine Schaltfläche geklickt wird, und wie Sie feststellen können, ob auf eine Schaltfläche geklickt wurde.
Deklarieren Sie einfach ein Ereignis, lösen Sie es gegebenenfalls aus und behandeln Sie es. Es wird so aussehen:
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
Was großartig wäre, wäre, wenn wir mit einem Raster arbeiten würden, das diese Dinge nur für uns erledigt. Wir könnten die erste Frage leicht beantworten : you've added a button to your DataGridView and you want to run some code when it's clicked
. Hier ist ein Ansatz, der die DataGridView
. Es lohnt sich möglicherweise nicht, mit jeder Bibliothek ein benutzerdefiniertes Steuerelement bereitzustellen, aber zumindest wird der Code, der zum Bestimmen, ob auf eine Schaltfläche geklickt wurde, verwendet wird, maximal wiederverwendet.
Fügen Sie dies einfach Ihrer Baugruppe hinzu:
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
Das ist es. Nie wieder anfassen. Stellen Sie sicher, dass Ihr DataGrid vom Typ DataGridViewExt
ist, der genauso funktionieren sollte wie ein DataGridView. Außer es wird auch ein zusätzliches Ereignis ausgelöst, das Sie wie folgt behandeln können:
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); } } }
Dies wird hier für WinForms vollständig beantwortet: DataGridViewButtonColumn Class
und hier: Gewusst wie: Auf Schaltflächenereignisse in einem GridView-Steuerelement reagieren
für Asp.Net abhängig von der Steuerung, die Sie tatsächlich verwenden. (Ihre Frage lautet DataGrid, aber Sie entwickeln eine Windows-App. Das Steuerelement, das Sie dort verwenden würden, ist also DataGridView ...)
dataGridView1_CellClick
diesen Code nicht eingegeben. Können Sie Ihre Antwort aktualisieren und mir eine Beschreibung geben?
Hier ist die bessere Antwort:
Sie können kein Ereignis mit Schaltflächenklick für Schaltflächenzellen in einer DataGridViewButtonColumn implementieren. Stattdessen verwenden Sie das CellClicked-Ereignis von DataGridView und bestimmen, ob das Ereignis für eine Zelle in Ihrer DataGridViewButtonColumn ausgelöst wurde. Verwenden Sie die DataGridViewCellEventArgs.RowIndex-Eigenschaft des Ereignisses, um herauszufinden, auf welche Zeile geklickt wurde.
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);
}
}
hier zu finden: button click event in datagridview
Ein bisschen zu spät zur Tabelle hier, aber in c # (vs2013) müssen Sie auch keine Spaltennamen verwenden, tatsächlich ist ein Großteil der zusätzlichen Arbeit, die einige Leute vorschlagen, völlig unnötig.
Die Spalte wird tatsächlich als Mitglied des Containers erstellt (das Formular oder die Benutzersteuerung, in die Sie DataGridView eingefügt haben). Aus dem Designer-Code (dem Material, das Sie nur bearbeiten sollen, wenn der Designer etwas kaputt macht) sehen Sie Folgendes:
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;
Im CellContentClick-Handler müssen Sie also nicht nur sicherstellen, dass der Zeilenindex nicht 0 ist, sondern auch überprüfen, ob die angeklickte Spalte tatsächlich die gewünschte ist, indem Sie Objektreferenzen vergleichen:
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();
}
}
}
Beachten Sie, dass das Schöne daran ist, dass alle Namensänderungen vom Compiler abgefangen werden. Wenn Sie mit einem Textnamen indizieren, der sich ändert oder den Sie falsch großschreiben, sind Sie an Laufzeitprobleme gebunden. Hier verwenden Sie tatsächlich den Namen eines Objekts, das der Designer basierend auf dem von Ihnen angegebenen Namen erstellt. Aber jede Nichtübereinstimmung wird Sie vom Compiler darauf aufmerksam machen.
Hier ist mein Code-Snippet, um das Klickereignis auszulösen und den Wert an ein anderes Formular zu übergeben:
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();
}
}
Angenommen, Sie haben beispielsweise DataGridView
die unten angegebenen Spalten und die datengebundenen Elemente sind vom Typ PrimalPallet
, können Sie die unten angegebene Lösung verwenden.
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.
}
}
}
Es ist sicherer, direkt auf Spalten zuzugreifen, als sie zu verwenden, dataGridView1.Columns["MyColumnName"]
und es ist nicht erforderlich, sie zu analysieren sender
, DataGridView
da sie nicht benötigt werden.
gut, ich werde beißen.
Sie müssen so etwas tun - offensichtlich ist alles Metacode.
button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method)
Dadurch wird die IClicked_My_Button_method-Methode bis zum Click-Ereignis der Schaltfläche "eingehakt". Jedes Mal, wenn das Ereignis innerhalb der Eigentümerklasse "ausgelöst" wird, wird unsere Methode ebenfalls ausgelöst.
In der IClicked_MyButton_method geben Sie einfach ein, was passieren soll, wenn Sie darauf klicken.
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.
}
Die tatsächlichen Details hier liegen bei Ihnen, aber wenn Ihnen noch etwas fehlt, lassen Sie es mich wissen und ich werde versuchen zu helfen.
Die am häufigsten gewählte Lösung ist falsch, da nicht mit wenigen Schaltflächen in einer Reihe gearbeitet werden kann.
Die beste Lösung ist der folgende Code:
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");
}
}
ToList()
Fügen Sie einfach eine Methode am Ende Ihrer Liste hinzu, wo Sie an datagridview DataSource binden:
dataGridView1.DataSource = MyList.ToList();
Sie können es versuchen, die Reihenfolge der Spalten ist Ihnen egal.
private void TheGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (TheGrid.Columns[e.ColumnIndex].HeaderText == "Edit")
{
// to do: edit actions here
MessageBox.Show("Edit");
}
}
Zum Beispiel für ClickCell-Ereignis in Windows Forms.
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);
}
Grüße :)
Falls jemand C # verwendet (oder siehe Hinweis zu VB.NET unten) und diesen Punkt erreicht hat, aber immer noch nicht weiterkommt, lesen Sie bitte weiter.
Joshuas Antwort hat mir geholfen, aber nicht den ganzen Weg. Sie werden bemerken, dass Peter fragte "Woher würden Sie den Knopf bekommen?", Aber unbeantwortet blieb.
Die einzige Möglichkeit für mich bestand darin, einen der folgenden Schritte auszuführen, um meinen Ereignishander hinzuzufügen (nachdem die DataSource von DataGridView zu meiner DataTable und die DataGridViewButtonColumn zur DataGridView hinzugefügt wurden):
Entweder:
dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);
oder:
dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);
Fügen Sie dann die in den verschiedenen Antworten oben gezeigte Handlermethode hinzu (entweder dataGridView1_CellClick oder dataGridView1_CellContentClick).
Hinweis: VB.NET unterscheidet sich in dieser Hinsicht von C #, da wir der Signatur unserer Methode einfach eine Handles-Klausel hinzufügen oder eine AddHandler-Anweisung ausgeben können, wie im Microsoft-Dokument "Gewusst wie: Aufrufen eines Ereignishandlers in Visual Basic " beschrieben.
Sie werden eine solche Schaltflächenspalte in Ihre dataGridView einfügen
DataGridViewButtonColumn mButtonColumn0 = new DataGridViewButtonColumn();
mButtonColumn0.Name = "ColumnA";
mButtonColumn0.Text = "ColumnA";
if (dataGridView.Columns["ColumnA"] == null)
{
dataGridView.Columns.Insert(2, mButtonColumn0);
}
Anschließend können Sie einige Aktionen innerhalb des Zellenklickereignisses hinzufügen. Ich fand, dass dies der einfachste Weg ist.
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.
}
}
Ich habe festgestellt, dass das Cell Click-Ereignis häufig automatisch abonniert wird. Also brauchte ich diesen Code unten nicht. Wenn Ihr Zellenklickereignis jedoch nicht abonniert ist, fügen Sie diese Codezeile für Ihre dataGridView hinzu.
this.dataGridView.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellClick);