it-swarm.com.de

Wie gehe ich mit dem Click-Ereignis in der Button-Spalte in Datagridview um?

Ich entwickle eine Windows-Anwendung mit C #. Ich verwende DataGridView, um Daten anzuzeigen. Ich habe eine Button-Spalte hinzugefügt. Ich möchte wissen, wie ich mit dem Click-Ereignis auf dieser Schaltfläche in DataGridView umgehen kann.

115
Himadri

Sie haben Ihrer DataGridView eine Schaltfläche hinzugefügt, und Sie möchten Code ausführen, wenn Sie darauf klicken.
Easy peasy - folgen Sie einfach diesen Schritten:

Don'ts:

Zunächst einmal, was NICHT zu tun ist:

Ich würde die Vorschläge in einigen der anderen Antworten hier vermeiden und sogar in der Dokumentation bei MSDN enthalten, um den Spaltenindex oder den Spaltennamen fest zu codieren, um festzustellen, ob eine Schaltfläche angeklickt 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 sich Ihre Schaltfläche in einem bestimmten Spaltennamen oder Index befindet. Es gibt einen einfacheren Weg ...

Seien Sie auch vorsichtig mit dem Ereignis, das Sie behandeln möchten. Auch hier wird die Dokumentation und viele Beispiele falsch. Die meisten Beispiele behandeln das CellClick -Ereignis, das ausgelöst wird:

wenn ein Teil einer Zelle angeklickt wird.

... wird aber auch ausgelöst, wenn auf die Kopfzeile row geklickt wird. Dies erfordert das Hinzufügen von zusätzlichem Code, nur um festzustellen, ob der e.RowIndex-Wert kleiner als 0 ist

Behandeln Sie stattdessen die CellContentClick , die nur auftritt:

wenn auf den Inhalt einer Zelle geklickt wird

Aus irgendeinem Grund wird der column -Header auch als "Inhalt" in einer Zelle betrachtet, daher müssen wir unten noch nachsehen.

DOS:

So sollten Sie folgendes tun:

Zuerst muss cast der Sender DataGridView eingeben, um seine internen Eigenschaften zur Entwurfszeit anzuzeigen. Sie können den Typ für den Parameter ändern. Dies macht jedoch manchmal das Hinzufügen oder Entfernen von Handlern schwierig.

Überprüfen Sie als Nächstes, ob eine Schaltfläche angeklickt wurde, ob die Spalte, die das Ereignis auslöst, vom Typ DataGridViewButtonColumn ist. Da wir den Sender bereits in DataGridView umwandeln, können wir die Columns-Auflistung abrufen und die aktuelle Spalte mit e.ColumnIndex auswählen. Prüfen Sie dann, ob das Objekt vom Typ DataGridViewButtonColumn ist.

Wenn Sie zwischen mehreren Schaltflächen pro Raster unterscheiden müssen, können Sie natürlich die Auswahl anhand des Spaltennamens oder des Index vornehmen. Dies sollte jedoch nicht Ihre erste Prüfung sein. Vergewissern Sie sich immer, dass zuerst eine Schaltfläche angeklickt wurde, und behandeln Sie dann alles andere entsprechend. In den meisten Fällen, in denen Sie nur eine einzige Taste pro Raster haben, können Sie direkt zu den Rennen springen.

Alles zusammenstellen:

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

Update 1 - Benutzerdefiniertes Ereignis

Wenn Sie ein wenig Spaß haben wollten, können Sie Ihr eigenes Ereignis hinzufügen, das ausgelöst wird, wenn Sie auf eine Schaltfläche im DataGrid klicken. Sie können es nicht dem DataGrid selbst hinzufügen, ohne sich mit der Vererbung usw. unordentlich zu machen, aber Sie können Ihrem Formular ein benutzerdefiniertes Ereignis hinzufügen und es gegebenenfalls auslösen. Es ist ein wenig mehr Code, aber der Vorteil ist, dass Sie das, was Sie tun möchten, wenn Sie auf eine Schaltfläche klicken, heraussucht, um herauszufinden, ob eine Schaltfläche angeklickt wurde. 

Deklarieren Sie einfach ein Ereignis, melden Sie es an 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

Update 2 - Erweitertes Gitter

Was wäre toll, wenn wir mit einem Raster arbeiten würden, das diese Dinge für uns erledigt hat. 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 erweitert. Es ist vielleicht nicht die Mühe wert, mit jeder Bibliothek ein benutzerdefiniertes Steuerelement ausgeben zu müssen, aber der Code, mit dem festgestellt wird, ob eine Schaltfläche angeklickt wurde, wird zumindest maximal verwendet.

Fügen Sie dies einfach Ihrer Versammlung 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 genau wie eine DataGridView funktionieren sollte. Es wird jedoch 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
217
KyleMit

Das ist hier für WinForms vollständig beantwortet: DataGridViewButtonColumn-Klasse

und hier: Gewusst wie: Antworten auf Schaltflächenereignisse in einem GridView-Steuerelement

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 ein DataGridView ...)

15
David

Hier ist die bessere Antwort:

