0

州、郡、市のカスケード コンボボックス列。datagridview を使用して単純なフォームを作成しました。datagridview には、3 つのコンボボックス列 (州、郡、市) が含まれます。州を選択すると、郡コンボボックスにはその州内の郡のみが表示され、郡を選択すると、都市列には選択した州と郡内の都市のみが表示されます。州と郡をいつでも変更できるようにする必要があります。これにより、他の対応する列がリセットされます。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace StateCountyCityDataGridViewComboboxColumnIssue
{
    public partial class Form1 : Form
    {
        private DataTable dtStateCountyCity = new DataTable();

        public Form1()
        {
            InitializeComponent();

            dtStateCountyCity = CreateDataTable_StateCountyCity();

            var stateList = (from scc in dtStateCountyCity.AsEnumerable()
                             group scc by scc.Field<string>("state") into g
                             select new { State = g.Key }).ToList();

            dgvCmbColState.DataSource = stateList;
            dgvCmbColState.DisplayMember = "state";
            dgvCmbColState.ValueMember = "state";
        }

        public DataTable CreateDataTable_StateCountyCity()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("State", typeof(string));
            dt.Columns.Add("County", typeof(string));
            dt.Columns.Add("City", typeof(string));

            dt.Rows.Add("Michigan", "Oakland", "Royal Oak");
            dt.Rows.Add("Michigan", "Oakland", "Birmingham");
            dt.Rows.Add("Michigan", "Oakland", "Troy");
            dt.Rows.Add("Michigan", "Macomb", "Sterling Heights");
            dt.Rows.Add("Michigan", "Macomb", "Warren");
            dt.Rows.Add("Illinois", "Cook", "Chicago");
            dt.Rows.Add("Illinois", "Cook", "Alsip");
            dt.Rows.Add("Illinois", "Cook", "Oak Park");
            dt.Rows.Add("Illinois", "Clinton", "Albers");
            dt.Rows.Add("Illinois", "Clinton", "Aviston");


            return dt;        
        }

        private void CountyComboBox_DropDown(object sender, EventArgs e)
        {
            //Int64 xRefID = Convert.ToInt64(dgvDepartmentWorkersComp.CurrentRow.Cells[6].Value);
            if (dgvStateCountyCity.CurrentRow.Cells[0].Value != null)
            {
                string stateSelected = dgvStateCountyCity.CurrentRow.Cells[0].Value.ToString();
                DataRow[] drTempRows = dtStateCountyCity.Select("State = '" + stateSelected + "'");

                if (drTempRows != null && drTempRows.Length > 0)
                {
                    DataTable dtTemp = drTempRows.CopyToDataTable();

                    var countyList = (from tblCounty in dtTemp.AsEnumerable()
                                      group tblCounty by tblCounty.Field<string>("county") into g
                                     select new { County = g.Key }).ToList();

                    BindingSource bs = new BindingSource(countyList, "");

                    dgvCmbColCounty.DataSource = bs;
                    dgvCmbColCounty.DisplayMember = "County";
                    dgvCmbColCounty.ValueMember = "County";

                }
            }

        }

        private void CityComboBox_DropDown(object sender, EventArgs e)
        {
            //Int64 xRefID = Convert.ToInt64(dgvDepartmentWorkersComp.CurrentRow.Cells[6].Value);
            if (dgvStateCountyCity.CurrentRow.Cells[1].Value != null)
            {
                string countySelected = dgvStateCountyCity.CurrentRow.Cells[1].Value.ToString();
                DataRow[] drTempRows = dtStateCountyCity.Select("County = '" + countySelected + "'");

                if (drTempRows != null && drTempRows.Length > 0)
                {
                    DataTable dtTemp = drTempRows.CopyToDataTable();
                    BindingSource bs = new BindingSource(dtTemp, "");
                    dgvCmbColCity.DataSource = bs;
                    dgvCmbColCity.DisplayMember = "City";
                    dgvCmbColCity.ValueMember = "City";

                }
            }

        }

        private void StateSelectionChanged(object sender, EventArgs e)
        { 

        }

        private void dgvStateCountyCity_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            int stateColumnIndex = 0;
            int countyColumnIndex = 1;
            int cityColumnIndex = 2;

            if (e.Control is ComboBox)
            {
                if (dgvStateCountyCity.CurrentCell.ColumnIndex == countyColumnIndex)
                {
                    ComboBox CountyComboBox = e.Control as ComboBox;
                    if (CountyComboBox != null)
                    {
                        CountyComboBox.DropDown += new EventHandler(CountyComboBox_DropDown);
                    }
                }

                if (dgvStateCountyCity.CurrentCell.ColumnIndex == cityColumnIndex)
                {
                    ComboBox CityComboBox = e.Control as ComboBox;
                    if (CityComboBox != null)
                    {
                        CityComboBox.DropDown += new EventHandler(CityComboBox_DropDown);
                    }
                }

                //register selectedvaluechanged event and reset item combobox to default if category changes
                if (dgvStateCountyCity.CurrentCell != null && dgvStateCountyCity.CurrentCell.ColumnIndex == stateColumnIndex)
                {
                    ComboBox StateComboBox = e.Control as ComboBox;
                    if (StateComboBox != null)
                    {
                        StateComboBox.SelectedValueChanged += new EventHandler(StateSelectionChanged);
                    }
                }
            }
        }

        //Because filtering this way can make some cell have a value which is not contained in 
        //the DataGridViewComboBoxColumn.Items, we have to handle the DataError
        private void dgvStateCountyCity_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            //We're interested only in DataGridViewComboBoxColumn
            if (dgvStateCountyCity.Columns[e.ColumnIndex] is DataGridViewComboBoxColumn)
            {
                e.Cancel = true;
            }
        }

    }
}

