Datagridview comboboxcolumn每行的值不同

Moh*_*mad 3 c# winforms datagridviewcomboboxcell

我想使用c#使用comboboxcolumns创建一个datagridview.

问题是我不知道如何为每行中的组合框提供不同的值.

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];
}
Run Code Online (Sandbox Code Playgroud)

此示例提供以下结果:

对于每一行:

comboboxcolumnstate:

a1
a1
a2
a2
a3
Run Code Online (Sandbox Code Playgroud)

comboboxcolumncity:

b1
b2
b3
b4
b5
Run Code Online (Sandbox Code Playgroud)

我知道这是正常的,因为我正在循环数据表.

那我怎么能得到这个结果:

第1行:comboboxcolumnstate comboboxcolumncity

             a1               b1 - b2
Run Code Online (Sandbox Code Playgroud)

第2行:comboboxcolumnstate comboboxcolumncity

             a2               b3 - b4
Run Code Online (Sandbox Code Playgroud)

第2行:comboboxcolumnstate comboboxcolumncity

             a3               b5
Run Code Online (Sandbox Code Playgroud)

我是C#的新手.我搜索了很多,但我没有找到解决这个问题的解决方案.谢谢

TaW*_*TaW 8

这是一个可以帮助您入门的示例代码.

首先,我为每个州创建一个值列表(城市).为此,该 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);
}
Run Code Online (Sandbox Code Playgroud)

我在你的桌子上循环,每一行都为城市添加一个新条目,如有必要,还为该州添加.

现在我们修改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;
}
Run Code Online (Sandbox Code Playgroud)

注意:这会设置DropDowns中的值,但是在"状态"列中每次更改后,您都需要调整该行中的"城市"列!因此,通过将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];
}
Run Code Online (Sandbox Code Playgroud)

请注意,cityCell.Value只有在离开已编辑的单元格后才会显示新内容!

最后注意事项:如果您确实希望每个状态只显示一行,则需要更改填充DGVto循环的循环,而不是在表上,而是在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;
}
Run Code Online (Sandbox Code Playgroud)