C# datagridview中的两个组合框

C# datagridview中的两个组合框,c#,datagridview,combobox,sqldatareader,C#,Datagridview,Combobox,Sqldatareader,我在windowsforms的datagridview中使用组合框 假设我在一个datagridview中有两个梳妆盒,所以我的问题是 如何根据此datagridview中另一个comboboxcolumn中的选定值在datagridview中填充ComboxColumn我想我有点晚了,但您应该做的是将值更改事件处理程序附加到列中。当您选择一个新值时,处理程序应该触发,然后使用传递给函数的参数来确定更改了哪一行,并更改该行中的第二个组合框。我会提供一个例子,但我几乎可以肯定你无论如何都不会回来看

我在windowsforms的datagridview中使用组合框 假设我在一个datagridview中有两个梳妆盒,所以我的问题是

如何根据此datagridview中另一个comboboxcolumn中的选定值在datagridview中填充ComboxColumn我想我有点晚了,但您应该做的是将值更改事件处理程序附加到列中。当您选择一个新值时,处理程序应该触发,然后使用传递给函数的参数来确定更改了哪一行,并更改该行中的第二个组合框。我会提供一个例子,但我几乎可以肯定你无论如何都不会回来看这个答案

编辑: 没想到你会真的回来,但这里有一个方法来实现动态组合框。但是,我不能说我对这个答案感到完全自豪,因为它不适用于数据绑定(您必须自己添加每一行并设置适当的初始值)。但至少这个解决方案可以为您指明正确的方向或新的方向

public partial class DualComboBoxGridViewForm : Form
{
    private Dictionary<Country, List<City>> locations;

    public DualComboBoxGridViewForm()
    {
        InitializeComponent();
        InitializeLocations();

        dataGridView1.Rows.Add(new DataGridViewRow());
    }

    private void InitializeLocations()
    {
        // Loading these from a database would be highly recommended, I 
        // just did it like this with a dictionary to it would be easier 
        // to show.
        locations = new Dictionary<Country, List<City>>();

        List<City> americanCities = new List<City>();
        americanCities.Add(new City { ID = 0, Name = "Please Select A City" });
        americanCities.Add(new City { ID = 1, Name = "Boston" });
        americanCities.Add(new City { ID = 2, Name = "New York" });

        List<City> japaneseCities = new List<City>();
        japaneseCities.Add(new City { ID = 0, Name = "Please Select A City" });
        japaneseCities.Add(new City { ID = 1, Name = "Tokyo" });
        japaneseCities.Add(new City { ID = 2, Name = "Kyoto" });

        locations.Add(new Country { ID = 0, Name = "Please Select A Country" }, new List<City>());
        locations.Add(new Country { ID = 1, Name = "USA" }, americanCities);
        locations.Add(new Country { ID = 2, Name = "Japan" }, japaneseCities);
    }

    private void InitializeDataGridView()
    {
        dataGridView1.AutoGenerateColumns = false;
        dataGridView1.EditingControlShowing += dataGridView1_EditingControlShowing;

        // Create columns
        DataGridViewTextBoxColumn eventNameColumn = new DataGridViewTextBoxColumn();
        eventNameColumn.HeaderText = "Event";

        DataGridViewComboBoxColumn countryComboBox = new DataGridViewComboBoxColumn();
        countryComboBox.Name = "Country";
        countryComboBox.HeaderText = "Country";
        countryComboBox.ValueMember = "ID";
        countryComboBox.DisplayMember = "Name";
        foreach (Country country in locations.Keys)
        {
            countryComboBox.Items.Add(country);
        }

        DataGridViewComboBoxColumn cityComboBox = new DataGridViewComboBoxColumn();
        cityComboBox.Name = "City";
        cityComboBox.HeaderText = "City";
        cityComboBox.ValueMember = "ID";
        cityComboBox.DisplayMember = "Name";

        dataGridView1.Columns.Add(eventNameColumn);
        dataGridView1.Columns.Add(countryComboBox);
        dataGridView1.Columns.Add(cityComboBox);
    }

