チェックボックス列があるグリッドビューがあり、セルの値が切り替わったらすぐに描画イベントをトリガーしたい。 ValueChaged、CellEndEdit、BeginEditを試し、選択モードとしてCellSelectを選択しました。最初の2つのイベントについては、現在のセルから出たり、前後に移動したりするなど、編集モードの終了時にイベントがトリガーされました。それは奇妙な動作です。
セル値が変更されるとすぐにグリッドビューでイベントをトリガーするものはありますか?
宜しくお願いします、
私の同僚は、CurrentCellDirtyStateChangedイベントをトラップすることを推奨しています。 http://msdn.Microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged.aspx を参照してください。
CellContentClickイベントを使用して、ユーザーがチェックボックスをクリックしたことを確認します。ユーザーが同じセルにいる場合でも、複数回起動します。 1つの問題は、値が更新されず、チェックされていない場合は常に「false」を返すことです。トリックは、Valueプロパティの代わりにセルの.EditedFormattedValueプロパティを使用することです。 EditedFormattedValueはチェックマークで追跡し、CellContentClickが発生したときにValueが保持することを望んでいます。
タイマーは必要ありません。派手なものは不要です。CellContentClickイベントを使用し、EditedFormattedValueを調べて、チェックボックスがどの状態になったのか、どの状態になったのかを確認します。 EditedFormattedValue = trueの場合、チェックボックスがチェックされています。
別の方法は、CellContentClickイベント(セルのValueプロパティで現在の値を提供しない)を処理し、grid.CommitEdit(DataGridViewDataErrorContexts.Commit)を呼び出して値を更新し、次にCellValueChangedを発生させて、実際の(つまり正しい)DataGridViewCheckBoxColumn値。
private void grid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
grid.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
private void grid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
// do something with grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value
}
ターゲット.NETフレームワーク:2.0
私は同じ問題を抱えていましたが、別の解決策を思いつきました:
ユーザーがチェックボックスをクリックしても値が変わらないように、列またはグリッド全体を「読み取り専用」にした場合。
幸いなことに、DataGridView.CellClick
イベントは引き続き発生します。私の場合、cellClick
イベントで次のことを行います。
if (jM_jobTasksDataGridView.Columns[e.ColumnIndex].CellType.Name == "DataGridViewCheckBoxCell")
ただし、チェックボックス列が複数ある場合は、列名を確認できます。
その後、データセットのすべての変更/保存を自分で行います。
小さなアップデート.... EditedFormattedValue
の代わりにvalue
の代わりにvalue
を使用していることを確認してください。 value
が、最新のc#2010 expressで使用されているように、以下の方法でアクセスできます。
grdJobDetails.Rows[e.RowIndex].Cells[0].EditedFormattedValue
また、_CellValueChanged
少数で提案または使用されるイベントは、場合によっては使用可能でなければなりませんが、セルのすべてのチェック/チェック解除を探している場合は、必ず_CellContentClick
その他、通知ごとに毎回表示されるわけではない_CellValueChanged
が起動されます。つまり、同じチェックボックスが何度もクリックされても、起動されません_CellValueChanged
ただし、たとえば交互にクリックすると、2つのchekboxがあり、次々にクリック_CellValueChanged
イベントが発生しますが、通常、任意のセルがチェック/チェック解除されるたびに発生するイベントを探している場合は_CellValueChanged
は発生しません。
最終的にこの方法で実装しました
private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
{
if (dataGridView1[e.ColumnIndex, e.RowIndex].GetContentBounds(e.RowIndex).Contains(e.Location))
{
cellEndEditTimer.Start();
}
}
}
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{ /*place your code here*/}
private void cellEndEditTimer_Tick(object sender, EventArgs e)
{
dataGridView1.EndEdit();
cellEndEditTimer.Stop();
}
CellContentClickイベントにフックしてみてください。 DataGridViewCellEventArgsにはColumnIndexとRowIndexがあるため、ChecboxCellが実際にクリックされたかどうかを確認できます。このイベントの良い点は、実際のチェックボックス自体がクリックされた場合にのみ起動することです。チェックボックスの周りのセルの白い領域をクリックしても、起動しません。これにより、このイベントが発生したときにチェックボックスの値が変更されたことをほぼ保証できます。その後、Invalidate()を呼び出して描画イベントをトリガーし、必要に応じてEndEdit()を呼び出して行の編集の終了をトリガーできます。
「EditingControlShowing」イベントは、チェックボックスの値を変更しても発生しません。チェックボックスセルの表示スタイルは変わらないためです。
私が使用した回避策は次のとおりです。 (CellContentClickイベントを使用しました)
private void gGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (string.Compare(gGridView1.CurrentCell.OwningColumn.Name, "CheckBoxColumn") == 0)
{
bool checkBoxStatus = Convert.ToBoolean(gGridView1.CurrentCell.EditedFormattedValue);
//checkBoxStatus gives you whether checkbox cell value of selected row for the
//"CheckBoxColumn" column value is checked or not.
if(checkBoxStatus)
{
//write your code
}
else
{
//write your code
}
}
}
上記は私のために働いています。さらにサポートが必要な場合はお知らせください。
簡単な解決策を見つけました。
セルをクリックした後、セルのフォーカスを変更するだけです。
private void DGV_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == "Here checkbox column id or name") {
DGV.Item(e.ColumnIndex, e.RowIndex + 1).Selected = true;
//Here your code
}
}
(ckeckbox + 1)インデックスの列が存在するかどうかを確認することを忘れないでください。
CellClick
およびCellMouseClick
の回答はすべて間違っています。これは、キーボードでセルの値を変更でき、イベントが発生しないためです。また、CurrentCellDirtyStateChanged
は1回だけ起動します。つまり、同じボックスを複数回チェック/チェック解除すると、1つのイベントのみが取得されます。上記の回答のいくつかを組み合わせると、次の簡単な解決策が得られます。
private void dgvList_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgvList.CurrentCell is DataGridViewCheckBoxCell)
dgvList.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
private void dgvList_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
// Now this will fire immediately when a check box cell is changed,
// regardless of whether the user uses the mouse, keyboard, or touchscreen.
//
// Value property is up to date, you DO NOT need EditedFormattedValue here.
}
DataGridビューでcheckedChanged
イベントを使用する場合は、次のコードを使用します。
_private void grdBill_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
grdBill.CurrentCell = grdBill.Rows[grdBill.CurrentRow.Index].Cells["gBillNumber"];
}
private void grdBill_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
calcBill();
}
private void calcBill()
{
listBox1.Items.Clear();
for (int i = 0; i < grdBill.Rows.Count - 1; i++)
{
if (Convert.ToBoolean(grdBill.Rows[i].Cells["gCheck"].Value) == true)
{
listBox1.Items.Add(grdBill.Rows[i].Cells["gBillNumber"].Value.ToString());
}
}
}
_
ここでは、グリッドのgrdBill = DataGridView1, gCheck = CheckBox in GridView(First Column), gBillNumber = TextBox
(2列目)。
したがって、クリックごとにcheckchangedイベントを発生させたい場合は、最初にCellContentClickを実行します。ユーザーがテキストボックスをクリックすると発生し、次に現在のセルを次の列に移動します。したがって、CellEndEdit列が発生し、チェックボックスがチェックされているかどうか、およびリストボックスに「gBillNumber」を追加します(関数calcBill内)。
最初の2つの答えを組み合わせることで、必要なものが得られました。 CurrentCellDirtyStateChangedイベントを使用して、EditedFormattedValueを調べました。
private void dgv_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
DataGridView dgv = (DataGridView)sender;
DataGridViewCell cell = dgv.CurrentCell;
if (cell.RowIndex >= 0 && cell.ColumnIndex == 3) // My checkbox column
{
// If checkbox checked, copy value from col 1 to col 2
if (dgv.Rows[cell.RowIndex].Cells[cell.ColumnIndex].EditedFormattedValue != null && dgv.Rows[cell.RowIndex].Cells[cell.ColumnIndex].EditedFormattedValue.Equals(true))
{
dgv.Rows[cell.RowIndex].Cells[1].Value = dgv.Rows[cell.RowIndex].Cells[2].Value;
}
}
}
cellEndEditTimer.Start();
この行により、datagridviewはチェックボックスのリストを更新します
ありがとうございました。
バインドされていないコントロール(つまり、コンテンツをプログラムで管理します)を操作し、EndEdit()を使用せずに、CurrentCellDirtyStateChangedを一度だけ呼び出してから、二度と呼び出しません。しかし、EndEdit()でCurrentCellDirtyStateChangedが2回呼び出されることがわかりました(2番目はおそらくEndEdit()が原因ですが、チェックしませんでした)。
bool myGridView_DoCheck = false;
private void myGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (!myGridView_DoCheck)
{
myGridView_DoCheck = true;
myGridView.EndEdit();
// do something here
}
else
myGridView_DoCheck = false;
}