105

私はwinformsアプリを持っていて、コントロールに埋め込まれたチェックボックスDataGridViewがチェック/チェックされていないときにいくつかのコードをトリガーしたいと考えています. 私が試したすべてのイベント

  1. がクリックされるとすぐにトリガーされCheckBoxますが、チェック状態が変わる前に、または
  2. CheckBoxがフォーカスを失ったときにのみトリガーされます

チェック状態が変化した直後にトリガーされるイベントが見つからないようです。


編集:

私が達成しようとしているのは、1 つの のチェック状態がCheckBox変化すると、他の 2 つのs のDataGridViewデータが変化することです。DataGridViewしかし、私が使用したすべてのイベント、他のグリッドのデータはCheckBox、最初のグリッドがDataGridViewフォーカスを失った後にのみ変更されます。

4

19 に答える 19

118

DatGridViewsイベントを処理するには、CheckedChanged最初に を起動する必要がありますCellContentClick(これには es の現在の状態はありませんCheckBox!) から、 を呼び出します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

于 2012-08-07T10:42:28.083 に答える
95

@Killercamのソリューションが機能することがわかりましたが、ユーザーがダブルクリックするのが速すぎると少し危険でした. 他の人がそのケースを発見したかどうかはわかりません。ここで別の解決策を見つけました。

データグリッドのCellValueChangedとを使用しCellMouseUpます。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();
    }
}
于 2013-02-21T20:44:20.780 に答える
9

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();
    }
}
于 2014-10-06T22:18:00.850 に答える
6

Killercam の回答に続いて、私のコード

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
            }
        }
    }
于 2013-12-24T10:01:13.320 に答える
6

ここにいくつかのコードがあります:

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);
    }
}
于 2012-12-12T10:54:31.963 に答える
6

これは、キーボードのアクティブ化も処理します。

    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.....
    }
于 2014-07-06T22:12:10.217 に答える
2

セルを編集することがすべてです。セルが実際に編集されていないという問題があるため、セルまたは行の変更を保存して、チェックボックスをクリックしたときにイベントを取得して、この関数を使用できるようにする必要があります。

datagridview.CommitEdit(DataGridViewDataErrorContexts.CurrentCellChange)

これで違うイベントでも使えます。

于 2015-07-28T13:16:42.767 に答える
1

私にとってうまくいったのはCurrentCellDirtyStateChangeddatagridView1.EndEdit()

private void dataGridView1_CurrentCellDirtyStateChanged( object sender, EventArgs e ) {
    if ( dataGridView1.CurrentCell is DataGridViewCheckBoxCell ) {
        DataGridViewCheckBoxCell cb = (DataGridViewCheckBoxCell)dataGridView1.CurrentCell;
        if ( (byte)cb.Value == 1 ) {
            dataGridView1.CurrentRow.Cells["time_loadedCol"].Value = DateTime.Now.ToString();
        }
    }
    dataGridView1.EndEdit();
}
于 2013-08-28T04:38:21.577 に答える
1

コードは DataGridView でループし、CheckBox 列がチェックされているかどうかを確認します

private void dgv1_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.ColumnIndex == 0 && e.RowIndex > -1)
    {
        dgv1.CommitEdit(DataGridViewDataErrorContexts.Commit);
        var i = 0;
        foreach (DataGridViewRow row in dgv1.Rows)
        {
            if (Convert.ToBoolean(row.Cells[0].Value))
            {
                i++;
            }
        }

        //Enable Button1 if Checkbox is Checked
        if (i > 0)
        {
            Button1.Enabled = true;
        }
        else
        {
            Button1.Enabled = false;
        }
    }
}
于 2015-09-30T08:23:23.957 に答える
0

私は VirtualMode=true で DataGridView を使用していますが、このオプションのみが機能しました (マウスとスペースバーの両方が機能し、スペースのクリックが繰り返される場合):

private void doublesGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
   var data_grid = (DataGridView)sender;
      
   if (data_grid.CurrentCell.IsInEditMode && data_grid.IsCurrentCellDirty) {
      data_grid.EndEdit();            
   }
}

private void doublesGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
   if (e.ColumnIndex == CHECKED_COLUMN_NUM && e.RowIndex >= 0 && e.RowIndex < view_objects.Count) { // view_objects - pseudocode   
     view_objects[e.RowIndex].marked = !view_objects[e.RowIndex].marked;        // Invert the state of the displayed object
   }
}  
于 2020-12-10T09:46:29.383 に答える