DataGridViewを拡張する基本クラスがあります。
public abstract class MyDataGridView : DataGridView
次に、MyDataGridViewを拡張するクラスがあります。クラス定義とコンストラクターは次のとおりです。
// ::FunctionGridView
public class FunctionGridView : MyDataGridView
{
private static int NUM_COLUMNS = 12;
private static int NUM_ROWS = 1;
public FunctionGridView()
{
// call the method in the base class to setup the grid
setupGridView(NUM_ROWS, NUM_COLUMNS);
}
}
データグリッドに使用される列タイプはDataGridViewCheckBoxColumnです。列(基本クラスで定義)を設定するコードは次のとおりです。
// ::MyDataGridView
protected void setupGridView(int numRows, int numColumns)
{
for (int i = 0; i < numColumns; i++)
{
DataGridViewCheckBoxColumn column = new DataGridViewCheckBoxColumn();
column.Name = "Column" + (i + 1).ToString();
this.Columns.Add(column);
}
}
ユーザーがセルをクリックしてから、選択したセルのチェックボックスを切り替えたときに、 SelectionChangedイベントをキャッチしたいと思います。コールバックは、基本クラスのコンストラクターで次のように設定されます。
// ::MyDataGridView
// initialize the controls then add the event handler
public MyDataGridView()
{
initialize();
this.SelectionChanged += selectionChanged;
}
選択変更コールバックは次のように定義されます。
// ::MyDataGridView
// get the checkbox _checked_ value and toggle it for the selected cell
private void handleSelectionChanged(object sender, EventArgs e)
{
int currentRow = this.CurrentCell.RowIndex;
int currentColumn = this.CurrentCell.ColumnIndex;
bool cellChecked = (bool)this.Rows[currentRow].Cells[currentColumn].Value;
this.Rows[currentRow].Cells[currentColumn].Value = !cellChecked;
}
処理方法がわからない異常が1つあることを除いて、すべて正常に動作します。
プログラムが起動し、DataGridViewが作成されてパネルに追加されると、最初にRow [0].Cell[0]に対してSelectionChangedイベントがスローされます。このイベントは、ユーザーが実際にそのセルをクリックしたことがない場合でも呼び出されます。
その結果、プログラムが起動すると、ユーザーがクリックしなくても最初のセルがチェックされます。私のデータグリッドビューは、次のようになります。
ユーザーのクリックからではなく、初期化中にSelectionChangedコールバックがスローされているかどうかを判断し、チェックボックスの値を切り替えずにコールバックを終了する方法が必要ですか?
// ::MyDataGridView
private void selectionChanged(object sender, EventArgs e)
{
**// if (e.isInitializing()) return;**
....
....
}
Java ActionEventクラスで、 getSourceを呼び出して、イベントが他のソースではなくコントロールによってトリガーされたことを確認できることを思い出しているようです。C#に相当するものはありますか?
================================================== ============================
質問を単純にするために、基本的な名前を使用し、詳細のほとんどを省略しました。実際のクラス/基本クラス名は、FunctionKeyTimerおよびKeyTimer(基本クラス)です。それが役立つ場合は、クラス図と完全なソースコードを次に示します。
public abstract class KeyTimer : DataGridView
{
public static int WIDTH = 640;
public static int HEIGHT = 40;
private bool initialCheckedValue = false;
public KeyTimer()
{
initialize();
this.SelectionChanged += selectionChanged;
}
public KeyTimer(bool initialChecked)
{
this.initialCheckedValue = initialChecked;
initialize();
this.SelectionChanged += selectionChanged;
}
protected void setupGridView(int numRows, int numColumns, string columnNamePrefix)
{
for (int i = 0; i < numColumns; i++)
{
DataGridViewCheckBoxColumn column = new DataGridViewCheckBoxColumn();
column.Resizable = DataGridViewTriState.False;
column.SortMode = DataGridViewColumnSortMode.NotSortable;
column.Name = columnNamePrefix + (i + 1).ToString();
this.Columns.Add(column);
}
for (int i = 0; i < numRows; i++)
{
DataGridViewRow row = new DataGridViewRow();
this.Rows.Add(row);
}
foreach (DataGridViewRow row in this.Rows)
{
for (int i = 0; i < numColumns; i++)
{
row.Cells[i].Value = this.initialCheckedValue;
}
}
}
private void selectionChanged(object sender, EventArgs e)
{
int currentRow = this.CurrentCell.RowIndex;
int currentColumn = this.CurrentCell.ColumnIndex;
bool cellChecked = (bool)this.Rows[currentRow].Cells[currentColumn].Value;
this.Rows[currentRow].Cells[currentColumn].Value = !cellChecked;
}
private void initialize()
{
this.AllowUserToDeleteRows = false;
this.AllowUserToResizeColumns = false;
....
....
}
}
public class FunctionKeyTimer : KeyTimer
{
private static int NUM_COLUMNS = 12;
private static int NUM_ROWS = 1;
private static string COLUMN_NAME_PREFIX = "F";
public FunctionKeyTimer()
{
setupGridView(NUM_ROWS, NUM_COLUMNS, COLUMN_NAME_PREFIX);
}
}