Я розробляю додаток для Windows за допомогою C #. Я використовую DataGridView
для відображення даних. Я додав у цьому стовпчик кнопок. Я хочу знати, як я можу обробляти події клацання на цій кнопці в DataGridView.
Я розробляю додаток для Windows за допомогою C #. Я використовую DataGridView
для відображення даних. Я додав у цьому стовпчик кнопок. Я хочу знати, як я можу обробляти події клацання на цій кнопці в DataGridView.
Відповіді:
Ви додали кнопку до свого DataGridView
і хочете запустити якийсь код при натисканні на нього.
Легкий горошок - просто виконайте наступні дії:
По-перше, ось що НЕ робити:
Я б уникнув пропозицій у деяких інших відповідях тут і навіть наданих документацією на MSDN для жорсткого кодування індексу чи назви стовпців, щоб визначити, чи натиснули кнопку. Подія натискання реєструється для всієї сітки, тож якимось чином потрібно визначити, що була натиснута кнопка, але цього не слід робити, вважаючи, що ваша кнопка живе у певній назві або індексі стовпця ... є простіший спосіб ...
Крім того, будьте уважні, з якою подією ви хочете вчинити. Знову ж таки, документація та багато прикладів помиляються. Більшість прикладів стосується CellClick
події, яка спричинить пожежу:
коли клацніть будь-яку частину комірки.
... але також запускатиметься кожного разу, коли натискається заголовок рядка . Це вимагає додавання додаткового коду, щоб просто визначити, чи є e.RowIndex
значення менше 0
Замість цього обробіть те, CellContentClick
що відбувається лише:
при натисканні на вміст у комірці
З будь-якої причини заголовок стовпця також вважається "вмістом" всередині комірки, тому нам все одно доведеться перевірити це нижче.
Отже, ось що вам потрібно зробити:
По-перше, відправте відправника типу, DataGridView
щоб відкрити його внутрішні властивості під час проектування. Ви можете змінити тип параметра, але це може часом зробити додавання або видалення обробників складним.
Далі, щоб побачити, чи натиснули кнопку, просто перевірте, чи відповідає тип стовпця, що піднімає подію DataGridViewButtonColumn
. Оскільки ми вже передали відправника для введення DataGridView
, ми можемо отримати Columns
колекцію та вибрати поточний стовпець за допомогою e.ColumnIndex
. Потім перевірте, чи є цей об’єкт типу DataGridViewButtonColumn
.
Звичайно, якщо вам потрібно розрізняти кілька кнопок на сітці, ви можете вибрати їх на основі назви стовпця чи індексу, але це не має бути вашою першою перевіркою. Завжди переконайтеся, що спочатку було натиснуто кнопку, а потім належним чином обробляйте будь-що інше. У більшості випадків, коли у вас є лише одна кнопка на сітці, ви можете стрибати прямо на перегони.
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
Якщо ви хотіли трохи повеселитися, ви можете додати свою власну подію, коли потрібно підняти кожен раз, коли натиснути кнопку на DataGrid. Ви не можете додати його до самої DataGrid, не заплутавшись у спадщині тощо, але ви можете додати спеціальну подію до своєї форми та запустити її, коли це доречно. Це трохи більше коду, але перевершення полягає в тому, що ви виділили те, що хочете зробити, коли натискаєте кнопку, і як визначити, чи натиснула кнопку.
Просто оголосіть подію, підніміть її, коли це доречно, і поводьтеся з нею. Це буде виглядати приблизно так:
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
Що було б чудово, якби ми працювали з сіткою, яка тільки робила ці речі для нас. Ми могли б відповісти на перше питання легко: you've added a button to your DataGridView and you want to run some code when it's clicked
. Ось підхід, який поширює стратегію DataGridView
. Можливо, не варто мати клопоту над тим, щоб доставляти користувальницький контроль з кожною бібліотекою, але принаймні це максимально повторно використовує код, який використовується для визначення того, чи було натиснуто кнопку.
Просто додайте це до своєї збірки:
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
Це воно. Ніколи не торкайтеся його знову. Переконайтеся, що ваш DataGrid має тип, DataGridViewExt
який повинен працювати точно так само, як DataGridView. Крім того, це також призведе до додаткової події, з якою ви можете впоратися так:
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); } } }
Це повністю відповів тут для WinForms: DataGridViewButtonColumn Class
і ось тут: Як: реагувати на події кнопки в контролі GridView
для Asp.Net залежно від контролю, який ви фактично використовуєте. (У вашому запитанні йдеться про DataGrid, але ви розробляєте додаток для Windows, тому управління, яке ви використовуєте там, є DataGridView ...)
dataGridView1_CellClick
у цей код. Чи можете ви оновити свою відповідь і дати мені деяку характеристику.
Ось краща відповідь:
Ви не можете реалізувати подію, натиснуту на кнопку, для комірок кнопки у колонці DataGridViewButtonColumn. Замість цього ви використовуєте подію CellClicked DataGridView і визначаєте, чи подія запускається для комірки вашої DataGridViewButtonColumn. Використовуйте властивість події DataGridViewCellEventArgs.RowIndex, щоб дізнатися, на який рядок було натиснуто.
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);
}
}
знайдено тут: подія натискання кнопки в перегляді даних
Трохи запізнюючись до таблиці тут, але в c # (vs2013) вам також не потрібно використовувати назви стовпців, адже багато зайвої роботи, яку деякі люди пропонують, зовсім непотрібна.
Стовпчик насправді створюється як член контейнера (форма або користувальницький контроль, у який ви помістили DataGridView). З коду дизайнера (речі, які ви не повинні редагувати, за винятком випадків, коли дизайнер щось ламає), ви побачите щось на кшталт:
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;
Отже, в обробнику CellContentClick, окрім того, щоб індекс рядків не дорівнював 0, потрібно просто перевірити, чи дійсно натиснута стовпець потрібна, порівнявши посилання на об'єкти:
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();
}
}
}
Зауважте, що краса цього в тому, що будь-які зміни імені будуть впіймані компілятором. Якщо ви індексуєте текстове ім’я, яке змінюється, або ви його неправильно використовуєте з великої літери, ви маєте проблеми з часом виконання. Тут ви фактично використовуєте назву об'єкта, який дизайнер створює на основі вказаного вами імені. Але будь-яка невідповідність буде доведена до уваги компілятором.
Ось мій фрагмент коду, щоб запустити подію натискання та передати значення іншій формі:
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();
}
}
Якщо припустити, наприклад DataGridView
, стовпці, як зазначено нижче, і елементи, пов'язані з даними, мають тип, PrimalPallet
ви можете використовувати рішення, наведене нижче.
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.
}
}
}
Безпечніше отримувати доступ до стовпців безпосередньо, ніж використовувати, dataGridView1.Columns["MyColumnName"]
і немає необхідності розбирати sender
їх, DataGridView
оскільки це не потрібно.
добре, я кусаю.
вам потрібно зробити щось подібне - очевидно, це весь метакод.
button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method)
який "зачіпає" метод IClicked_My_Button_method аж до події Клік. Тепер, кожного разу, коли подія буде "запущена" з класу власників, наш метод також буде запущений.
У методі IClicked_MyButton_method ви просто поміщаєте все, що хочете, щоб сталося при натисканні на нього.
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.
}
Фактичні деталі тут залежать від вас, але якщо ви ще чогось не вистачаєте, то концептуально пропустіть, повідомте мене, і я спробую допомогти.
Більшість проголосованих рішень є неправильним, оскільки не може працювати з кількома кнопками в одному ряду.
Найкращим рішенням буде наступний код:
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()
метод до кінця списку, де прив'язується до datagridview DataSource:
dataGridView1.DataSource = MyList.ToList();
Ви можете спробувати це, ви б мало переймалися упорядкуванням стовпців.
private void TheGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (TheGrid.Columns[e.ColumnIndex].HeaderText == "Edit")
{
// to do: edit actions here
MessageBox.Show("Edit");
}
}
Наприклад для ClickCell події у формах Windows.
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);
}
З повагою :)
Якщо хтось використовує C # (або див. Примітку про VB.NET нижче) і досяг цього, але все ще затримався, будь ласка, читайте далі.
Відповідь Джошуа мені допомогла, але далеко не всім шляхом. Ви помітите, що Петро запитував: "Звідки б ви взяли кнопку?", Але не відповів.
Єдиний спосіб, який він працював для мене, - це зробити одне з наступного, щоб додати мій посилання для подій (після встановлення джерела даних DataGridView до мого DataTable та після додавання DataGridViewButtonColumn до DataGridView):
Або:
dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);
або:
dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);
А потім додайте метод обробника (або dataGridView1_CellClick або dataGridView1_CellContentClick), показаний у різних відповідях вище.
Примітка: VB.NET в цьому відношенні відрізняється від C #, тому що ми можемо просто додати пункт підписки Handles до підпису нашого методу або видати заяву AddHandler, як описано в документі Microsoft " Як: викликати обробник подій у Visual Basic "
Ви додасте такий стовпець кнопок у свій dataGridView
DataGridViewButtonColumn mButtonColumn0 = new DataGridViewButtonColumn();
mButtonColumn0.Name = "ColumnA";
mButtonColumn0.Text = "ColumnA";
if (dataGridView.Columns["ColumnA"] == null)
{
dataGridView.Columns.Insert(2, mButtonColumn0);
}
Потім ви можете додати деякі дії всередині події клацання клітинки. Я знайшов, що це найпростіший спосіб зробити це.
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 часто підписується часто. Тому мені цей код нижче не потрібен. Однак якщо подія кліку вашої клітини не підписана, додайте цей рядок коду для свого dataGridView.
this.dataGridView.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellClick);