C# 如何在DataGridView控件中实现级联组合框?
我需要在几个C# 如何在DataGridView控件中实现级联组合框?,c#,winforms,datagridview,cascadingdropdown,C#,Winforms,Datagridview,Cascadingdropdown,我需要在几个DataGridViews中实现级联组合框。作为概念证明,我将下面的代码放在一起。选择国家时,应填充3列(客户,国家,城市),但不起作用 有没有更好的方法来实现这一点并纠正我做错的事情 public partial class Form1 : Form { private List<Customer> customers; private List<Country> countries; private List<City>
DataGridView
s中实现级联组合框。作为概念证明,我将下面的代码放在一起。选择国家时,应填充3列(客户,国家,城市),但不起作用
有没有更好的方法来实现这一点并纠正我做错的事情
public partial class Form1 : Form
{
private List<Customer> customers;
private List<Country> countries;
private List<City> cities;
private ComboBox cboCountry;
private ComboBox cboCity;
public Form1()
{
InitializeComponent();
countries = GetCountries();
customers = GetCustomers();
SetupDataGridView();
}
private List<Customer> GetCustomers()
{
var customerList = new List<Customer>
{
new Customer {Id=1,Name = "Jo",Surname = "Smith"},
new Customer {Id=2,Name = "Mary",Surname = "Glog"},
new Customer {Id=3,Name = "Mark",Surname = "Bloggs"}
};
return customerList;
}
private List<Country> GetCountries()
{
var countryList = new List<Country>
{
new Country {Id=1,Name = "England"},
new Country {Id=2,Name = "Spain"},
new Country {Id=3,Name = "Germany"}
};
return countryList;
}
private List<City> GetCities(string countryName)
{
var cityList = new List<City>();
if (countryName == "England") cityList.Add(new City { Id = 1, Name = "London" });
if (countryName == "Spain") cityList.Add(new City { Id = 2, Name = "Madrid" });
if (countryName == "Germany") cityList.Add(new City { Id = 3, Name = "Berlin" });
return cityList;
}
private void SetupDataGridView()
{
dataGridView1.CellLeave += dataGridView1_CellLeave;
dataGridView1.EditingControlShowing += dataGridView1_EditingControlShowing;
DataGridViewTextBoxColumn colCustomer = new DataGridViewTextBoxColumn();
colCustomer.Name = "colCustomer";
colCustomer.HeaderText = "CustomerName";
DataGridViewComboBoxColumn colCountry = new DataGridViewComboBoxColumn();
colCountry.Name = "colCountry";
colCountry.HeaderText = "Country";
DataGridViewComboBoxColumn colCity = new DataGridViewComboBoxColumn();
colCity.Name = "colCity";
colCity.HeaderText = "City";
dataGridView1.Columns.Add(colCustomer);
dataGridView1.Columns.Add(colCountry);
dataGridView1.Columns.Add(colCity);
//Databind gridview columns
((DataGridViewComboBoxColumn)dataGridView1.Columns["colCountry"]).DisplayMember = "Name";
((DataGridViewComboBoxColumn)dataGridView1.Columns["colCountry"]).ValueMember = "Id";
((DataGridViewComboBoxColumn)dataGridView1.Columns["colCountry"]).DataSource = countries;
((DataGridViewComboBoxColumn)dataGridView1.Columns["colCity"]).DisplayMember = "Name";
((DataGridViewComboBoxColumn)dataGridView1.Columns["colCity"]).ValueMember = "Id";
((DataGridViewComboBoxColumn)dataGridView1.Columns["colCity"]).DataSource = cities;
foreach (Customer cust in customers)
{
dataGridView1.Rows.Add(cust.Name + " " + cust.Surname);
}
}
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
//register a event to filter displaying value of items column.
if (dataGridView1.CurrentRow != null && dataGridView1.CurrentCell.ColumnIndex == 2)
{
cboCity = e.Control as ComboBox;
if (cboCity != null)
{
cboCity.DropDown += cboCity_DropDown;
}
}
//Register SelectedValueChanged event and reset item comboBox to default if category changes
if (dataGridView1.CurrentRow != null && dataGridView1.CurrentCell.ColumnIndex == 1)
{
cboCountry = e.Control as ComboBox;
if (cboCountry != null)
{
cboCountry.SelectedValueChanged += cboCountry_SelectedValueChanged;
}
}
}
void cboCountry_SelectedValueChanged(object sender, EventArgs e)
{
//If category value changed then reset item to default.
dataGridView1.CurrentRow.Cells[2].Value = 0;
}
void cboCity_DropDown(object sender, EventArgs e)
{
string countryName = dataGridView1.CurrentRow.Cells[1].Value.ToString();
List<City> cities = new List<City>();
cities = GetCities(countryName);
cboCity.DataSource = cities;
cboCity.DisplayMember = "Name";
cboCity.ValueMember = "Id";
}
private void dataGridView1_CellLeave(object sender, DataGridViewCellEventArgs e)
{
if (cboCity != null) cboCity.DropDown -= cboCity_DropDown;
if (cboCountry != null)
{
cboCountry.SelectedValueChanged -= cboCountry_SelectedValueChanged;
}
}
}
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
}
public class City
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
公共部分类表单1:表单
{
私人名单客户;
私人名单国家;
私人名单城市;
私人组合框CBO国家;
私人组合框社区;
公共表格1()
{
初始化组件();
countries=GetCountries();
customers=GetCustomers();
SetupDataGridView();
}
私有列表GetCustomers()
{
var customerList=新列表
{
新客户{Id=1,Name=“Jo”,Name=“Smith”},
新客户{Id=2,Name=“Mary”,姓氏=“Glog”},
新客户{Id=3,Name=“Mark”,Name=“Bloggs”}
};
返回客户列表;
}
私人名单国家()
{
var countryList=新列表
{
新国家{Id=1,Name=“英格兰”},
新国家{Id=2,Name=“西班牙”},
新国家{Id=3,Name=“德国”}
};
返回国家列表;
}
私有列表GetCities(字符串countryName)
{
var cityList=新列表();
if(countryName==“England”)cityList.Add(新城{Id=1,Name=“伦敦”});
if(countryName==“西班牙”)cityList.Add(新城{Id=2,Name=“马德里”});
if(countryName==“Germany”)cityList.Add(新城市{Id=3,Name=“Berlin”});
返回城市列表;
}
私有void SetupDataGridView()
{
dataGridView1.CellLeave+=dataGridView1_CellLeave;
dataGridView1.EditingControlShowing+=dataGridView1\u EditingControlShowing;
DataGridViewTextBoxColumn colCustomer=新DataGridViewTextBoxColumn();
colCustomer.Name=“colCustomer”;
colCustomer.HeaderText=“CustomerName”;
DataGridViewComboBoxColumn colCountry=新DataGridViewComboxColumn();
colCountry.Name=“colCountry”;
colCountry.HeaderText=“国家”;
DataGridViewComboBoxColumn colCity=新DataGridViewComboxColumn();
colCity.Name=“colCity”;
colCity.HeaderText=“城市”;
dataGridView1.Columns.Add(colCustomer);
dataGridView1.Columns.Add(colCountry);
dataGridView1.Columns.Add(colCity);
//数据绑定gridview列
((DataGridViewComboxColumn)dataGridView1.Columns[“colCountry”]).DisplayMember=“Name”;
((DataGridViewComboxColumn)dataGridView1.Columns[“colCountry”]).ValueMember=“Id”;
((DataGridViewComboxColumn)dataGridView1.Columns[“colCountry”])。数据源=国家;
((DataGridViewComboxColumn)dataGridView1.Columns[“colCity”]).DisplayMember=“Name”;
((DataGridViewComboxColumn)dataGridView1.Columns[“colCity”]).ValueMember=“Id”;
((DataGridViewComboxColumn)dataGridView1.Columns[“colCity”])。数据源=城市;
foreach(客户中的客户)
{
dataGridView1.Rows.Add(cust.Name+“”+cust.姓氏);
}
}
私有void dataGridView1_EditingControlShowing(对象发送方,DataGridViewEditingControlShowingEventArgs e)
{
//注册一个事件以筛选项列的显示值。
如果(dataGridView1.CurrentRow!=null&&dataGridView1.CurrentCell.ColumnIndex==2)
{
cboCity=e.控件作为组合框;
如果(cboCity!=null)
{
cboCity.DropDown+=cboCity\u下拉列表;
}
}
//注册SelectedValueChanged事件,并在类别更改时将项目组合框重置为默认值
if(dataGridView1.CurrentRow!=null&&dataGridView1.CurrentCell.ColumnIndex==1)
{
cbocontry=e.控件作为组合框;
如果(cboCountry!=null)
{
cboCountry.SelectedValueChanged+=cboCountry\u SelectedValueChanged;
}
}
}
void cboCountry\u SelectedValueChanged(对象发送方,事件参数e)
{
//如果类别值更改,则将项目重置为默认值。
dataGridView1.CurrentRow.Cells[2]。值=0;
}
void cboCity_下拉列表(对象发送方、事件参数e)
{
字符串countryName=dataGridView1.CurrentRow.Cells[1].Value.ToString();
列表城市=新列表();
cities=GetCities(countryName);
cboCity.DataSource=城市;
cboCity.DisplayMember=“Name”;
cboCity.ValueMember=“Id”;
}
私有void dataGridView1_CellLeave(对象发送方,DataGridViewCellEventArgs e)
{
if(cboCity!=null)cboCity.DropDown-=cboCity\u DropDown;
如果(cboCountry!=null)
{
cboCountry.SelectedValueChanged-=cboCountry\u SelectedValueChanged;
}
}
}
公营国家
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
公营城市
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
公共类客户
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串姓氏{get;set;}
}
}我希望我能简单地用几行代码为您提供一个解决方案,但我可能需要发布一个完整的Visual Studio项目来用代码进行演示
这里的想法是,您不应该试图通过控件的事件来控制此类场景。相反,您应该致力于使用Windows窗体的数据绑定机制。通过将控件绑定到能够
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.EditingControlShowing +=new DataGridViewEditingControlShowingEventHandler(dataGridView1_EditingControlShowing);
DataGridViewComboBoxColumn curCol1 = new DataGridViewComboBoxColumn();
List<string> source1 = new List<string>() { "val1", "val2", "val3" };
curCol1.DataSource = source1;
DataGridViewComboBoxColumn curCol2 = new DataGridViewComboBoxColumn();
dataGridView1.Columns.Add(curCol1);
dataGridView1.Columns.Add(curCol2);
for (int i = 0; i <= 5; i++)
{
dataGridView1.Rows.Add();
dataGridView1[0, i].Value = source1[0];
changeSourceCol2((string)dataGridView1[0, i].Value, (DataGridViewComboBoxCell)dataGridView1[1, i]);
}
}
private void changeSourceCol2(string col1Val, DataGridViewComboBoxCell cellToChange)
{
if (col1Val != null)
{
List<string> source2 = new List<string>() { col1Val + "1", col1Val + "2", col1Val + "3" };
cellToChange.DataSource = source2;
cellToChange.Value = source2[0];
}
}
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView1.CurrentRow != null)
{
ComboBox col1Combo = e.Control as ComboBox;
if (col1Combo != null)
{
if (dataGridView1.CurrentCell.ColumnIndex == 0)
{
col1Combo.SelectedIndexChanged += col1Combo_SelectedIndexChanged;
}
}
}
}
private void col1Combo_SelectedIndexChanged(object sender, EventArgs e)
{
if (dataGridView1.CurrentCell.ColumnIndex == 0)
{
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
changeSourceCol2(dataGridView1.CurrentCell.Value.ToString(), (DataGridViewComboBoxCell)dataGridView1[1, dataGridView1.CurrentCell.RowIndex]);
}
}