誰がこれを完了するかについてのアイデアはありますか? 助けてくれてありがとう!

4

1 に答える 1

0

別の場所に隠された答えを見つけました。だから私は自分のコードを修正し、ここにあります。重要なのは、DataGridViewComboBoxCell を使用する必要があることです。これは完全に機能するサンプルです。好きなように、保証なしで使用してください。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace StateCountyCityDataGridViewComboboxColumnIssue
{
    public partial class Form1 : Form
    {
        private DataTable dtStateCountyCity = new DataTable();

        public Form1()
        {
            InitializeComponent();

            dtStateCountyCity = CreateDataTable_StateCountyCity();

            var stateList = (from scc in dtStateCountyCity.AsEnumerable()
                             group scc by scc.Field<string>("state") into g
                             select new { State = g.Key }).ToList();

            dgvCmbColState.DataSource = stateList;
            dgvCmbColState.DisplayMember = "state";
            dgvCmbColState.ValueMember = "state";
        }

        public DataTable CreateDataTable_StateCountyCity()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("State", typeof(string));
            dt.Columns.Add("County", typeof(string));
            dt.Columns.Add("City", typeof(string));

            dt.Rows.Add("Michigan", "Oakland", "Royal Oak");
            dt.Rows.Add("Michigan", "Oakland", "Birmingham");
            dt.Rows.Add("Michigan", "Oakland", "Troy");
            dt.Rows.Add("Michigan", "Macomb", "Sterling Heights");
            dt.Rows.Add("Michigan", "Macomb", "Warren");
            dt.Rows.Add("Illinois", "Cook", "Chicago");
            dt.Rows.Add("Illinois", "Cook", "Alsip");
            dt.Rows.Add("Illinois", "Cook", "Oak Park");
            dt.Rows.Add("Illinois", "Clinton", "Albers");
            dt.Rows.Add("Illinois", "Clinton", "Aviston");


            return dt;        
        }


        //Because filtering this way can make some cell have a value which is not contained in 
        //the DataGridViewComboBoxColumn.Items, we have to handle the DataError
        private void dgvStateCountyCity_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            //We're interested only in DataGridViewComboBoxColumn
            if (dgvStateCountyCity.Columns[e.ColumnIndex] is DataGridViewComboBoxColumn)
            {
                e.Cancel = true;
            }
        }

        private void dgvStateCountyCity_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 1)
            {
                if (dgvStateCountyCity.CurrentRow.Cells[0].Value != null)
                {
                    string stateSelected = dgvStateCountyCity.CurrentRow.Cells[0].Value.ToString();
                    DataRow[] drTempRows = dtStateCountyCity.Select("State = '" + stateSelected + "'");

                    if (drTempRows != null && drTempRows.Length > 0)
                    {
                        DataTable dtTemp = drTempRows.CopyToDataTable();

                        var countyList = (from tblCounty in dtTemp.AsEnumerable()
                                          group tblCounty by tblCounty.Field<string>("county") into g
                                          select new { County = g.Key }).ToList();

                        BindingSource bs = new BindingSource(countyList, "");

                        // NOTE: Here is what was changed from my previous code
                        DataGridViewComboBoxCell comboCell = dgvStateCountyCity[1, dgvStateCountyCity.CurrentRow.Index] as DataGridViewComboBoxCell;
                        comboCell.DataSource = new BindingSource(bs, null);
                        comboCell.DisplayMember = "County"; //name of column indataTable to display!!
                        comboCell.ValueMember = "County"; // vlaue if needed 


                    }
                }
            }

            if (e.ColumnIndex == 2)
            {
                if (dgvStateCountyCity.CurrentRow.Cells[1].Value != null)
                {
                    string countySelected = dgvStateCountyCity.CurrentRow.Cells[1].Value.ToString();
                    DataRow[] drTempRows = dtStateCountyCity.Select("County = '" + countySelected + "'");

                    if (drTempRows != null && drTempRows.Length > 0)
                    {
                        DataTable dtTemp = drTempRows.CopyToDataTable();
                        BindingSource bs = new BindingSource(dtTemp, "");

                        // NOTE: Here is what was changed from my previous code
                        DataGridViewComboBoxCell comboCell2 = dgvStateCountyCity[2, dgvStateCountyCity.CurrentRow.Index] as DataGridViewComboBoxCell;
                        comboCell2.DataSource = new BindingSource(bs, null);
                        comboCell2.DisplayMember = "City"; //name of column indataTable to display!!
                        comboCell2.ValueMember = "City"; // vlaue if needed 

                    }
                }

            }

        }

        private void dgvStateCountyCity_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {      

            //Register SelectedValueChanged event and reset item comboBox to default if category changes
            if (dgvStateCountyCity.CurrentCell.ColumnIndex == 0 )
            {
                ComboBox comboBox = e.Control as ComboBox;
                comboBox.SelectedIndexChanged -= new EventHandler(dgvcbState_SelectedValueChanged);
                comboBox.SelectedIndexChanged += new EventHandler(dgvcbState_SelectedValueChanged);
            }
        }


        private void dgvcbState_SelectedValueChanged(object sender, EventArgs e)
        {
            //If category value changed then reset item to default.
            if (dgvStateCountyCity.CurrentCell.ColumnIndex == 0)
            {
                if (((DataGridViewComboBoxEditingControl)sender).EditingControlValueChanged == true)
                {
                    dgvStateCountyCity.CurrentRow.Cells[1].Value = "";
                    dgvStateCountyCity.CurrentRow.Cells[2].Value = "";
                }
            }

        }
    }
}
于 2013-07-26T19:28:33.020 に答える