Datagridview의 버튼 열에서 클릭 이벤트를 처리하는 방법은 무엇입니까?


136

C #을 사용하여 Windows 응용 프로그램을 개발 중입니다. DataGridView데이터를 표시하는 데 사용 하고 있습니다. 거기에 버튼 열을 추가했습니다. DataGridView의 해당 버튼에서 클릭 이벤트를 처리하는 방법을 알고 싶습니다.


1
프로그래밍 방식으로 버튼을 추가하고 있습니까?
XstreamINsanity

이 온라인에는 많은 답변이 있습니다. 특히 문제가되는 것은 무엇입니까?
Joshua Evensen

1
@Joshua 나는 그물에 많은 대답을 얻었지만 실제로 무엇을하고 언제 시작 해야하는지 전혀 알지 못했습니다. datagridview에 버튼을 추가했는데 클릭 이벤트를 처리하는 방법을 모릅니다.
Himadri

답변:


263

에 버튼을 추가했으며 클릭 할 DataGridView때 일부 코드를 실행하려고합니다.
쉬운 peasy-다음 단계를 따르십시오.

하지 말아야 할 것 :

먼저, 하지 말아야 할 것이 있습니다 :

여기에있는 다른 답변 중 일부는 제안하지 않으며 버튼을 클릭했는지 확인하기 위해 열 색인 또는 열 이름을 하드 코딩하기 위해 MSDN설명서에서 제공합니다 . 클릭 이벤트는 전체 그리드에 등록되므로 버튼이 클릭되었는지 확인해야하지만 버튼이 특정 열 이름이나 색인에 있다고 가정하여 그렇게하면 안됩니다 ... 더 쉬운 방법이 있습니다 ...

또한 처리하려는 이벤트를주의하십시오. 다시 말하지만, 문서와 많은 예제는 이것을 잘못 알고 있습니다. 대부분의 예제 CellClick는 발생 하는 이벤트를 처리합니다 .

셀의 일부를 클릭하면

...하지만 헤더를 클릭 할 때마다 실행됩니다. 따라서 e.RowIndex값이 0보다 작은 지 확인하기 위해 추가 코드를 추가해야합니다.

대신 CellContentClick발생 하는 것을 처리하십시오 .

셀 내의 내용을 클릭 할 때

어떤 이유로 든 헤더는 셀 내에서 '콘텐츠'로 간주되므로 아래에서 여전히 확인해야합니다.

복용량 :

그래서 당신이해야 할 일은 다음과 같습니다.

첫째, 캐스트 입력 할 보낸 사람 DataGridView이 디자인 타임에 내부 속성을의 노출. 매개 변수의 유형을 수정할 수 있지만 때로는 처리기를 추가하거나 제거하기가 까다로울 수 있습니다.

그런 다음 버튼을 클릭했는지 확인하려면 이벤트를 발생시키는 열이 유형인지 확인하십시오 DataGridViewButtonColumn. 우리는 이미 발신자를 type으로 캐스팅했기 때문에 컬렉션을 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

업데이트 1-맞춤 이벤트

약간의 재미를 원한다면 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

업데이트 2-확장 그리드

우리를 위해 이런 일을 한 그리드로 작업하는 것이 좋을 것입니다. 초기 질문에 쉽게 대답 할 수 있습니다 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가 DataGridView DataGridViewExt와 정확히 동일하게 작동하는 유형인지 확인하십시오 . 그것을 제외하고는 다음과 같이 처리 할 수있는 추가 이벤트가 발생합니다.

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

1
VB.net에서는 열 인덱스를 확인할 필요가 없습니다. 두 개의 열이있는 dgv 에이 정확한 예제를 사용하고 있습니다. 편집 가능한 하나의 열과 제거 버튼이있는 두 번째 열. dgv 전체를 클릭하면 버튼을 클릭하면 이벤트가 시작됩니다.
Luminous

3
+1. 그러나이 경우 열은 일반 DataGridViewColumn이며 셀 유형을 확인해야합니다.TypeOf senderGrid.Rows(e.RowIndex).Cells(e.ColumnIndex) Is DataGridViewButtonCell
Dave Johnson

공감대와 의견으로 판단하면 이것이 정답이라는 것을 이해하지만 ... 왜 모든 것이 항상 그렇게 복잡해야 하는가! 아직 WPF에 접근하지 않았지만 거기에서 동일합니까?
jj_

1
업데이트 2의 C # 코드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); } } }
Tony Cheetham

@ tonyenkiducx는 높이 평가했지만 주석은 전체 클래스의 대체 구문, 특히 코드 변환기를 통해 쉽게 파생 될 수있는 대체 구문을 보여주기에 좋은 장소는 아닙니다 . 물론 사람들은 C #을 찾고 여기에 와서 직접 횡단 보도를 작성할 수 있으며 구현을 찾고있는 주석을 탐색하지 않을 것입니다. 댓글을 삭제하는 것이 좋습니다.
KyleMit

15

그것은 WinForms에 대해 완전히 대답했습니다 : DataGridViewButtonColumn 클래스

여기에 : 방법 : GridView 컨트롤에서 버튼 이벤트에 응답

