我有这个asp:gridview,其中使用mySql存储过程显示数据。我有一个名为ddlstatus的列表框,用于过滤数据。我使用viewstate显示从列表框中选择的数据。问题是我想在此列表框上进行多个选择,并显示对其所做的每个选择的数据,但是当它仅显示初始选择的数据时。
以下是客户端代码:
<asp:Label ID="lblstat" Text="status" Visible="false" runat="server"></asp:Label>
<asp:ListBox ID="ddlstatus" runat="server" OnSelectedIndexChanged="DropDownChange" AutoPostBack="true" AppendDataBoundItems="true" SelectionMode="Multiple"></asp:ListBox>
<asp:GridView ID="gdvTM" runat="server" ControlStyle-Width="100%" AutoGenerateColumns="False" DataKeyNames="ID" OnRowDeleting="gdvTM_RowDeleting" PageSize="5" CssClass="cssgridview" AlternatingRowStyle-BackColor="#d5d8dc">
<Columns >
<asp:TemplateField HeaderText="Current Status">
<ItemTemplate >
<asp:Label ID="lblcstat" runat="server" Text='<%# Eval("status") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
下面是服务器端代码:
private void BindDropDownList()
{
PopulateDropDown(ddlstatus, lblstat.Text);
}
private void PopulateDropDown(ListBox ddl, string columnName)
{
ddl.Items.Clear();
ddl.DataSource = BindDropDown(columnName);
ddl.DataTextField = columnName;
ddl.DataValueField = columnName;
ddl.DataBind();
ddl.Items.Insert(0, new ListItem("Please select", "0"));
}
private void BindGrid()
{
DataTable dt = new DataTable();
String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
MySqlConnection con = new MySqlConnection(strConnString);
MySqlDataAdapter sda = new MySqlDataAdapter();
MySqlCommand cmd = new MySqlCommand("GetTMData");
cmd.CommandType = CommandType.StoredProcedure;
string statusVal = null;
if (ViewState["stat"] != null && ViewState["stat"].ToString() != "0")
{
statusVal = ViewState["stat"].ToString();
}
cmd.Parameters.AddWithValue("statusVal", statusVal);
cmd.Connection = con;
sda.SelectCommand = cmd;
sda.Fill(dt);
gdvTM.DataSource = dt;
int i = dt.Rows.Count;
gdvTM.DataBind();
this.BindDropDownList();
TableCell cell = gdvTM.HeaderRow.Cells[0];
setDropdownselectedItem(ViewState["stat"] != null ? (string)ViewState["stat"] : string.Empty, ddlstatus);
}
private void setDropdownselectedItem(string selectedvalue, ListBox ddl)
{
if (!string.IsNullOrEmpty(selectedvalue))
{
ddl.Items.FindByValue(selectedvalue).Selected = true;
}
}
protected void DropDownChange(object sender, EventArgs e)
{
ListBox dropdown = (ListBox)sender;
string selectedValue = dropdown.SelectedItem.Value;
switch (dropdown.ID.ToLower())
{
case "ddlstatus":
ViewState["stat"] = selectedValue;
break;
}
this.BindGrid();
}
private DataTable BindDropDown(string columnName)
{
string username = uName.Text;
String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
MySqlConnection con = new MySqlConnection(strConnString);
MySqlCommand cmd = new MySqlCommand("SELECT DISTINCT (" + columnName + ") FROM approved WHERE tm = @tm AND " + columnName + " IS NOT NULL", con);
MySqlDataAdapter sda = new MySqlDataAdapter(cmd);
cmd.Parameters.AddWithValue("@tm", username);
DataTable dt = new DataTable();
sda.Fill(dt);
return dt;
}
下面是MySql存储过程:
CREATE DEFINER=`root`@`localhost` PROCEDURE `GetTMData`(in statusVal varchar(45))
BEGIN
SELECT *
FROM approved
WHERE (statusVal IS NULL
OR status = statusVal)
order by date desc;
END
我该如何实现?预先感谢。
答案 0 :(得分:3)
请使列表框为多个
<asp:ListBox id="ListBox1"
Rows="6"
Width="100px"
**SelectionMode="Multiple"**
runat="server">
<asp:ListItem Selected="True">Item 1</asp:ListItem>
<asp:ListItem>Item 2</asp:ListItem>
<asp:ListItem>Item 3</asp:ListItem>
<asp:ListItem>Item 4</asp:ListItem>
<asp:ListItem>Item 5</asp:ListItem>
<asp:ListItem>Item 6</asp:ListItem>
</asp:ListBox>
然后在服务器端 void SubmitBtn_Click(对象发送者,EventArgs e) {
Message.Text = "You chose: <br />";
// Iterate through the Items collection of the ListBox and
// display the selected items.
foreach (ListItem item in ListBox1.Items)
{
if(item.Selected)
{
Message.Text += item.Text + "<br />";
}
}
}
答案 1 :(得分:2)
首先,自动回发不允许您选择多个项目,因为要选择第二个项目,回发已经发生在第一个选定的项目上,所以
您必须为列表框设置AutoPostBack="false"
,
<asp:ListBox ID="ddlstatus" runat="server" AutoPostBack="false" AppendDataBoundItems="true" SelectionMode="Multiple"></asp:ListBox>
例如,要收集多个选定的项目,我们只需选择按钮即可,您可以在任意位置收集这些项目,
然后添加一个按钮,该按钮将调用以下代码
<asp:Button ID="button1" runat="server" OnClick="button1_Click" Text="Click"/>
在按钮事件处理程序上方,添加以下代码,
protected void button1_Click(object sender, EventArgs e)
{
var selectedNames = ddlstatus.Items.Cast<ListItem>()
.Where(i => i.Selected)
.Select(i => i.Value)
.ToList();
string selectedValue = string.Join("','", selectedNames);
selectedValue = "'" + selectedValue + "'";
ViewState["stat"] = selectedValue;
}
然后ViewState
中用逗号分隔的项目将用于存储过程参数
string statusVal = null;
if (ViewState["stat"] != null && ViewState["stat"].ToString() != "0")
{
statusVal = ViewState["stat"].ToString();
}
cmd.Parameters.AddWithValue("statusVal", statusVal); //<= Now this string variable contains comma separated list box items values.
如果您在Page_Load
上填充列表框,请确保将其填充到!Page.IsPostBack
中,如
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//Populate your list box here
}
}
您的SP是
CREATE DEFINER=`root`@`localhost` PROCEDURE `GetTMData1`(in statusVal varchar(255))
BEGIN
IF statusVal = '\'\'' THEN
select * from approved;
ELSE
SET @sql = CONCAT('SELECT * FROM approved WHERE status IN (', statusVal, ')');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF ;
END
如果从下拉列表中选择多个项目,则SP的参数数据看起来像'\'apple\',\'banana\''
。如果不是,则看起来像'\''
。
答案 2 :(得分:1)
我发现了一些可能需要解决的问题,
确保仅在非回发(页面刷新)时调用方法BindDropDownList
,因为您的方法PopulateDropDown
正在清除列表中的项目,这意味着无法在其中还原视图状态回发,因此可能只是选择一个项目的原因。
我不是100%的表模式,但是提供的SQL似乎无法正确地通过多个状态进行查询,您可能应该发送以逗号分隔的值列表,并且在SQL中将它们变成一个临时表,以便您有效地搜索具有多个状态的项目(您可能应该为此创建一个新问题)。
请勿对多个选择使用SelectedItem
,相反,您需要为所选择的项迭代列表项,而无需使用ViewState
来传递它(您可能是因为上述第1点)。例如,您可以将方法BindGrid
和DropDownChange
替换为:
private void BindGrid()
{
DataTable dt = new DataTable();
String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
MySqlConnection con = new MySqlConnection(strConnString);
MySqlDataAdapter sda = new MySqlDataAdapter();
MySqlCommand cmd = new MySqlCommand("GetTMData");
cmd.CommandType = CommandType.StoredProcedure;
string statusVal = null;
foreach (ListItem item in ddlstatus.Items)
{
if(item.Selected)
{
if(statusVal.length > 0)
statusVal += ",";
statusVal += item.Value;
}
}
cmd.Parameters.AddWithValue("statusVal", statusVal);
cmd.Connection = con;
sda.SelectCommand = cmd;
sda.Fill(dt);
gdvTM.DataSource = dt;
gdvTM.DataBind();
}
protected void DropDownChange(object sender, EventArgs e)
{
this.BindGrid();
}