Datagridview'da Düğme Sütununda tıklama olayını nasıl işlerim?


136

C # kullanarak bir windows uygulaması geliştiriyorum. DataGridViewVerileri görüntülemek için kullanıyorum . Buna bir düğme sütunu ekledim. DataGridView bu düğmeye tıklama olayı nasıl işleyebilir bilmek istiyorum.


1
Düğmeyi programlı olarak mı ekliyorsunuz (tek yol olduğundan şüphelendiğim gibi)?
XstreamINsanity

Bu çevrimiçi için birçok cevap var. Özellikle size sıkıntı veren nedir?
Joshua Evensen

1
@Joshua İnternette birçok cevap aldım ama ne yapacağımı ve ne zaman başlayacağımı bilmiyordum. Ben datagridview bir düğme ekledi sadece onun tıklama olayını işlemek için nasıl bilmiyorum.
Himadri

Yanıtlar:


263

Cihazınıza bir düğme eklediniz DataGridViewve tıklandığında bir kod çalıştırmak istiyorsunuz.
Kolay peasy - sadece şu adımları izleyin:

Yapılmaması Gerekenler:

İlk olarak, YAPMAYINIZ :

Ben burada diğer cevapların bazı önerileri önlemek ve hatta bir belge tıklanmış olup olmadığını belirlemek için sütun dizini veya sütun adını sabit kodlamak için MSDN belgeleri tarafından sağlanan bile . Click olayı tüm ızgaraya kaydolur, bu nedenle bir şekilde bir düğmenin tıklandığını belirlemeniz gerekir, ancak düğmenizin belirli bir sütun adında veya dizinde yaşadığını varsayarak bunu yapmamalısınız ... daha kolay bir yol var ...

Ayrıca, hangi etkinliği gerçekleştirmek istediğinize dikkat edin. Yine, belgeler ve birçok örnek bunu yanlış anlıyor. Çoğu örnek, işlenecek olan CellClickolayı ele alır :

bir hücrenin herhangi bir parçası tıklandığında.

... ancak satır başlığı her tıklandığında tetiklenir. Bu, e.RowIndexdeğerin 0'dan küçük olup olmadığını belirlemek için ekstra kod eklemeyi gerektirir

Bunun yerine CellContentClicksadece gerçekleşen işlemek :

bir hücredeki içerik tıklandığında

Hangi nedenle olursa olsun, sütun başlığı da bir hücre içinde 'içerik' olarak kabul edilir, bu yüzden aşağıda bunu kontrol etmemiz gerekir.

Dos:

İşte yapmanız gerekenler:

İlk olarak, döküm tipine gönderenDataGridView tasarım esnasında iç özelliklerini bulunuyor ortaya çıkarmak. Parametredeki türü değiştirebilirsiniz, ancak bu bazen işleyicileri eklemeyi veya kaldırmayı zorlaştırabilir.

Ardından, bir düğmenin tıklanıp tıklanmadığını görmek için, etkinliği artıran sütunun türünde olduğundan emin olun DataGridViewButtonColumn. Göndereni zaten yazmak için yayınladığımızdan DataGridView, Columnskoleksiyonu alabilir ve geçerli sütunu kullanarak seçebiliriz e.ColumnIndex. Sonra bu nesnenin türünü kontrol edin DataGridViewButtonColumn.

Tabii ki, ızgara başına birden çok düğmeyi ayırt etmeniz gerekiyorsa, sütun adına veya dizinine göre seçim yapabilirsiniz, ancak bu ilk kontrolünüz olmamalıdır. Her zaman önce bir düğmenin tıklandığından emin olun ve sonra başka bir şeyi uygun şekilde kullanın. Izgara başına yalnızca tek bir düğmenizin olduğu çoğu durumda, hemen yarışlara atlayabilirsiniz.

Hepsini bir araya koy:

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

Güncelleme 1 - Özel Etkinlik

Biraz eğlenmek istiyorsanız, DataGrid'de bir düğmeye her tıklandığında kendi etkinliğinizi ekleyebilirsiniz. Kalıtım vb.Ile karışmadan DataGrid'e ekleyemezsiniz, ancak formunuza özel bir olay ekleyebilir ve uygun olduğunda tetikleyebilirsiniz. Bu biraz daha kod, ancak üst kısım, bir düğmeye tıklandığında ne yapmak istediğinizi, bir düğmenin tıklanıp tıklanmadığını nasıl belirleyeceğinizi ayırmanızdır.

Bir olayı beyan edin, uygun olduğunda yükseltin ve yönetin. Bunun gibi görünecek:

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

Güncelleme 2 - Genişletilmiş Izgara

