[c#] DataGridView CheckBox 이벤트 변경을 감지하는 방법은 무엇입니까?

winforms 앱이 있고 DataGridView컨트롤에 포함 된 확인란 이 선택 / 선택 취소 될 때 일부 코드를 트리거하고 싶습니다 . 내가 시도한 모든 이벤트

  1. CheckBox클릭 하자마자 선택된 상태가 변경되기 전에 트리거됩니다.
  2. CheckBox초점을 잃은 경우에만 트리거됩니다.

확인 된 상태가 변경된 직후에 트리거되는 이벤트를 찾을 수없는 것 같습니다.


편집하다:

내가 달성하려는 CheckBox것은 하나 의 체크 상태가 DataGridView변경되면 다른 두 개의 데이터가 변경 된다는 것 DataGridView입니다. 그러나 내가 사용한 모든 이벤트, 다른 그리드의 데이터 CheckBox는 첫 번째 DataGridView초점을 잃은 후에 만 변경 됩니다.



답변

DatGridViews CheckedChanged이벤트 를 처리하려면 먼저 CellContentClickto fire ( CheckBoxes 현재 상태 가 없습니다 !)를 가져온 다음을 호출해야 CommitEdit합니다. 그러면 CellValueChanged작업을 수행하는 데 사용할 수 있는 이벤트가 시작됩니다. 이것은 Microsoft의 감독 입니다. 다음과 같은 일을하십시오 …

private void dataGridViewSites_CellContentClick(object sender,
    DataGridViewCellEventArgs e)
{
    dataGridViewSites.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

/// <summary>
/// Works with the above.
/// </summary>
private void dataGridViewSites_CellValueChanged(object sender,
    DataGridViewCellEventArgs e)
{
    UpdateDataGridViewSite();
}

이게 도움이 되길 바란다.

PS이 기사 확인 https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged(v=vs.110).aspx


답변

@Killercam의 솔루션이 작동하는 것을 찾았지만 사용자가 너무 빨리 두 번 클릭하면 약간 이상했습니다. 다른 사람도 그 사건을 발견했는지 확실하지 않습니다. 여기서 다른 해결책을 찾았 습니다 .

그것은 데이터 그리드의 CellValueChangedCellMouseUp. Changhong은 다음과 같이 설명합니다.

“그 이유는 DataGridView에서 편집이 완료되었다고 생각할 때까지 OnCellvalueChanged 이벤트가 실행되지 않기 때문입니다. OnCellvalueChanged가 각 키 입력에 대해 실행되지는 않기 때문에 TextBox 열에 대해 의미가 있지만 [ 이해하기] CheckBox. “

다음은 그의 예에서 나온 것입니다.

private void myDataGrid_OnCellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == myCheckBoxColumn.Index && e.RowIndex != -1)
    {
        // Handle checkbox state change here
    }
}

그리고 체크 박스에 사용자가 필드를 떠날 때까지 기다리지 않고 클릭하면 편집이 완료되었음을 알리는 코드 :

private void myDataGrid_OnCellMouseUp(object sender,DataGridViewCellMouseEventArgs e)
{
    // End of edition on each click on column of checkbox
    if (e.ColumnIndex == myCheckBoxColumn.Index && e.RowIndex != -1)
    {
        myDataGrid.EndEdit();
    }
}

편집 : DoubleClick 이벤트는 MouseUp 이벤트와 별도로 처리됩니다. DoubleClick 이벤트가 감지되면 애플리케이션은 첫 번째 MouseUp 이벤트를 완전히 무시합니다. 이 로직은 MouseUp 이벤트 외에도 CellDoubleClick 이벤트에 추가되어야합니다.

private void myDataGrid_OnCellDoubleClick(object sender,DataGridViewCellEventArgs e)
{
    // End of edition on each click on column of checkbox
    if (e.ColumnIndex == myCheckBoxColumn.Index && e.RowIndex != -1)
    {
        myDataGrid.EndEdit();
    }
}


답변

jsturtevants의 솔루션은 훌륭하게 작동했습니다. 그러나 EndEdit 이벤트에서 처리를 선택했습니다. CellValueChanged 이벤트와 달리 그리드를 채우는 동안 EndEdit 이벤트가 발생하지 않기 때문에 내 응용 프로그램에서이 방법을 선호합니다.

내 코드는 다음과 같습니다. 일부는 jsturtevant에서 도난당했습니다.

private void gridCategories_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == gridCategories.Columns["AddCategory"].Index)
    {
        //do some stuff
    }
}



private void gridCategories_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.ColumnIndex == gridCategories.Columns["AddCategory"].Index)
    {
        gridCategories.EndEdit();
    }
}


답변

이것은 또한 키보드 활성화를 처리합니다.

    private void dgvApps_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        if(dgvApps.CurrentCell.GetType() == typeof(DataGridViewCheckBoxCell))
        {
            if (dgvApps.CurrentCell.IsInEditMode)
            {
                if (dgvApps.IsCurrentCellDirty)
                {
                    dgvApps.EndEdit();
                }
            }
        }
    }


    private void dgvApps_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    {
          // handle value changed.....
    }


답변

다음 Killercam’answer, 내 코드

private void dgvProducts_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        dgvProducts.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }

및 :

private void dgvProducts_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    {
        if (dgvProducts.DataSource != null)
        {
            if (dgvProducts.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString() == "True")
            {
                //do something
            }
            else
            {
               //do something
            }
        }
    }


답변

다음은 몇 가지 코드입니다.

private void dgvStandingOrder_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (dgvStandingOrder.Columns[e.ColumnIndex].Name == "IsSelected" && dgvStandingOrder.CurrentCell is DataGridViewCheckBoxCell)
    {
        bool isChecked = (bool)dgvStandingOrder[e.ColumnIndex, e.RowIndex].EditedFormattedValue;
        if (isChecked == false)
        {
            dgvStandingOrder.Rows[e.RowIndex].Cells["Status"].Value = "";
        }
        dgvStandingOrder.EndEdit();
    }
}

private void dgvStandingOrder_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{

    dgvStandingOrder.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

private void dgvStandingOrder_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dgvStandingOrder.CurrentCell is DataGridViewCheckBoxCell)
    {
        dgvStandingOrder.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }
}


답변

셀 편집에 관한 것입니다. 실제로 셀이 편집되지 않은 문제이므로 확인란을 클릭 할 때 이벤트를 가져 오려면 셀 또는 행의 변경 사항을 저장해야이 기능을 사용할 수 있습니다.

datagridview.CommitEdit(DataGridViewDataErrorContexts.CurrentCellChange)

이것으로 다른 이벤트에도 사용할 수 있습니다.