Zajmuję się tworzeniem aplikacji dla systemu Windows w języku C #. ja używamDataGridView
do wyświetlania danych. Dodałem w tym kolumnę z przyciskami. Chcę wiedzieć, jak obsłużyć zdarzenie kliknięcia tego przycisku w DataGridView.
Zajmuję się tworzeniem aplikacji dla systemu Windows w języku C #. ja używamDataGridView
do wyświetlania danych. Dodałem w tym kolumnę z przyciskami. Chcę wiedzieć, jak obsłużyć zdarzenie kliknięcia tego przycisku w DataGridView.
Odpowiedzi:
Dodałeś przycisk do swojego DataGridView
i chcesz uruchomić kod po jego kliknięciu.
Łatwe peasy - po prostu wykonaj następujące kroki:
Po pierwsze, oto czego NIE robić:
Unikałbym sugestii zawartych w niektórych innych odpowiedziach tutaj, a nawet zawartych w dokumentacji MSDN, aby zakodować na stałe indeks kolumny lub nazwę kolumny w celu ustalenia, czy przycisk został kliknięty. Zdarzenie kliknięcia rejestruje całą siatkę, więc musisz w jakiś sposób ustalić, że przycisk został kliknięty, ale nie powinieneś tego robić, zakładając, że przycisk znajduje się w określonej nazwie lub indeksie kolumny ... jest łatwiejszy sposób ...
Uważaj też, które zdarzenie chcesz obsłużyć. Ponownie, dokumentacja i wiele przykładów zawiera błąd. Większość przykładów obsługuje CellClick
zdarzenie, które się uruchomi:
po kliknięciu dowolnej części komórki.
... ale będzie również uruchamiany po kliknięciu nagłówka wiersza . Wymaga to dodania dodatkowego kodu, aby po prostu określić, czy e.RowIndex
wartość jest mniejsza niż 0
Zamiast tego zajmij się tym, CellContentClick
co występuje tylko:
po kliknięciu zawartości w komórce
Z jakiegoś powodu nagłówek kolumny jest również uważany za „zawartość” w komórce, więc nadal będziemy musieli to sprawdzić poniżej.
Oto, co powinieneś zrobić:
Najpierw obsadź nadawcę na typ, DataGridView
aby ujawnić jego wewnętrzne właściwości w czasie projektowania. Możesz zmodyfikować typ parametru, ale czasami może to utrudnić dodawanie lub usuwanie programów obsługi.
Następnie, aby zobaczyć, czy przycisk został kliknięty, po prostu sprawdź, czy kolumna podnosząca zdarzenie jest typu DataGridViewButtonColumn
. Ponieważ już przerzuciliśmy nadawcę na typ DataGridView
, możemy pobrać Columns
kolekcję i wybrać bieżącą kolumnę za pomocą e.ColumnIndex
. Następnie sprawdź, czy ten obiekt jest typuDataGridViewButtonColumn
.
Oczywiście, jeśli chcesz rozróżnić wiele przycisków na siatkę, możesz wybrać na podstawie nazwy kolumny lub indeksu, ale nie powinno to być pierwsze sprawdzenie. Zawsze upewnij się, że najpierw kliknięto przycisk, a następnie odpowiednio obsłuż wszystko inne. W większości przypadków, gdy masz tylko jeden przycisk na siatkę, możesz od razu wskoczyć do wyścigów.
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
Jeśli chcesz się trochę zabawić, możesz dodać własne zdarzenie, które będzie wywoływane za każdym razem, gdy klikniesz przycisk na DataGrid. Nie możesz dodać go do samego DataGrid bez bałaganu z dziedziczeniem itp., Ale możesz dodać zdarzenie niestandardowe do formularza i uruchomić je w razie potrzeby. To trochę więcej kodu, ale zaletą jest to, że oddzieliłeś, co chcesz zrobić po kliknięciu przycisku, z tym, jak określić, czy przycisk został kliknięty.
Wystarczy zadeklarować zdarzenie, podnieść je w razie potrzeby i obsłużyć. Będzie to wyglądać tak:
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
Byłoby wspaniale, gdybyśmy pracowali z siatką, która po prostu robi to za nas. Możemy łatwo odpowiedzieć początkowe pytanie: you've added a button to your DataGridView and you want to run some code when it's clicked
. Oto podejście, które rozszerza DataGridView
. Może nie być warte kłopotów z koniecznością dostarczania niestandardowej kontrolki do każdej biblioteki, ale przynajmniej maksymalnie wykorzystuje ona kod używany do określania, czy przycisk został kliknięty.
Po prostu dodaj to do swojego zespołu:
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
Otóż to. Nigdy więcej tego nie dotykaj. Upewnij się, że DataGrid jest typu, DataGridViewExt
który powinien działać dokładnie tak samo, jak DataGridView. Z wyjątkiem tego, że spowoduje to również dodatkowe zdarzenie, które możesz obsłużyć w ten sposób:
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); } } }
To jest pełne odpowiedzi tutaj dla WinForms: DataGridViewButtonColumn Class
i tutaj: instrukcje: odpowiadanie na zdarzenia przycisków w kontrolce GridView
dla Asp.Net w zależności od kontrolki, której faktycznie używasz. (Twoje pytanie brzmi DataGrid, ale tworzysz aplikację dla systemu Windows, więc kontrolka, której będziesz używać, to DataGridView ...)
dataGridView1_CellClick
do tego kodu. Czy możesz zaktualizować swoją odpowiedź i podać mi jej opis.
Oto lepsza odpowiedź:
Nie można zaimplementować zdarzenia kliknięcia przycisku dla komórek przycisku w DataGridViewButtonColumn. Zamiast tego używasz zdarzenia CellClicked DataGridView i określasz, czy zdarzenie zostało uruchomione dla komórki w DataGridViewButtonColumn. Użyj właściwości DataGridViewCellEventArgs.RowIndex zdarzenia, aby dowiedzieć się, który wiersz został kliknięty.
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);
}
}
znaleziono tutaj: zdarzenie kliknięcia przycisku w datagridview
Trochę późno do tabeli tutaj, ale w C # (vs2013) nie musisz też używać nazw kolumn, w rzeczywistości wiele dodatkowej pracy, którą niektórzy proponują, jest całkowicie niepotrzebnych.
Kolumna jest faktycznie tworzona jako element członkowski kontenera (formularz lub kontrolka użytkownika, w której umieściłeś DataGridView). Z kodu projektanta (rzeczy, których nie powinieneś edytować, chyba że projektant coś zepsuje), zobaczysz coś takiego:
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;
Więc w module obsługi CellContentClick, oprócz upewnienia się, że indeks wiersza nie wynosi 0, wystarczy sprawdzić, czy kliknięta kolumna jest faktycznie tą, którą chcesz, porównując odniesienia do obiektów:
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();
}
}
}
Zwróć uwagę, że piękno tego polega na tym, że wszelkie zmiany nazw zostaną przechwycone przez kompilator. Jeśli indeksujesz z nazwą tekstową, która się zmienia lub niepoprawnie wpisujesz wielkie litery, jesteś związany z problemami w czasie wykonywania. Tutaj faktycznie używasz nazwy obiektu, który projektant tworzy na podstawie podanej nazwy. Jednak kompilator zwróci uwagę na każdą niezgodność.
Oto mój fragment kodu uruchamiający zdarzenie kliknięcia i przekazujący wartość do innego formularza:
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();
}
}
Zakładając na przykład, że DataGridView
ma kolumny, jak podano poniżej, a jego elementy powiązane z danymi są typu PrimalPallet
, możesz użyć rozwiązania podanego poniżej.
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.
}
}
}
Bezpieczniej jest uzyskać dostęp do kolumn bezpośrednio, niż używać dataGridView1.Columns["MyColumnName"]
i nie ma potrzeby analizowania sender
do kolumny, DataGridView
ponieważ nie jest to potrzebne.
dobrze, ugryzę.
będziesz musiał zrobić coś takiego - oczywiście to cały metakod.
button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method)
to „przechwytuje” metodę IClicked_My_Button_method aż do zdarzenia Click przycisku. Teraz za każdym razem, gdy zdarzenie jest „uruchamiane” z poziomu klasy owner, nasza metoda również zostanie uruchomiona.
W IClicked_MyButton_method po kliknięciu umieszczasz wszystko, co chcesz.
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.
}
Szczegóły tutaj zależą od Ciebie, ale jeśli koncepcyjnie brakuje Ci czegoś jeszcze, daj mi znać, a postaram się pomóc.
Większość głosowanych rozwiązań jest błędna, ponieważ nie działa z kilkoma przyciskami w jednym rzędzie.
Najlepszym rozwiązaniem będzie następujący kod:
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");
}
}
po prostu dodaj ToList()
metodę na końcu listy, gdzie połącz się z datagridview DataSource:
dataGridView1.DataSource = MyList.ToList();
Możesz wypróbować ten, nie przejmowałbyś się zbytnio kolejnością kolumn.
private void TheGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (TheGrid.Columns[e.ColumnIndex].HeaderText == "Edit")
{
// to do: edit actions here
MessageBox.Show("Edit");
}
}
Na przykład dla zdarzenia ClickCell w 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);
}
Pozdrowienia :)
Jeśli ktoś używa C # (lub zobacz uwagę o VB.NET poniżej) i osiągnął ten punkt, ale nadal utknął, czytaj dalej.
Odpowiedź Joshuy pomogła mi, ale nie do końca. Zauważysz, że Peter zapytał „Skąd wziąłbyś guzik?”, Ale nie odpowiedział.
Jedynym sposobem, w jaki to zadziałało, było wykonanie jednej z następujących czynności, aby dodać moją obsługę zdarzeń (po ustawieniu DataSource mojego DataGridView do mojego DataTable i po dodaniu DataGridViewButtonColumn do DataGridView):
Zarówno:
dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);
lub:
dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);
Następnie dodaj metodę obsługi (dataGridView1_CellClick lub dataGridView1_CellContentClick) pokazaną w różnych odpowiedziach powyżej.
Uwaga: VB.NET różni się pod tym względem od języka C #, ponieważ możemy po prostu dodać klauzulę Handles do podpisu naszej metody lub wydać instrukcję AddHandler zgodnie z opisem w dokumencie „ How to: Call an Event Handler in Visual Basic ” firmy Microsoft.
Dodasz kolumnę przycisku, taką jak ta w swoim dataGridView
DataGridViewButtonColumn mButtonColumn0 = new DataGridViewButtonColumn();
mButtonColumn0.Name = "ColumnA";
mButtonColumn0.Text = "ColumnA";
if (dataGridView.Columns["ColumnA"] == null)
{
dataGridView.Columns.Insert(2, mButtonColumn0);
}
Następnie możesz dodać akcje do zdarzenia kliknięcia komórki. Przekonałem się, że to najłatwiejszy sposób.
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.
}
}
Zauważyłem, że zdarzenie Cell Click jest często subskrybowane automatycznie. Więc nie potrzebowałem tego kodu poniżej. Jeśli jednak zdarzenie kliknięcia komórki nie jest subskrybowane, dodaj ten wiersz kodu do swojego dataGridView.
this.dataGridView.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellClick);