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

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



답변

에 버튼을 추가했으며 클릭 할 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


답변

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

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

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


답변

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

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의 버튼 클릭 이벤트


답변

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

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


답변

여기 테이블에 조금 늦었지만 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();
        }
    }
}

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


답변

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

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.