2

C# (.NET 4.0) で小さなアプリケーションを作成しています。私は datagridview を持っています。各行は 1 つのオブジェクトを表します。そのオブジェクトの特定のプロパティを選択できるコンボボックス列が必要です。

例:

public class Car
{
   public String Make {get; set;}
   public BindingList<String> AllColors {get; set;}
   public int SelectedColorIndex {get; set;}
}

各行は 1 つの Car オブジェクトを表します。各 (異なる) 車のオブジェクトには、可能な色 (AllColors) の独自の選択があります。AllColors から色の 1 つを選択して SelectedColorIndex を設定できる列が必要です (AllColors は各 Car オブジェクトに固有です)。

注: この例は私が作成したものですが、私が達成したいことを説明しています。

どうすればこれを達成できますか? 私が見つけた唯一の解決策は、選択した行を変更できる特定のコンボボックスをデータグリッドビューの外に置くことでした。行入力イベントで、バインディングソースのデータソースを現在の「AllColors」に変更しました。

お時間とご回答ありがとうございます。

4

1 に答える 1

3

以下は、使用可能な色が、バインドされたオブジェクトの AllColors リストで提供される色にフィルターされる実際の例のコード ビハインドです。

CellBeginEditイベント ハンドラとイベント ハンドラで魔法が起こりCellEndEditます。各コンボ ボックス セルにバインドされた行のリストを提供し、終了時にリセットします。

これが依存していることの 1 つは、すべての色を含むマスター リストを持っていることです。これを回避する方法はありません。

また、新しい行にデフォルト値が必要な場合の処理​​を追加しました。選択したインデックスをデフォルトで 1 に設定するだけです。もちろん、これは現実の世界では機能しません。もう少しスマートなものが必要です。このDefaultValuedNeededイベントはMSDNで説明されています。

public partial class Form1 : Form
{

    private BindingSource cars;
    private BindingSource masterColors;

    public Form1()
    {
        InitializeComponent();

        masterColors = new BindingSource();
        masterColors.Add(new CarColor{Name = "Blue", Index = 1});
        masterColors.Add(new CarColor{Name = "Red", Index = 2});
        masterColors.Add(new CarColor { Name = "Green", Index = 3 });
        masterColors.Add(new CarColor { Name = "White", Index = 4 });

        BindingList<CarColor> fordColors = new BindingList<CarColor>();
        fordColors.Add(new CarColor{Name = "Blue", Index = 1});
        fordColors.Add(new CarColor{Name = "Red", Index = 2});

        BindingList<CarColor> toyotaColors = new BindingList<CarColor>();
        toyotaColors.Add(new CarColor { Name = "Green", Index = 3 });
        toyotaColors.Add(new CarColor { Name = "White", Index = 4 });

        cars = new BindingSource();
        cars.Add(new Car { Make = "Ford", SelectedColorIndex = 1, AllColors = fordColors });
        cars.Add(new Car { Make = "Toyota", SelectedColorIndex = 3, AllColors = toyotaColors });

        dataGridView1.DataSource = cars;
        dataGridView1.Columns["SelectedColorIndex"].Visible = false;
        //dataGridView1.Columns["AllColors"].Visible = false;

        DataGridViewComboBoxColumn col = new DataGridViewComboBoxColumn();
        col.Name = "AvailableColors";
        col.DataSource = masterColors;
        col.DisplayMember = "Name";
        col.DataPropertyName = "SelectedColorIndex";
        col.ValueMember = "Index";
        dataGridView1.Columns.Add(col);

        dataGridView1.CellBeginEdit += new DataGridViewCellCancelEventHandler(dataGridView1_CellBeginEdit);
        dataGridView1.CellEndEdit += new DataGridViewCellEventHandler(dataGridView1_CellEndEdit);
        dataGridView1.DefaultValuesNeeded += new DataGridViewRowEventHandler(dataGridView1_DefaultValuesNeeded);
    }

    void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
    {
        if (e.ColumnIndex == dataGridView1.Columns["AvailableColors"].Index)
        {
            if (e.RowIndex != dataGridView1.NewRowIndex)
            {
                // Set the combobox cell datasource to the filtered BindingSource
                DataGridViewComboBoxCell dgcb = (DataGridViewComboBoxCell)dataGridView1
                                [e.ColumnIndex, e.RowIndex];
                Car rowCar = dataGridView1.Rows[e.RowIndex].DataBoundItem as Car;
                dgcb.DataSource = rowCar.AllColors;
            }

        }
    }

    private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    {
        if (e.ColumnIndex == dataGridView1.Columns["AvailableColors"].Index)
        {
            // Reset combobox cell to the unfiltered BindingSource
            DataGridViewComboBoxCell dgcb = (DataGridViewComboBoxCell)dataGridView1
                            [e.ColumnIndex, e.RowIndex];
            dgcb.DataSource = masterColors; //unfiltered
        }
    }

    void dataGridView1_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
    {
        e.Row.Cells["SelectedColorIndex"].Value = 1;
    }

}

public class Car
{
    public String Make { get; set; }
    public BindingList<CarColor> AllColors { get; set; }
    public int SelectedColorIndex { get; set; }
}

public class CarColor
{
    public String Name { get; set; }
    public int Index { get; set; }
}

1これを行う方法をDataGridView FAQから初めて学びました。これは、当時DataGridViewMicrosoftのプログラム マネージャーであった Mark Rideout によって書かれた優れたリソースです。FAQ の例は、別のコンボボックスに基づいてフィルタリングし、DataTables を使用しますが、原則は同じです。

于 2012-06-23T14:35:37.393 に答える