如何将新的数据源添加到已经数据绑定的 CheckBoxList
How do I add new DataSource to an already Databinded CheckBoxList
我正在构建一个显示数据库项目(表、行、FK、...)的 Web 表单
我有一个 CheckBoxList of Tables (chkListTable
),每当我从 chkListTable
更改 SelectedIndexChanged 时,它都会显示一个新的 CheckBoxList of Rows (chkListRow
)。问题是我可以显示来自 chkListTable
的项目和 1 个选定项目。但是我不知道如何显示 chkListRow
如果选择了 chkListTable
中的多个项目。
这是我的代码:
aspx
:
<div>
<asp:Label ID="Label2" runat="server" Text="Table: "></asp:Label>
<asp:CheckBoxList ID="chkListTable" runat="server"
DataTextField="name"
DataValueFeild="name"
AutoPostBack="true"
OnSelectedIndexChanged="chkListTable_SelectedIndexChanged">
</asp:CheckBoxList>
</div>
<div>
<asp:CheckBoxList ID="chkListRow" runat="server"
DataTextField="COLUMN_NAME"
DataValueField="COLUMN_NAME"
RepeatDirection="Horizontal">
</asp:CheckBoxList>
</div>
aspx.cs
:
protected void chkListTable_SelectedIndexChanged(object sender, EventArgs e)
{
tableName.Clear();
foreach (ListItem item in chkListTable.Items)
{
if(item.Selected)
{
tableName.Add(item.Text.Trim());
}
}
for(int i = 0; i < tableName.Count; i++)
{
String query = "USE " + dbname +
" SELECT * FROM information_schema.columns" +
" WHERE table_name = '" + tableName[i] + "'" +
" AND COLUMN_NAME != 'rowguid'";
chkListRow.DataSource = Program.ExecSqlDataReader(query);
chkListRow.DataBind();
Program.conn.Close();
}
}
Program.cs
:
public static bool Connect()
{
if (Program.conn != null && Program.conn.State == ConnectionState.Open)
Program.conn.Close();
try
{
Program.conn.ConnectionString = Program.constr;
Program.conn.Open();
return true;
}
catch (Exception e)
{
return false;
}
}
public static SqlDataReader ExecSqlDataReader(String query)
{
SqlDataReader myreader;
SqlCommand sqlcmd = new SqlCommand(query, Program.conn);
sqlcmd.CommandType = CommandType.Text;
if (Program.conn.State == ConnectionState.Closed) Program.conn.Open();
try
{
myreader = sqlcmd.ExecuteReader();
return myreader;
myreader.Close();
}
catch (SqlException ex)
{
Program.conn.Close();
return null;
}
}
我希望我的显示是这样的:
[x]Table1 [x]Table2 [ ]Table3
[ ]Row1(Table1) [ ]Row2(Table1) [ ]Row3(Table1)
[ ]Row1(Table2) [ ]Row2(Table2)
好的,这是一个相当可爱的小问题。
所以,如果我们 select 1 table,那么我们需要有一个“子”或所谓的一个复选框列表。
但是,如果我们 select 2 tables,(或 5),那么我们需要 2(或 5)个子复选框列表。
换句话说,我们不会使用相同的复选框列表(子),或者尝试“破坏”我们需要的“N”个复选框列表。
所以,这个“子”集(每个检查一个table)是事先不知道的。
那么,我们有一组“重复”的子复选框列表,对吗?
所以,我们可以(也应该)使用“中继器”。中继器所做的就是“重复”我们想要的任何内容,然后我们将 tables.
的主列表“提供”给中继器
因此,我们的标记现在将如下所示:
<style>
.rBut input {margin-right: 5px; }
.rBut label {margin-right: 15px; }
</style>
<asp:Label ID="Label2" runat="server" Text="Table: "></asp:Label>
<div class="rBut">
<asp:CheckBoxList ID="chkListTable" runat="server"
DataTextField="TABLE_NAME"
DataValueFeild="TABLE_NAME"
AutoPostBack="true" RepeatDirection="Horizontal" OnSelectedIndexChanged="chkListTable_SelectedIndexChanged" >
</asp:CheckBoxList>
</div>
</div>
<div>
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
Table: <%# Eval("Table") %> -
<div class="rBut">
<asp:CheckBoxList ID="chkListRow" runat="server"
RepeatDirection="Horizontal">
</asp:CheckBoxList>
</div>
</ItemTemplate>
</asp:Repeater>
注意第二个重复者,我们没有设置值和文本列——我们还不知道它们。您没有提到要显示哪些列,但我的大多数 table 总是在第一列有一个 PK“ID”,因此让我们将其设置为值,并显示(DataTextField,给定中的第二列table).
所以,现在我们建立第一个 select 离子的“列表”,(tables),然后将那个东西传递给转发器,它会重复。
代码现在看起来像这样:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
string strSQL = "SELECT TABLE_NAME FROM VideoGames.INFORMATION_SCHEMA.TABLES " +
"WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME";
chkListTable.DataSource = MyRst(strSQL);
chkListTable.DataBind();
}
protected void chkListTable_SelectedIndexChanged(object sender, EventArgs e)
{
DataTable MyTables = new DataTable();
MyTables.Columns.Add("Table", typeof(string));
foreach (ListItem OneTable in chkListTable.Items)
{
if (OneTable.Selected)
{
DataRow OneRow = MyTables.NewRow();
OneRow["Table"] = OneTable.Value;
MyTables.Rows.Add(OneRow);
}
}
// ok, we have a list of tables, send that to repeater
Repeater1.DataSource = MyTables;
Repeater1.DataBind();
}
public DataTable MyRst(string strSQL)
{
var rst = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.VideoGames))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
rst.Load(cmdSQL.ExecuteReader());
}
}
return rst;
}
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item
| e.Item.ItemType == ListItemType.AlternatingItem)
{
DataRowView rItem = e.Item.DataItem as DataRowView; // get binding data row
CheckBoxList chkListRow = e.Item.FindControl("chkListRow") as CheckBoxList;
string strSQL = "SELECT * FROM " + rItem["Table"].ToString();
DataTable MyTable = MyRst(strSQL);
chkListRow.DataValueField = MyTable.Columns[0].ColumnName;
chkListRow.DataTextField = MyTable.Columns[1].ColumnName;
chkListRow.DataSource = MyRst(strSQL);
chkListRow.DataBind();
}
}
所以,现在我们看到这个:
如果我点击一个,我会看到这个:
但是,假设我点击了 3,然后我看到了这个:
所以,请注意我是如何向 Repeater 提供 table(可能是 sql 查询,但在这种情况下,我们在代码中创建 table)。传递给转发器。
对于每个 table,itemdatabound 触发器。因为table有多个副本,所以我们需要使用find control.
如果您想 test/get 所有选中的项目,那么我们对 Repeater 项目中的每个项目执行一次 - 并再次使用查找控件来获取每个复选框控件。
但请注意我们只有两个复选框列表,但第二个在中继器内部,并且是数据驱动的。
因此,这将适用于 1 或“N”table秒。
我正在构建一个显示数据库项目(表、行、FK、...)的 Web 表单
我有一个 CheckBoxList of Tables (chkListTable
),每当我从 chkListTable
更改 SelectedIndexChanged 时,它都会显示一个新的 CheckBoxList of Rows (chkListRow
)。问题是我可以显示来自 chkListTable
的项目和 1 个选定项目。但是我不知道如何显示 chkListRow
如果选择了 chkListTable
中的多个项目。
这是我的代码:
aspx
:
<div>
<asp:Label ID="Label2" runat="server" Text="Table: "></asp:Label>
<asp:CheckBoxList ID="chkListTable" runat="server"
DataTextField="name"
DataValueFeild="name"
AutoPostBack="true"
OnSelectedIndexChanged="chkListTable_SelectedIndexChanged">
</asp:CheckBoxList>
</div>
<div>
<asp:CheckBoxList ID="chkListRow" runat="server"
DataTextField="COLUMN_NAME"
DataValueField="COLUMN_NAME"
RepeatDirection="Horizontal">
</asp:CheckBoxList>
</div>
aspx.cs
:
protected void chkListTable_SelectedIndexChanged(object sender, EventArgs e)
{
tableName.Clear();
foreach (ListItem item in chkListTable.Items)
{
if(item.Selected)
{
tableName.Add(item.Text.Trim());
}
}
for(int i = 0; i < tableName.Count; i++)
{
String query = "USE " + dbname +
" SELECT * FROM information_schema.columns" +
" WHERE table_name = '" + tableName[i] + "'" +
" AND COLUMN_NAME != 'rowguid'";
chkListRow.DataSource = Program.ExecSqlDataReader(query);
chkListRow.DataBind();
Program.conn.Close();
}
}
Program.cs
:
public static bool Connect()
{
if (Program.conn != null && Program.conn.State == ConnectionState.Open)
Program.conn.Close();
try
{
Program.conn.ConnectionString = Program.constr;
Program.conn.Open();
return true;
}
catch (Exception e)
{
return false;
}
}
public static SqlDataReader ExecSqlDataReader(String query)
{
SqlDataReader myreader;
SqlCommand sqlcmd = new SqlCommand(query, Program.conn);
sqlcmd.CommandType = CommandType.Text;
if (Program.conn.State == ConnectionState.Closed) Program.conn.Open();
try
{
myreader = sqlcmd.ExecuteReader();
return myreader;
myreader.Close();
}
catch (SqlException ex)
{
Program.conn.Close();
return null;
}
}
我希望我的显示是这样的:
[x]Table1 [x]Table2 [ ]Table3
[ ]Row1(Table1) [ ]Row2(Table1) [ ]Row3(Table1)
[ ]Row1(Table2) [ ]Row2(Table2)
好的,这是一个相当可爱的小问题。
所以,如果我们 select 1 table,那么我们需要有一个“子”或所谓的一个复选框列表。
但是,如果我们 select 2 tables,(或 5),那么我们需要 2(或 5)个子复选框列表。
换句话说,我们不会使用相同的复选框列表(子),或者尝试“破坏”我们需要的“N”个复选框列表。
所以,这个“子”集(每个检查一个table)是事先不知道的。
那么,我们有一组“重复”的子复选框列表,对吗?
所以,我们可以(也应该)使用“中继器”。中继器所做的就是“重复”我们想要的任何内容,然后我们将 tables.
的主列表“提供”给中继器因此,我们的标记现在将如下所示:
<style>
.rBut input {margin-right: 5px; }
.rBut label {margin-right: 15px; }
</style>
<asp:Label ID="Label2" runat="server" Text="Table: "></asp:Label>
<div class="rBut">
<asp:CheckBoxList ID="chkListTable" runat="server"
DataTextField="TABLE_NAME"
DataValueFeild="TABLE_NAME"
AutoPostBack="true" RepeatDirection="Horizontal" OnSelectedIndexChanged="chkListTable_SelectedIndexChanged" >
</asp:CheckBoxList>
</div>
</div>
<div>
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
Table: <%# Eval("Table") %> -
<div class="rBut">
<asp:CheckBoxList ID="chkListRow" runat="server"
RepeatDirection="Horizontal">
</asp:CheckBoxList>
</div>
</ItemTemplate>
</asp:Repeater>
注意第二个重复者,我们没有设置值和文本列——我们还不知道它们。您没有提到要显示哪些列,但我的大多数 table 总是在第一列有一个 PK“ID”,因此让我们将其设置为值,并显示(DataTextField,给定中的第二列table).
所以,现在我们建立第一个 select 离子的“列表”,(tables),然后将那个东西传递给转发器,它会重复。
代码现在看起来像这样:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
string strSQL = "SELECT TABLE_NAME FROM VideoGames.INFORMATION_SCHEMA.TABLES " +
"WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME";
chkListTable.DataSource = MyRst(strSQL);
chkListTable.DataBind();
}
protected void chkListTable_SelectedIndexChanged(object sender, EventArgs e)
{
DataTable MyTables = new DataTable();
MyTables.Columns.Add("Table", typeof(string));
foreach (ListItem OneTable in chkListTable.Items)
{
if (OneTable.Selected)
{
DataRow OneRow = MyTables.NewRow();
OneRow["Table"] = OneTable.Value;
MyTables.Rows.Add(OneRow);
}
}
// ok, we have a list of tables, send that to repeater
Repeater1.DataSource = MyTables;
Repeater1.DataBind();
}
public DataTable MyRst(string strSQL)
{
var rst = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.VideoGames))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
rst.Load(cmdSQL.ExecuteReader());
}
}
return rst;
}
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item
| e.Item.ItemType == ListItemType.AlternatingItem)
{
DataRowView rItem = e.Item.DataItem as DataRowView; // get binding data row
CheckBoxList chkListRow = e.Item.FindControl("chkListRow") as CheckBoxList;
string strSQL = "SELECT * FROM " + rItem["Table"].ToString();
DataTable MyTable = MyRst(strSQL);
chkListRow.DataValueField = MyTable.Columns[0].ColumnName;
chkListRow.DataTextField = MyTable.Columns[1].ColumnName;
chkListRow.DataSource = MyRst(strSQL);
chkListRow.DataBind();
}
}
所以,现在我们看到这个:
如果我点击一个,我会看到这个:
但是,假设我点击了 3,然后我看到了这个:
所以,请注意我是如何向 Repeater 提供 table(可能是 sql 查询,但在这种情况下,我们在代码中创建 table)。传递给转发器。
对于每个 table,itemdatabound 触发器。因为table有多个副本,所以我们需要使用find control.
如果您想 test/get 所有选中的项目,那么我们对 Repeater 项目中的每个项目执行一次 - 并再次使用查找控件来获取每个复选框控件。
但请注意我们只有两个复选框列表,但第二个在中继器内部,并且是数据驱动的。
因此,这将适用于 1 或“N”table秒。