如何根据 1 个组合框中的选择过滤 2 个组合框?
How to filter 2 comboboxes based on the selection in 1 combobox?
我有 3 个 table:
1) 房子:
| ID_house | House_names | num_region |
---------------------------------------
| int | names | int |
num_region - 一个外键,相当于 table.
区域的主键(Region.ID_region)
2) 地区:
| ID_region | Nameofregions | num_arearegion |
---------------------------------------------
| int | names | int |
num_arearegion - 外键,等于 Areas_InRegion table.
中的主键(Areas_InRegion.ID_areas)
3) Areas_InRegion:
| ID_areas | Area_names |
------------------------
| int | names |
在表格中我有 3 个组合框:
1) cmbHouse - 用于显示 House table.
中的房屋名称
2) cmbRegion - 用于显示区域 table.
中的区域名称
3) cmbArea - 用于显示 Areas_InRegion table.
区域中的区域名称
我这样填充组合框:
//cmbHouse
string cmbHouse_query = "SELECT * FROM House";
OleDbDataAdapter dahouse = new OleDbDataAdapter(cmbHouse_query, connection);
DataTable tablehouse = new DataTable();
dahouse.Fill(tablehouse);
cmbHouse.DataSource = tablehouse;
cmbHouse.DisplayMember = "House_names";
cmbHouse.ValueMember = "House.num_region";
cmbHouse.SelectedIndex = -1;
//cmbRegion
string cmbRegion_query = "SELECT * FROM Region";
OleDbDataAdapter daregion = new OleDbDataAdapter(cmbRegion_query, connection);
DataTable tableregion = new DataTable();
daregion.Fill(tableregion);
cmbRegion.DataSource = tableregion;
cmbRegion.DisplayMember = "Nameofregions";
cmbRegion.ValueMember = "Region.ID_region";
cmbRegion.SelectedIndex = -1;
//cmbArea
string cmbArea_query = "SELECT * FROM Areas_InRegion";
OleDbDataAdapter daArea = new OleDbDataAdapter(cmbArea_query, connection);
DataTable tablearea = new DataTable();
daArea.Fill(tablearea);
cmbArea.DataSource = tablearea;
cmbArea.DisplayMember = "Names_OfAreas";
cmbArea.ValueMember = "Areas_InRegion.ID_areas";
cmbArea.SelectedIndex = -1;
Combobox cmbRegion 将 valuemember 作为主键。
我可以通过主键过滤cmbHouse组合框作为cmbRegion组合中的valuemeber,但我不能过滤cmbArea组合框。
private void cmbHouse_SelectionChangeCommitted(object sender, EventArgs e)
{
if (cmbHouse.SelectedIndex > -1)
{
//DataRow selectedDataRow = ((DataRowView)cmbHouse.SelectedItem).Row;
int num_region = Convert.ToInt32(cmbHouse.SelectedValue);
OleDbCommand com = new OleDbCommand();
com.CommandText = "SELECT * FROM Region WHERE Region.ID_region=" + num_region.ToString() + "";
//com.Parameters.AddWithValue("House.num_region", typeof(int));
OleDbDataAdapter danum_region = new OleDbDataAdapter(com.CommandText, connection);
DataTable tablenum_region = new DataTable();
danum_region.Fill(tablenum_region);
cmbRegion.DataSource = tablenum_region;
cmbRegion.DisplayMember = "Nameofregions";
cmbRegion.ValueMember = "Region.num_arearegion";
//cmbRegion.SelectedIndex = -1;
if(cmbRegion.SelectedIndex > -1)
{
int num_area = Convert.ToInt32(cmbRegion.SelectedValue);
OleDbCommand com2 = new OleDbCommand();
com2.CommandText = "SELECT * FROM Areas_InRegion WHERE Areas_InRegion.ID_areas=" + num_area.ToString(); // + num_area.ToString() + " ; WHERE Region.num_arearegion=@Areas_InRegion.ID_area
//com2.Parameters.AddWithValue("@Areas_InRegion.ID_area", num_area);
OleDbDataAdapter danum_area = new OleDbDataAdapter(com2.CommandText, connection);
DataTable tablenum_area = new DataTable();
//tablenum_area.DefaultView.RowFilter = "Areas_InRegion.ID_areas=" + num_area.ToString();
danum_area.Fill(tablenum_area);
cmbArea.DataSource = tablenum_area;
cmbArea.DisplayMember = "Names_OfAreas";
cmbArea.ValueMember = "Areas_InRegion.ID_areas";
//cmbArea.SelectedIndex = -1;
}
}
}
为此,有必要有另一个 valuemeber 作为外键 [Region.num_areas]。
是否可以在每个组合框中有多个值成员?
当我点击任何组合框时,其他组合框应该被过滤。
请帮助我。
谢谢。
一个房子位于一个region(1-1关系),一个Region可以有一个或多个Area(1-n关系),一个Area只属于一个Region 对于这些关系,您的数据库模式有误。你需要这样的东西(因为显然房子只能位于一个区域)
1) House:
| ID_house | House_names | ID_region | ID_areas |
--------------------------------------------------
| int | names | int | int |
2) Region:
| ID_region | Nameofregions |
-----------------------------
| int | names |
3) Areas:
| ID_areas | Area_names | ID_region |
-------------------------------------
| int | names | int |
现在,当您获得房屋的 ID 时,您还可以获得地区和地区的 ID。
private void cmbHouse_SelectionChangeCommitted(object sender, EventArgs e)
{
if (cmbHouse.SelectedIndex > -1)
{
// Each item in a combobox binded to a datatable is a DataRowView
// If we get this object we can access all the columns from that row
DataRowView rv = cmbHouse.SelectedItem as DataRowView;
// Extract the fk for the region and the area
int id_region = Convert.ToInt32(rv["ID_region"]);
int id_area = Convert.ToInt32(rv["ID_area"]);
// at startup you have already filled the combo with the regions,
// so there is no need to look again in the database for the region
// Just set the current selected value to the region
cmbRegion.SelectedValue = num_region;
// the same happens for the Areas combo. It is already filled with the
// areas, but here we should really have only the areas that belongs to
// the selected region not all the area to avoid problems
// (so remove the initial filling and do it only when the user choose an House)
// Query for all areas belonging to the selected region
string areaSql = @"SELECT * FROM Areas
WHERE ID_Region=@reg";
OleDbCommand com2 = new OleDbCommand(areaSql, connection);
com2.Parameters.AddWithValue("@reg", num_region);
OleDbDataAdapter danum_area = new OleDbDataAdapter(com2);
DataTable tablenum_area = new DataTable();
danum_area.Fill(tablenum_area);
// Always put the Datasource after the setting for DisplayMember and ValueMember
// to avoid performance drops and problems if there is a SelectedIndexChanged event
cmbArea.DisplayMember = "Names_OfAreas";
cmbArea.ValueMember = "ID_areas";
cmbArea.DataSource = tablenum_area;
// last step is setting the SelectedValue on the cmbArea to the house's area
cmbArea.SelectedValue = id_area;
}
}
我有 3 个 table:
1) 房子:
| ID_house | House_names | num_region |
---------------------------------------
| int | names | int |
num_region - 一个外键,相当于 table.
区域的主键(Region.ID_region)2) 地区:
| ID_region | Nameofregions | num_arearegion |
---------------------------------------------
| int | names | int |
num_arearegion - 外键,等于 Areas_InRegion table.
中的主键(Areas_InRegion.ID_areas)3) Areas_InRegion:
| ID_areas | Area_names |
------------------------
| int | names |
在表格中我有 3 个组合框:
1) cmbHouse - 用于显示 House table.
中的房屋名称2) cmbRegion - 用于显示区域 table.
中的区域名称3) cmbArea - 用于显示 Areas_InRegion table.
区域中的区域名称我这样填充组合框:
//cmbHouse
string cmbHouse_query = "SELECT * FROM House";
OleDbDataAdapter dahouse = new OleDbDataAdapter(cmbHouse_query, connection);
DataTable tablehouse = new DataTable();
dahouse.Fill(tablehouse);
cmbHouse.DataSource = tablehouse;
cmbHouse.DisplayMember = "House_names";
cmbHouse.ValueMember = "House.num_region";
cmbHouse.SelectedIndex = -1;
//cmbRegion
string cmbRegion_query = "SELECT * FROM Region";
OleDbDataAdapter daregion = new OleDbDataAdapter(cmbRegion_query, connection);
DataTable tableregion = new DataTable();
daregion.Fill(tableregion);
cmbRegion.DataSource = tableregion;
cmbRegion.DisplayMember = "Nameofregions";
cmbRegion.ValueMember = "Region.ID_region";
cmbRegion.SelectedIndex = -1;
//cmbArea
string cmbArea_query = "SELECT * FROM Areas_InRegion";
OleDbDataAdapter daArea = new OleDbDataAdapter(cmbArea_query, connection);
DataTable tablearea = new DataTable();
daArea.Fill(tablearea);
cmbArea.DataSource = tablearea;
cmbArea.DisplayMember = "Names_OfAreas";
cmbArea.ValueMember = "Areas_InRegion.ID_areas";
cmbArea.SelectedIndex = -1;
Combobox cmbRegion 将 valuemember 作为主键。
我可以通过主键过滤cmbHouse组合框作为cmbRegion组合中的valuemeber,但我不能过滤cmbArea组合框。
private void cmbHouse_SelectionChangeCommitted(object sender, EventArgs e)
{
if (cmbHouse.SelectedIndex > -1)
{
//DataRow selectedDataRow = ((DataRowView)cmbHouse.SelectedItem).Row;
int num_region = Convert.ToInt32(cmbHouse.SelectedValue);
OleDbCommand com = new OleDbCommand();
com.CommandText = "SELECT * FROM Region WHERE Region.ID_region=" + num_region.ToString() + "";
//com.Parameters.AddWithValue("House.num_region", typeof(int));
OleDbDataAdapter danum_region = new OleDbDataAdapter(com.CommandText, connection);
DataTable tablenum_region = new DataTable();
danum_region.Fill(tablenum_region);
cmbRegion.DataSource = tablenum_region;
cmbRegion.DisplayMember = "Nameofregions";
cmbRegion.ValueMember = "Region.num_arearegion";
//cmbRegion.SelectedIndex = -1;
if(cmbRegion.SelectedIndex > -1)
{
int num_area = Convert.ToInt32(cmbRegion.SelectedValue);
OleDbCommand com2 = new OleDbCommand();
com2.CommandText = "SELECT * FROM Areas_InRegion WHERE Areas_InRegion.ID_areas=" + num_area.ToString(); // + num_area.ToString() + " ; WHERE Region.num_arearegion=@Areas_InRegion.ID_area
//com2.Parameters.AddWithValue("@Areas_InRegion.ID_area", num_area);
OleDbDataAdapter danum_area = new OleDbDataAdapter(com2.CommandText, connection);
DataTable tablenum_area = new DataTable();
//tablenum_area.DefaultView.RowFilter = "Areas_InRegion.ID_areas=" + num_area.ToString();
danum_area.Fill(tablenum_area);
cmbArea.DataSource = tablenum_area;
cmbArea.DisplayMember = "Names_OfAreas";
cmbArea.ValueMember = "Areas_InRegion.ID_areas";
//cmbArea.SelectedIndex = -1;
}
}
}
为此,有必要有另一个 valuemeber 作为外键 [Region.num_areas]。
是否可以在每个组合框中有多个值成员?
当我点击任何组合框时,其他组合框应该被过滤。
请帮助我。
谢谢。
一个房子位于一个region(1-1关系),一个Region可以有一个或多个Area(1-n关系),一个Area只属于一个Region 对于这些关系,您的数据库模式有误。你需要这样的东西(因为显然房子只能位于一个区域)
1) House:
| ID_house | House_names | ID_region | ID_areas |
--------------------------------------------------
| int | names | int | int |
2) Region:
| ID_region | Nameofregions |
-----------------------------
| int | names |
3) Areas:
| ID_areas | Area_names | ID_region |
-------------------------------------
| int | names | int |
现在,当您获得房屋的 ID 时,您还可以获得地区和地区的 ID。
private void cmbHouse_SelectionChangeCommitted(object sender, EventArgs e)
{
if (cmbHouse.SelectedIndex > -1)
{
// Each item in a combobox binded to a datatable is a DataRowView
// If we get this object we can access all the columns from that row
DataRowView rv = cmbHouse.SelectedItem as DataRowView;
// Extract the fk for the region and the area
int id_region = Convert.ToInt32(rv["ID_region"]);
int id_area = Convert.ToInt32(rv["ID_area"]);
// at startup you have already filled the combo with the regions,
// so there is no need to look again in the database for the region
// Just set the current selected value to the region
cmbRegion.SelectedValue = num_region;
// the same happens for the Areas combo. It is already filled with the
// areas, but here we should really have only the areas that belongs to
// the selected region not all the area to avoid problems
// (so remove the initial filling and do it only when the user choose an House)
// Query for all areas belonging to the selected region
string areaSql = @"SELECT * FROM Areas
WHERE ID_Region=@reg";
OleDbCommand com2 = new OleDbCommand(areaSql, connection);
com2.Parameters.AddWithValue("@reg", num_region);
OleDbDataAdapter danum_area = new OleDbDataAdapter(com2);
DataTable tablenum_area = new DataTable();
danum_area.Fill(tablenum_area);
// Always put the Datasource after the setting for DisplayMember and ValueMember
// to avoid performance drops and problems if there is a SelectedIndexChanged event
cmbArea.DisplayMember = "Names_OfAreas";
cmbArea.ValueMember = "ID_areas";
cmbArea.DataSource = tablenum_area;
// last step is setting the SelectedValue on the cmbArea to the house's area
cmbArea.SelectedValue = id_area;
}
}