トップ回答者
dataGridViewの行ヘッダー右クリックでメニューが出ないのはなぜ?

質問
-
行を選択して行ヘッダーで右クリックしたとの「行削除」メニューの表示のことでお教え願います。
下のコードでは,行を削除した後に再び行を削除しようとしたときには,<右クリックしてもメニューが表示されない>という不具合が生じていまいます。この不具合の原因と対処の仕方を知りたいと思います。どうぞよろしくお願いします。
//-- 行ヘッダにContextMenuStrip1を関連付け foreach (DataGridViewRow row in suitoDataGridView.Rows) { row.HeaderCell.ContextMenuStrip = contextMenuStrip1; } //////////////////////////////////////////////////////////// private void 行削除ToolStripMenuItem_Click(object sender, EventArgs e) { //削除するかどうか DialogResult dlgRet; dlgRet = MessageBox.Show("削除しますか?", "選択行削除", MessageBoxButtons.YesNo, MessageBoxIcon.Question); switch (dlgRet ) { case DialogResult.Yes : //選択されているすべての行を削除する DataGridView dgv = (DataGridView)suitoDataGridView; int del = 0; foreach (DataGridViewRow r in dgv.SelectedRows) { if (!r.IsNewRow) { dgv.Rows.Remove(r); del++; } } this.Validate(); this.groupSuitoBindingSource.EndEdit(); this.groupSuitoTableAdapter.Update(this.suitoDataSet6.groupSuito); //削除結果 MessageBox.Show(del.ToString() + " 行のデータを\n削除しました。", "削除結果"); suitoDataSet6.Clear(); this.groupSuitoTableAdapter.Fill(this.suitoDataSet6.groupSuito); break; case DialogResult.No : break; } }
zen73
回答
-
一度目はコンテキストメニューが表示されて削除することができ、二度目はコンテキストメニューが表示されないということでよろしいでしょうか? であれば、
//-- 行ヘッダにContextMenuStrip1を関連付け
foreach (DataGridViewRow row in suitoDataGridView.Rows)
{
row.HeaderCell.ContextMenuStrip = contextMenuStrip1;
}が二度目にうまく実行されていないのではないでしょうか?
ところで、余計なお世話かもしれませんが、直感的には複数行を選択したのち、行のどの部分を右クリックしてもコンテキストメニューが出るようにした方が良いように思います。つまり、DataGridViewのContextMenuStripプロパティに contextMenuStrip1をセットします。先走ってしまいますが、参考として、右クリックで行を選択するには以下のようにします。趣旨に合わなければ流して下さい。
private void dataGridView1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) //左ボタンが押された時は、CTRLやSHIFTと組み合わせて、複数行を選択できるようにするため。 { DataGridView.HitTestInfo hti = ((DataGridView)sender).HitTest(e.X, e.Y); if (hti.Type == DataGridViewHitTestType.Cell) ((DataGridView)sender).CurrentCell = ((DataGridView)sender)[hti.ColumnIndex, hti.RowIndex]; } }
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/- 回答としてマーク zen73 2010年8月16日 18:58
すべての返信
-
一度目はコンテキストメニューが表示されて削除することができ、二度目はコンテキストメニューが表示されないということでよろしいでしょうか? であれば、
//-- 行ヘッダにContextMenuStrip1を関連付け
foreach (DataGridViewRow row in suitoDataGridView.Rows)
{
row.HeaderCell.ContextMenuStrip = contextMenuStrip1;
}が二度目にうまく実行されていないのではないでしょうか?
ところで、余計なお世話かもしれませんが、直感的には複数行を選択したのち、行のどの部分を右クリックしてもコンテキストメニューが出るようにした方が良いように思います。つまり、DataGridViewのContextMenuStripプロパティに contextMenuStrip1をセットします。先走ってしまいますが、参考として、右クリックで行を選択するには以下のようにします。趣旨に合わなければ流して下さい。
private void dataGridView1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) //左ボタンが押された時は、CTRLやSHIFTと組み合わせて、複数行を選択できるようにするため。 { DataGridView.HitTestInfo hti = ((DataGridView)sender).HitTest(e.X, e.Y); if (hti.Type == DataGridViewHitTestType.Cell) ((DataGridView)sender).CurrentCell = ((DataGridView)sender)[hti.ColumnIndex, hti.RowIndex]; } }
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/- 回答としてマーク zen73 2010年8月16日 18:58
-
解決済みですが、もうひとつの方法を書かせてもらいます。
suitoDataGridView はバインドして使用されているのですよね?
以下はその場合の話です。
Cell のプロパティは、ListChangedType.Reset などの様々なタイミングで初期化されます。
たとえば以下のようにすると、削除操作によって●が消えることを確認できると思います。
(この動作はバインド時の仕様によるものだと思います。)
foreach (DataGridViewRow row in suitoDataGridView.Rows)
{
row.HeaderCell.ContextMenuStrip = contextMenuStrip1;
row.HeaderCell.Value = "●";
}
コンテキストメニューを任意のセルで表示する手段として、CellContextMenuStripNeeded イベントが用意されています。
private void dataGridView1_CellContextMenuStripNeeded(
object sender, DataGridViewCellContextMenuStripNeededEventArgs e)
{
// RowHeader の場合にメニューを表示します。
if (e.ColumnIndex == -1 && e.RowIndex != -1)
e.ContextMenuStrip = contextMenuStrip1;
}