Bizim için sadece bu şeyleri yapan bir ızgarayla çalışsaydık harika olurdu. Biz kolayca başlangıç soruya cevap verebilir: you've added a button to your DataGridView and you want to run some code when it's clicked. İşte bu yaklaşımı genişleten bir yaklaşım DataGridView. Her kitaplıkla özel bir denetim sunmak zorunda kalmaya değmeyebilir, ancak en azından bir düğmenin tıklanıp tıklanmadığını belirlemek için kullanılan kodu en üst düzeyde kullanır.

Sadece montajınıza ekleyin:

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

Bu kadar. Bir daha asla dokunmayın. DataGrid'inizin, DataGridView ile DataGridViewExttam olarak aynı şekilde çalışması gereken türde olduğundan emin olun . Bunun dışında şu şekilde başa çıkabileceğiniz fazladan bir olay ortaya çıkarır:

Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) _
                                      Handles DataGridView1.CellButtonClick
    'TODO - Button Clicked - Execute Code Here
End Sub

1
VB.net'te sütun dizinini kontrol etmek zorunda değilsiniz. Bu tam örneği iki sütunlu bir dgv için kullanıyorum. Bir sütun düzenlenebilir ve 2 sütun kaldır buttton ile. Tüm dgv'yi tıklıyorum ve olay yalnızca düğmeyi tıkladığımda tetikleniyor.
Aydınlık

3
+1. Ancak, bizim durumumuzda sütun genel bir DataGridViewColumn ve hücre türünü kontrol etmek zorunda kaldı:TypeOf senderGrid.Rows(e.RowIndex).Cells(e.ColumnIndex) Is DataGridViewButtonCell
Dave Johnson

Upvotes ve yorumlardan yola çıkarak bunun doğru bir cevap olduğunu anlıyorum, ama ... neden her şey bu kadar karmaşık olmalı? Henüz WPF'ye yaklaşmadım, ama orada da aynı olur mu?
jj_

1
Güncelleme 2 için C # kodupublic 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); } } }
Tony Cheetham

@tonyenkiducx, takdir ama yorum tüm sınıf için alternatif sözdizimi, özellikle bir kod dönüştürücü yoluyla kolayca türetilebilir göstermek için gerçekten iyi bir yer değil . Elbette, insanlar buraya c # aramaya gelecekler, ancak orada kendileri yaya geçebilirler ve yine de bir uygulama arayan yorumlara göz atmazlar.
Yorumunuzu

15

WinForms: DataGridViewButtonColumn Class için tam burada cevaplanmıştır

ve burada: Nasıl yapılır: Bir GridView Denetiminde Düğme Olaylarına Yanıt Verme

kullandığınız kontrole bağlı olarak Asp.Net için. (Sorunuz DataGrid diyor, ancak bir Windows uygulaması geliştiriyorsunuz, bu nedenle kullanacağınız kontrol bir DataGridView ...


Üzgünüm, bu benim hatamdı. DataGridView kullanıyorum. Ve cevabınızın ilk bağlantısını zaten görüyorum. Ben alamadım dataGridView1_CellClicko kodda. Cevabınızı güncelleyebilir ve bana biraz açıklama verebilir misiniz?
Himadri

10

İşte daha iyi cevap:

Bir DataGridViewButtonColumn içindeki düğme hücreleri için düğmeye tıklanan olayı uygulayamazsınız. Bunun yerine, DataGridView'ın CellClicked olayını kullanın ve olayın DataGridViewButtonColumn öğenizde bir hücre için tetiklenip tetiklenmediğini belirleyin. Hangi satırın tıklandığını bulmak için olayın DataGridViewCellEventArgs.RowIndex özelliğini kullanın.

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);
  }
}

burada bulundu: datagridview'da düğme tıklama etkinliği


8

Bu benim sorunumu çözdü.

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

5

Buradaki tabloya biraz geç, ancak c # (vs2013) 'te sütun adlarını kullanmanıza gerek yoktur, aslında bazı insanların önerdiği ekstra işlerin çoğu tamamen gereksizdir.

Sütun aslında kabın bir üyesi olarak oluşturulur (DataGridView içine koyduğunuz form veya usercontrol). Tasarımcı kodundan (tasarımcı bir şeyi bozma durumu dışında düzenlemeniz gerekmeyen şeyler), şöyle bir şey görürsünüz:

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;

Bu nedenle, CellContentClick işleyicisinde, satır dizininin 0 olmadığından emin olmanın yanı sıra, nesne referanslarını karşılaştırarak tıklanan sütunun aslında istediğiniz sütun olup olmadığını kontrol etmeniz yeterlidir:

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();
        }
    }
}