Sie können ein angeklicktes Ereignis für eine Schaltfläche nicht für Knopfzellen 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 festzustellen, 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 gefunden: button click event in datagridview

9
TechStuffBC

Das löst mein Problem.

private void dataGridViewName_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        //Your code
    }
8
Himadri

Etwas spät dran an der Tabelle, aber in c # (vs2013) müssen Sie auch keine Spaltennamen verwenden. Tatsächlich ist die zusätzliche Arbeit, die manche Leute vorschlagen, völlig überflüssig.

Die Spalte wird tatsächlich als Mitglied des Containers erstellt (das Formular oder die Benutzerkontrolle, in die Sie DataGridView eingefügt haben). Aus dem Designer-Code (dem Material, das Sie nicht bearbeiten dürfen, außer 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 nicht nur sicherstellen, dass der Zeilenindex nicht 0 ist, sondern nur überprüfen, ob die angeklickte Spalte tatsächlich die ist, die Sie möchten, indem Sie die 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 geändert wird oder Sie falsch schreiben, sind Sie mit Laufzeitproblemen konfrontiert. Hier verwenden Sie tatsächlich den Namen eines Objekts, das der Designer basierend auf dem von Ihnen angegebenen Namen erstellt. Jede Abweichung wird jedoch vom Compiler zur Kenntnis gebracht.

4
Arunas

Hier ist mein Code-Snippet, um das Click-Ereignis 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();

        }
    }
2
newComer

Wenn beispielsweise angenommen wird, dass DataGridView die unten angegebenen Spalten hat und die datengebundenen Elemente vom Typ PrimalPallet sind, können Sie die unten angegebene Lösung verwenden.

 enter image description here

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, anstatt dataGridView1.Columns["MyColumnName"] zu verwenden, und es ist nicht erforderlich, sender in DataGridView zu parsen, da dies nicht erforderlich ist. 

1
Ryfcia

Die meiste Lösung ist falsch, da nicht mit wenigen Tasten 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");
            }
        }
0
Andrew

Zum Beispiel für das 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 :)

Sie können dies versuchen, es würde Ihnen nicht viel ausmachen, die Spalten zu ordnen.

private void TheGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (TheGrid.Columns[e.ColumnIndex].HeaderText == "Edit")
    {
        // to do: edit actions here
        MessageBox.Show("Edit");
    }
}
0
JL Dajoyag

Falls jemand C # verwendet (oder siehe Hinweis zu VB.NET unten) und diesen Punkt erreicht hat, aber immer noch hängen bleibt, lesen Sie bitte weiter.

Josuas Antwort half mir, aber nicht ganz. Sie werden feststellen, dass Peter gefragt hat "Woher bekommen Sie den Button?", Wurde aber nicht beantwortet.

Die einzige Methode, die für mich funktionierte, bestand darin, eine der folgenden Aktionen auszuführen, um meinen Ereignishandler hinzuzufügen (nachdem die DataSource meiner DataGridView in meine DataTable gesetzt und die DataGridViewButtonColumn der DataGridView hinzugefügt wurde):

Entweder:

dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);

oder:

dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);

Fügen Sie dann die Handler-Methode (entweder dataGridView1_CellClick oder dataGridView1_CellContentClick) hinzu, die in den verschiedenen Antworten oben angezeigt wird.

Hinweis: VB.NET unterscheidet sich in dieser Hinsicht von C #, da wir einfach eine Handles-Klausel zur Signatur unserer Methode hinzufügen oder eine AddHandler-Anweisung ausgeben können, wie im Microsoft-Dokument " How to: Aufrufen eines Ereignishandlers in Visual Basic "

0
clairestreb

gut, ich werde beißen.

sie müssen so etwas tun - offensichtlich ist alles Metacode.

button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method)

dass die Methode IClicked_My_Button_method mit dem Click-Ereignis der Schaltfläche "verknüpft" wird. Jedes Mal, wenn das Ereignis innerhalb der Eigentümerklasse "ausgelöst" wird, wird auch unsere Methode ausgelöst.

In der IClicked_MyButton_method legen Sie einfach das fest, was Sie tun möchten, 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 eigentlichen Details liegen bei Ihnen, aber wenn Ihnen sonst noch etwas fehlt, lassen Sie es mich wissen und ich versuche zu helfen.

0
Joshua Evensen

Sie fügen diese Schaltfläche in Ihrer dataGridView so hinzu

        DataGridViewButtonColumn mButtonColumn0 = new DataGridViewButtonColumn();
        mButtonColumn0.Name = "ColumnA";
        mButtonColumn0.Text = "ColumnA";


        if (dataGridView.Columns["ColumnA"] == null)
        {
            dataGridView.Columns.Insert(2, mButtonColumn0);
        }

Dann können Sie einige Aktionen innerhalb des Zellklickereignisses hinzufügen. Ich fand das am einfachsten. 

    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. Ich brauchte diesen Code also nicht. Wenn Ihr Zellenklick-Ereignis 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);
0
auto9817

fügen Sie einfach die ToList()-Methode am Ende Ihrer Liste hinzu.

dataGridView1.DataSource = MyList.ToList();
0