3

C# を使用して、コンボボックス列を含むデータグリッドビューを作成したいと考えています。

問題は、各行のコンボボックスに異なる値を与える方法がわからないことです。

DataTable dt = new DataTable();
dt.Columns.Add("state");
dt.Columns.Add("city");
dt.Rows.Add("a1", "b1");
dt.Rows.Add("a1", "b2");
dt.Rows.Add("a2", "b3");
dt.Rows.Add("a2", "b4");
dt.Rows.Add("a3", "b5");
DataGridViewComboBoxColumn comboStates = new DataGridViewComboBoxColumn();
comboStates.HeaderText = "HeaderText_1";
this.dataGridView1.Columns.Insert(0, comboStates);
DataGridViewComboBoxColumn comboCities = new DataGridViewComboBoxColumn();
comboCities.HeaderText = "HeaderText_2";
this.dataGridView1.Columns.Insert(1, comboCities);

for (int i = 0; i < dt.Rows.Count; i++)
{
    dataGridView1.Rows.Add();
    comboStates.Items.Add(dt.Rows[i][0]);
        DataGridViewComboBoxCell stateCell = (DataGridViewComboBoxCell)    (dataGridView1.Rows[i].Cells[0]);
    stateCell.Value = comboStates.Items[i];
    comboCities.Items.Add(dt.Rows[i][1]);
    DataGridViewComboBoxCell cityCell = (DataGridViewComboBoxCell)(dataGridView1.Rows[i].Cells[1]);
    cityCell.Value = comboCities.Items[i];
}

この例では、次の結果が得られます。

行ごとに:

コンボボックス列状態:

a1
a1
a2
a2
a3

コンボボックスの列の市区町村:

b1
b2
b3
b4
b5

私はデータテーブルをループしているので、これは正常であることを知っています。

では、どうすればこの結果を得ることができますか:

row1: コンボボックス列状態 コンボボックス列市区町村

             a1               b1 - b2

row2: コンボボックス列状態 コンボボックス列市区町村

             a2               b3 - b4

row2: コンボボックス列状態 コンボボックス列市区町村

             a3               b5

私はC#が初めてです。よく検索しましたが、この問題を解決する解決策が見つかりませんでした。ありがとう

4

1 に答える 1

10

これは、開始するためのコード例です。

まず、各州の値 (都市) のリストを作成します。これには、 Dictionaryコレクションが便利です。

Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>();

for (int i = 0; i < dt.Rows.Count; i++)
{
    string state = dt.Rows[i][0].ToString();
    string city  = dt.Rows[i][1].ToString();

    if (! dict.Keys.Contains(state ))  dict.Add(state, new List<string>());
    dict[state].Add(city);
}

テーブルをループし、行ごとに都市の新しいエントリを追加し、必要に応じて州のエントリを追加します。

ここで、DGV の設定を変更して、それぞれの でそれらを使用ListsItemsますDataGridViewComboBoxCell

注: ここで重要なのは、!DataGridViewComboBoxCellsではなくを使用することです。DataGridViewComboBoxColumns

簡単にアクセスできるように、州と都市の値の文字列変数を再度作成します..

for (int i = 0; i < dt.Rows.Count; i++)
{
    string state = dt.Rows[i][0].ToString();
    string city = dt.Rows[i][1].ToString();
    dataGridView1.Rows.Add();
    DataGridViewComboBoxCell stateCell = 
                            (DataGridViewComboBoxCell)(dataGridView1.Rows[i].Cells[0]);
    stateCell.Items.AddRange(dict.Keys.ToArray());
    stateCell.Value = state;
    DataGridViewComboBoxCell cityCell = 
                            (DataGridViewComboBoxCell)(dataGridView1.Rows[i].Cells[1]);
    cityCell.Items.AddRange(dict[state].ToArray());
    cityCell.Value = city;
}

注: これにより、ドロップダウンの値が設定されますが、「州」列を変更するたびに、その行の「都市」列を調整する必要があります。したがって、それをクラス レベルに移動してDictionary 永続化し、そのような変更後に呼び出すことができる小さな関数を作成することをお勧めします。

この機能の例を次に示します。

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == 0)
        setCities(e.RowIndex, dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString());
}

void setCities(int row, string state)
{
    DataGridViewComboBoxCell cityCell = 
                           (DataGridViewComboBoxCell)(dataGridView1.Rows[row].Cells[1]);
    cityCell.Items.Clear();
    cityCell.Items.AddRange(dict[state].ToArray());
    cityCell.Value = cityCell.Items[0];
}

cityCell.Value編集したセルを離れた後にのみ、新しいものが表示されることに注意してください。

最後の注意: 状態ごとに 1 行だけを表示したい場合はDGV、テーブルではなくdict.Keysコレクションをループするループを変更する必要があります。

for (int i = 0; i <  dict.Keys.Count; i++)
{
    string state = dict.Keys.ElementAt(i);
    string city1 = dict[state][0].ToString();
    dataGridView1.Rows.Add();
    DataGridViewComboBoxCell stateCell = 
                            (DataGridViewComboBoxCell)(dataGridView1.Rows[i].Cells[0]);
    stateCell.Items.AddRange(dict.Keys.ToArray());
    stateCell.Value = state;
    DataGridViewComboBoxCell cityCell = 
                            (DataGridViewComboBoxCell)(dataGridView1.Rows[i].Cells[1]);
    cityCell.Items.AddRange(dict[state].ToArray());
    cityCell.Value = city1;
}
于 2014-11-29T12:28:04.177 に答える