0

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イベントがスローされます。このイベントは、ユーザーが実際にそのセルをクリックしたことがない場合でも呼び出されます。

その結果、プログラムが起動すると、ユーザーがクリックしなくても最初のセルがチェックされます。私のデータグリッドビューは、次のようになります。

DataGridViewの初期セルがチェックされました

ユーザーのクリックからではなく、初期化中に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);
    }
}
4

3 に答える 3

2

この問題は、箱から出してすぐに発生しますDataGridView

DataBindingComplete標準の修正は、イベントハンドラーの間に選択変更ハンドラーをアタッチすることです。

于 2012-08-18T09:49:54.120 に答える
1

さて、フォームエディタを使用したときにそのようなイベントで問題が発生したことはありません。コンポーネントが描画されるまで、イベントは呼び出されません。

プログラムでチェックボックスをオンにする前に、イベントハンドラーを追加しているためだと思います。したがって、それはあなた自身のコードによって引き起こされています。いくつかのデバッグメッセージを入れて、操作の順序を決定します。一部の関数を移動するのと同じくらい簡単かもしれません。

それ以外の場合は、イベントリスナーでsender.nameを出力して、ユーザーチェックとプログラムチェックの間で変更されるかどうかを確認してください。

私はそれが役立つことを願っています:)

〜ダン

于 2012-08-18T09:41:51.340 に答える
0

あなたが使用できる:

DataGridViewCheckBoxColumn cb = new DataGridViewCheckBoxColumn();
cb.Name = "The Name";
cb.HeaderText = "The Name";

dataGridView1.Columns.Add(cb);
row.Cells[2].Value = true;
dataGridView1.Rows[0].Cells[6].Value = true;
于 2012-12-26T12:00:04.323 に答える