실제로 사용중인 컨트롤에 따라 Asp.Net의 경우 (질문에 DataGrid가 있지만 Windows 앱을 개발 중이므로 사용중인 컨트롤에 DataGridView가 있습니다 ...)


미안, 그건 내 실수 야 DataGridView를 사용하고 있습니다. 그리고 나는 이미 당신의 대답의 첫 번째 링크를 봅니다. 나는 dataGridView1_CellClick그 코드를 얻지 못했다 . 답변을 업데이트하고 설명을 해 주시겠습니까?
Himadri

10

더 나은 답변은 다음과 같습니다.

DataGridViewButtonColumn에서 버튼 셀에 대한 버튼 클릭 이벤트를 구현할 수 없습니다. 대신 DataGridView의 CellClicked 이벤트를 사용하여 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);
  }
}

여기에서 발견 : datagridview의 버튼 클릭 이벤트


8

이것은 내 문제를 해결합니다.

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

5

여기 테이블에 조금 늦었지만 c # (vs2013)에서는 열 이름을 사용할 필요가 없습니다. 실제로 일부 사람들이 제안하는 추가 작업은 완전히 필요하지 않습니다.

열은 실제로 컨테이너의 멤버 (DataGridView를 넣은 양식 또는 usercontrol)로 작성됩니다. 디자이너 코드 (디자이너가 무언가를 깨뜨릴 때를 제외하고 편집하지 말아야 할 것들)에서 다음과 같은 것을 보게 될 것입니다.

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

이의 아름다움이 있다는 것을 참고 있는 이름 변경이 컴파일러에 의해 잡힐 것입니다. 텍스트 이름이 변경되거나 잘못 대문자로 색인을 생성하면 런타임 문제가 발생합니다. 여기에서는 실제로 디자이너가 제공 한 이름을 기준으로 개체 이름을 사용합니다. 그러나 컴파일러가 불일치를 주목할 것입니다.


이 영리한 것에 대해, -1 것에 대해 너무 영리 :-) 이럴 그것은 나 같은 많은 사람들이 아직도 유래에 대한 답을 찾고 있기 때문에, 오래된 게시물에 댓글을 추가 늦지 않았어.
JonP

2

다음은 클릭 이벤트를 발생시키고 다른 양식에 값을 전달하는 코드 스 니펫입니다.

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

예를 들어 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.


0

좋아, 물어볼 게

이와 같은 작업을 수행해야합니다. 분명히 모든 메타 코드입니다.

button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method)

이는 IClicked_My_Button_method 메소드를 버튼의 Click 이벤트에 "후킹"합니다. 이제 이벤트가 소유자 클래스 내에서 "시작될 때마다"메소드도 시작됩니다.

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

실제 세부 사항은 귀하에게 달려 있지만 다른 것이 있으면 개념적으로 알려 주시면 도와 드리겠습니다.


당신이 원하는 곳 어디든 연결합니다. 일반적으로 말하면, 아마도 datagridview가 초기화 된 후에 폼의 생성자에 들어갈 것입니다.
Joshua Evensen

버튼은 어디서 구할 수 있습니까!?
피터-모니카 복직 자

0

한 행에 몇 개의 단추를 사용할 수 없으므로 대부분의 투표 솔루션이 잘못되었습니다.

가장 좋은 해결책은 다음 코드입니다.

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에 바인드하십시오.

dataGridView1.DataSource = MyList.ToList();

0

이 방법을 시도하면 열 순서에 신경 쓰지 않을 것입니다.

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

0

예를 들어 Windows Forms의 ClickCell 이벤트입니다.

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

감사합니다 :)


0

누군가 C #을 사용하고 있거나 아래 VB.NET에 대한 참고 사항을 참조했지만이 시점에 도달했지만 여전히 붙어있는 경우 계속 읽으십시오.

여호수아의 대답이 도움이되었지만 완전히 도움이되지는 않았습니다. Peter가 "어디에서 단추를 가져 옵니까?"라고 물었지만 대답하지 않았습니다.

그것이 나를 위해 일한 유일한 방법은 내 이벤트 처리기를 추가하기 위해 다음 중 하나를 수행하는 것입니다 (DataGridView의 DataSource를 DataTable로 설정 한 후 DataGridViewButtonColumn을 DataGridView에 추가 한 후).

어느 한 쪽:

dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);

또는:

dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);

그런 다음 위의 다양한 답변에 표시된 핸들러 메소드 (dataGridView1_CellClick 또는 dataGridView1_CellContentClick)를 추가하십시오.

참고 : "우리는 단순히 우리의 방법의 서명에 핸들 절을 추가 또는 Microsoft 문서의 설명대로 AddHandler에 문을 발행 할 수 있기 때문에 VB.NET,이 점에서 C #을 다른 : Visual Basic에서 이벤트 핸들러를 호출하는 방법으로 "


0

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


    }

셀 클릭 이벤트가 자동으로 자주 구독된다는 것을 알았습니다. 따라서 아래 코드가 필요하지 않았습니다. 그러나 셀 클릭 이벤트가 등록되지 않은 경우 dataGridView에이 코드 행을 추가하십시오.

     this.dataGridView.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellClick);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.