    // Triggers when a column enters edit mode (new value not yet assigned).
    private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs args)
    {
        // we only want to change the city box if a country value is changed
        if (dataGridView1.CurrentCell.ColumnIndex == dataGridView1.Columns["Country"].Index)
        {
            ComboBox countryBox = args.Control as ComboBox;
            countryBox.SelectedIndexChanged += countryComboBox_SelectedIndexChanged;
        }
    }

    private void countryComboBox_SelectedIndexChanged(object sender, EventArgs args)
    {
        ComboBox box = sender as ComboBox;

        DataGridViewComboBoxCell cityCell = dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[dataGridView1.Columns["City"].Index] as
            DataGridViewComboBoxCell;
        cityCell.Items.Clear();
        foreach (City city in locations[box.SelectedItem as Country])
        {
            cityCell.Items.Add(city);
        }

        if (cityCell.Items.Count > 0)
        {
            cityCell.Value = cityCell.Items[0];
        }

        // Remove event handler to prevent memory leak
        box.SelectedIndexChanged -= countryComboBox_SelectedIndexChanged;
    }
}

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; }
}
公共部分类DualComboBoxGridViewForm:Form { 私人字典位置; 公共双ComboxGridViewForm() { 初始化组件(); 初始化位置(); 添加(新的DataGridViewRow()); } 私有无效初始化位置() { //我强烈建议从数据库加载这些文件 //只要用字典这样做就会更容易 //展示。 位置=新字典(); List americanCities=新列表(); Add(新城市{ID=0,Name=“请选择一个城市”}); Add(新城{ID=1,Name=“Boston”}); Add(纽约{ID=2,Name=“纽约”}); List japaneseCities=新列表(); Add(新城市{ID=0,Name=“请选择一个城市”}); Add(新城{ID=1,Name=“东京”}); Add(新城{ID=2,Name=“京都”}); 添加(新国家{ID=0,Name=“请选择一个国家”},新列表()); 添加(新国家{ID=1,Name=“USA”},美国城市); 添加(新国家{ID=2,Name=“Japan”},日本种); } private void initializedTagRidView() { dataGridView1.AutoGenerateColumns=false; dataGridView1.EditingControlShowing+=dataGridView1\u EditingControlShowing; //创建列 DataGridViewTextBoxColumn eventNameColumn=新DataGridViewTextBoxColumn(); eventNameColumn.HeaderText=“事件”; DataGridViewComboBoxColumn countryComboBox=新DataGridViewComboxColumn(); countryComboBox.Name=“Country”; countryComboBox.HeaderText=“国家”; countryComboBox.ValueMember=“ID”; countryComboBox.DisplayMember=“Name”; foreach(位置中的国家/地区。键) { countryComboBox.Items.Add(国家/地区); } DataGridViewComboxColumn cityComboBox=新DataGridViewComboxColumn(); cityComboBox.Name=“城市”; cityComboBox.HeaderText=“城市”; cityComboBox.ValueMember=“ID”; cityComboBox.DisplayMember=“Name”; dataGridView1.Columns.Add(eventNameColumn); dataGridView1.Columns.Add(countryComboBox); dataGridView1.Columns.Add(cityComboBox); } //当列进入编辑模式(尚未指定新值)时触发。 私有void dataGridView1_EditingControlShowing(对象发送方,DataGridViewEditingControlShowingEventArgs args) { //我们只希望在更改国家/地区值时更改城市框 如果(dataGridView1.CurrentCell.ColumnIndex==dataGridView1.Columns[“国家”].Index) { ComboBox countryBox=args.Control作为ComboBox; countryBox.SelectedIndexChanged+=countryComboBox\u SelectedIndexChanged; } } private void country组合框\u SelectedIndexChanged(对象发送方、事件args args) { ComboBox=发送方作为ComboBox; DataGridViewComboBoxCell cityCell=dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex]。单元格[dataGridView1.Columns[“City”].Index]为 DataGridViewComboxCell; cityCell.Items.Clear(); foreach(地点中的城市[box.SelectedItem as Country]) { cityCell.Items.Add(城市); } 如果(cityCell.Items.Count>0) { cityCell.Value=cityCell.Items[0]; } //删除事件处理程序以防止内存泄漏 box.SelectedIndexChanged-=国家组合框\u SelectedIndexChanged; } } 公营国家 { 公共int ID{get;set;} 公共字符串名称{get;set;} } 公营城市 { 公共int ID{get;set;} 公共字符串名称{get;set;} }
你的意思是网格中每行有两列组合框吗?请回答,因为这个问题很紧急谢谢你^ ^ ^@Denjamin我回来了,我正在等待你的回答Example@mohammedsameeh很抱歉,我没有找到让数据绑定正常工作的方法,但这相当棘手,因为需要在数据绑定时动态分配城市组合框。可以使用虚拟模式执行此操作,但只有在列未绑定时才能触发事件。解决方法之一是创建绑定到实际数据的隐藏列,并使一些可见的未绑定列显示下拉列表(只需使用EditingControlShowing之类的事件来更新隐藏的数据绑定列)。