Bunun güzelliği, herhangi bir isim değişikliğinin derleyici tarafından yakalanacağını unutmayın. Değişen veya yanlış büyük harf kullandığınız bir metin adıyla dizine eklerseniz, çalışma zamanı sorunları yaşarsınız. Burada aslında tasarımcının sağladığınız isme göre oluşturduğu bir nesnenin adını kullanırsınız. Ancak herhangi bir uyumsuzluk derleyici tarafından dikkatinize sunulacaktır.


Zeki olmak için +2, çok zeki olmak için -1 :-) IMHO eski bir gönderiye yorum eklemek için asla geç değildir, çünkü benim gibi birçok insan hala stackoverflow ile ilgili cevaplar arıyor.
JonP

2

Tıklama olayını tetiklemek ve değeri başka bir forma geçirmek için kod snippetim:

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

Örneğin DataGridView, aşağıda verilen sütunlara sahip olduğunu ve veriye bağlı öğelerinin PrimalPalletaşağıda verilen çözümü kullanabileceğiniz tipte olduğunu varsayarsak .

resim açıklamasını buraya girin

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.
        }
    }
}

Bu erişim sütunlara daha güvenli doğrudan yerine kullanarak var dataGridView1.Columns["MyColumnName"]ve ayrıştırmak için gerek yoktur senderiçin DataGridViewİhtiyaç olmadığında olarak.


0

iyi, ısırırım.

böyle bir şey yapmanız gerekecek - açıkçası tüm meta kodu.

button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method)

IClicked_My_Button_method yöntemini düğmenin Click etkinliğine "bağlar". Şimdi, etkinlik sahip sınıfından her "tetiklendiğinde" yöntemimiz de tetiklenecektir.

IClicked_MyButton_method'da, tıkladığınızda olmasını istediğiniz her şeyi koyabilirsiniz.

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.
}

Buradaki asıl detaylar size kalmış, ancak başka bir şey varsa, eksik olarak kavramsal olarak bana bildirin ve yardım etmeye çalışacağım.


bu bağlantının olmasını istediğiniz her yerde. Genel olarak, datagridview başlatıldıktan sonra büyük olasılıkla formunuzun yapıcısına gider.
Joshua Evensen

Düğmeyi nereden alırsın !?
Peter - Monica'yı

0

En çok oy alan çözüm yanlıştır, çünkü bir satırda birkaç düğme ile çalışamaz.

En iyi çözüm aşağıdaki kod olacaktır:

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

ToList()datagridview DataSource'a bağladığınız listenin sonuna yöntem eklemeniz yeterlidir:

dataGridView1.DataSource = MyList.ToList();

0

Bunu deneyebilirsiniz, sütunların sırasını fazla önemsemezsiniz.

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

0

Örneğin, Windows Forms'daki ClickCell Etkinliği için.

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);
                }

Saygılarımızla :)


0

Birisi C # kullanıyorsa (veya aşağıdaki VB.NET hakkında Not'a bakın) ve bu noktaya ulaştıysa, ancak hala takılı kalıyorsa, lütfen okumaya devam edin.

Yeşu'nun yanıtı bana yardımcı oldu ama tam olarak değil. Peter'ın "Düğmeyi nereden alırdınız?" Diye sorduğunu fark edeceksiniz, ancak yanıtlanmadı.

Benim için çalışmanın tek yolu, olay işleyicimi eklemek için aşağıdakilerden birini yapmaktı (DataGridView Veritabanımı DataTable'ım ayarladıktan sonra ve DataGridViewButtonColumn'u DataGridView'a ekledikten sonra):

Ya:

dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);

veya:

dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);

Ardından, yukarıdaki çeşitli yanıtlarda gösterilen işleyici yöntemini (dataGridView1_CellClick veya dataGridView1_CellContentClick) ekleyin.

Not: VB.NET bu açıdan C # 'dan farklıdır, çünkü yöntemimizin imzasına yalnızca bir Handles yan tümcesi ekleyebilir veya Microsoft doc'ın " Nasıl yapılır: Visual Basic'te Olay İşleyicisi Çağırma "


0

DataGridView içine böyle bir düğme sütunu ekleyeceksiniz

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


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

Ardından, hücre tıklama etkinliğinin içine bazı işlemler ekleyebilirsiniz. Bunu yapmanın en kolay yolu olduğunu gördüm.

    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.
         }


    }

Cell Click etkinliğinin sık sık otomatik olarak abone olduğunu gördüm. Bu yüzden aşağıda bu koda ihtiyacım yoktu. Ancak, hücre tıklama etkinliğiniz abone değilse, dataGridView için bu kod satırını ekleyin.

     this.dataGridView.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellClick);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.