2013-07-25 2 views
0

시, 군 및시 계단식 콤보 박스 열. 방금 ​​DataGridview를 사용하여 간단한 양식을 만들었습니다. datagridview 컨티넨스 3 개의 콤보 박스 컬럼 (주, 카운티 및 도시). 카운티 콤보 상자에 주를 선택하면 해당 주 내의 카운티 만 표시되어야합니다. 카운티를 선택하면 도시 열에는 선택된 주 및 카운티 내의 도시 만 표시됩니다. 어떤 시점에서 주와 군을 변경할 수 있어야합니다. 그러면 해당하는 다른 열을 재설정해야합니다.Datagridview의시, 군 및시 계단식 콤보 박스 열

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; 
      } 
     } 

    } 
} 

누구에게 아이디어를 작성 하시겠습니까? 도움을 많이 주셔서 감사합니다!

+0

[DataGridView Cascading/Dependent ComboBox Columns] (http://stackoverflow.com/a/39487773/3110834) –

답변

0

나는 그 답을 다른 곳에서 발견했다. 그래서 코드를 수정했고 여기에 있습니다. 핵심은 DataGridViewComboBoxCell을 사용해야한다는 것입니다. 이것은 완전히 작동하는 샘플입니다. 워렌티어 (Warrenties)없이 원하는대로 사용하십시오.

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 = ""; 
       } 
      } 

     } 
    } 
}