这两天一直在搞一个小页面,里面包含一个DropDownList控件DropDownList1,一个GridView控件GridView1,以及两个SqlDataSource控件SqlDataSource1和SqlDataSource2。想达到的目的如下:
1. 第一次打开这个页面的时候,GridView要显示SqlDataSource2数据控件连接到的表的所有数据, 如果数据够多,要分页(默认设置为一页10条)
2. 如果没有通过DropDownList1筛选数据,那点下一页要显示所有数据的第二页
3. 此时如果点DropDownList来筛选数据,要显示相应的符合条件的数据。同样,如果数据多于10条,要分页
4.此时如果再点下一页,要显示筛选后数据的第二页。
其实功能很简单,却花了我整整两天来解决这个问题。一开始的时候,我开了DropDownList1的AutoPostBack,设置了它的SelectedIndexChanged事件(该事件用来更改SqlDataSource2的SelectCommand属性从而达到筛选的目的)。但因为我在Page_Load事件里有写IsPostBack相关的代码来显示所有数据,而这个判断是否回发却不会区分你是点筛选后点下一页的回发还是直接显示所有数据再点下一页的回发,所以当筛选后,如果有第二页,当你点下一页时,显示的却是未筛选时的第二页。为解决此问题我Google和百度了N多个网页却没有找到答案,突然看到DropDownList的AppendDataBoundItems属性时,却得到了启发。之前我的DropDownList所有的项是来自于SqlDataSource1的,现在我给它在最前面添加一个项,Value值为0,Text值为“SelectALL”,再选它为”Selected"。然后设置AppendDataBoundItems属性为“True",这样,来自于SqlDataSource1里的所有项都会排在这个项之后。然后在DropDownList的SelectedIndexChanged事件里,我通过选中的是不是Value为0的那个项来确定是不是要显示所有数据。这样,就不存在两种情况下回发的不同了。
页面代码主要部分为:
<asp:DropDownList ID="DropDownList1" runat="server" AppendDataBoundItems="True" AutoPostBack="True" DataSourceID="SqlDataSource1" DataTextField="Username" DataValueField="UserID" onselectedindexchanged="DropDownList1_SelectedIndexChanged"> <asp:ListItem Value="0" Selected="True">Select All</asp:ListItem> </asp:DropDownList> <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" DataSourceID="SqlDataSource2" AutoGenerateColumns="False"> <Columns> <asp:BoundField DataField="UserID" HeaderText="UserID" SortExpression="UserID" /> <asp:BoundField DataField="Username" HeaderText="Username" SortExpression="Username" /> <asp:BoundField DataField="Department" HeaderText="Department" SortExpression="Department" /> <asp:BoundField DataField="Division" HeaderText="Division" SortExpression="Division" /> <asp:BoundField DataField="ComputerSN" HeaderText="ComputerSN" SortExpression="ComputerSN" /> <asp:BoundField DataField="Monitor1SN" HeaderText="Monitor1SN" SortExpression="Monitor1SN" /> <asp:BoundField DataField="Monitor2SN" HeaderText="Monitor2SN" SortExpression="Monitor2SN" /> <asp:BoundField DataField="IPPhoneNo" HeaderText="IPPhoneNo" SortExpression="IPPhoneNo" /> <asp:BoundField DataField="BBNo" HeaderText="BBNo" SortExpression="BBNo" /> </Columns> <PagerSettings FirstPageText="|&lt;First" LastPageText="Last&gt;|" Mode="NextPreviousFirstLast" NextPageText="Next&gt;" PreviousPageText="&lt;Prev" /> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:testConnectionString %>" SelectCommand="SELECT UserID,Username FROM Users.Users"></asp:SqlDataSource> <asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:testConnectionString %>"></asp:SqlDataSource>
后台代码主要为:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { SqlDataSource2.SelectCommand = "SELECT * FROM Users.vwUsageInfo"; ViewState["sql"] = SqlDataSource2.SelectCommand; } else { SqlDataSource2.SelectCommand = ViewState["sql"].ToString(); } } protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) { if (DropDownList1.SelectedValue == "0") { SqlDataSource2.SelectCommand = "SELECT * FROM Users.vwUsageInfo"; } else { SqlDataSource2.SelectCommand = "SELECT * FROM Users.vwUsageInfo WHERE UserID='" + DropDownList1.SelectedValue + "'"; } GridView1.PageIndex = 0; ViewState["sql"] = SqlDataSource2.SelectCommand; }
至此终于成功实现我的所有目的。
其实还有一种不需要后台代码的方法,那就是设置SqlDataSource2的SelectCommand属性为:
"SELECT * FROM Users.vwUsageInfo WHERE UserID= case WHEN @UserID=0 THEN UserID ELSE @UserID END" ,这其实也能达到效果。
写下这一段以备将来忘记啊。也方便如果有人遇到同样的问题。