Asp.net 实现GridView分页时记录CheckBox状态

 

  1. 用GridView自带的方法实现分页功能。
  2. 用ViewState记录GridView分页后各个分页面的CheckBox的选中状态。
  3. GridView不同分页面之间的跳转只是刷新当前页面,并没有跳出当前Web页面的生命周期。(这也是ViewState的作用范围)
  4. 如果想要在不同Web页面之间跳转实现信息传递的话,可以用Cookie,Session等。


  • 当我们写Asp.net程序的时候避免不了的是从数据库中取数据,然后将这些数据显示在页面上,当数据非常多的时候我们又很自然的想到了把这些数据进行分页显示。分页在Asp.net中用到的地方是非常多的,我们可以自己去编写分页程序,也可以用Asp.net给我们封装好的。这里我们用Asp.net封装好的分页功能,并用ViewState实现实现不同分页面的CheckBox的状态:

 

  • 用GridView去显示数据的时候避免不了的与CheckBox的结合(即:将GridView的每一行的第一列设置为CheckBox)方法如下:可以用拖控件的方法去创建GridView然后在GridView控件中加入CheckBox列。body的代码如下:其中onpageindexchanging="GridView1_PageIndexChanging"表示选择不同分页面时所调用的方法,AllowPaging="True"表示此GridView允许自带的分页,PageSize=“5”表示每页的行数为5(可以在GridView1的属性中去选择填写)
    1 <body style="height: 12px; width: 688px">
    2 <form id="form1" runat="server">
    3 <div>
    4 <asp:GridView ID="GridView1" runat="server" Height="289px" Width="673px"
    5 onpageindexchanging="GridView1_PageIndexChanging" AllowPaging="True" PageSize="5">
    6 <Columns>
    7 <asp:TemplateField>
    8 <ItemTemplate>
    9 <asp:CheckBox ID="CheckBox1" Checked =false AutoPostBack =true runat="server" />
    10 </ItemTemplate>
    11 </asp:TemplateField>
    12 </Columns>
    13 <PagerSettings Mode="NumericFirstLast" />
    14 </asp:GridView>
    15 </div>
    16
    17 <asp:Button ID="Button1" runat="server" onclick="Button1_Click"
    18 Text="SelectAll" />
    19 <asp:Button ID="Button2" runat="server" onclick="Button2_Click"
    20 Text="CancelAll" />
    21
    22 </form>
    23  </body>

     

  • 页面布局时注意:若用拖控件和写代码混合生成界面时,一定要保证...aspx.designer.cs中有所有控件的注册信息(这也是为什么许多从网上复制的代码拷贝到自己的工程当中出错的原因之一,初学者很容易犯这样的错误)。如:上面GridView,CheckBox,Button1, Button2的注册信息为:
    1   protected global::System.Web.UI.WebControls.GridView GridView1;
    2    protected global::System.Web.UI.WebControls.CheckBox CheckBox1;
    3    protected global::System.Web.UI.WebControls.Button Button1;
    4    protected global::System.Web.UI.WebControls.Button Button2;

     

 

  • 用GridView分页去显示数据的时候有一个弊端:GridView只能记录当前页面所显示的数据,而不去保存其他页面的控件状态,比如:我在第一页上选择了1行(在CheckBox上打个对号),当我们跳到下一页之后再返回时,选中的那行又恢复到了一开始的状态(没选中)。
  • 想要解决这个问题也有很多方法,比如Session,Cookie等。这里我选择用ViewState变量去记录所有分页面CheckBox的状态(【注】ViewState的作用是:变量可以在跨分页面情况下保存其原来的值,也就是说:其变量所保存的值不会因为我们分页面的跳转而发生改变,但如果是不同的Web页面之间的跳转的话,ViewState就无能为力了,但是我们可以换用Session和Cookie实现)
  • 我们定义一个Pagination类,类中的方法实现CheckBox具体的状态。代码如下:
    1 using System;
    2  using System.Collections.Generic;
    3  using System.Linq;
    4  using System.Web;
    5  using System.Web.UI;
    6  using System.Web.UI.WebControls;
    7
    8 namespace FenYe
    9 {
    10 public class Pagination
    11 {
    12 //Remember the station of every CheckBox in all pages
    13 public void RememberOldValues(Dictionary<string, bool> dic, GridView gdv)
    14 {
    15 for (int i = 0; i < gdv.Rows.Count; i++)
    16 {
    17 string currentValue = gdv.Rows[i].Cells[1].Text.Trim();
    18 CheckBox currentCbx = gdv.Rows[i].Cells[0].FindControl("CheckBox1") as CheckBox;
    19 if (currentCbx.Checked && dic[currentValue] == false)
    20 {
    21 dic[currentValue] = true;
    22 }
    23 else if (!currentCbx.Checked && dic[currentValue] == true)
    24 {
    25 dic[currentValue] = false;
    26 }
    27 }
    28 }
    29
    30 //Repopulate the station of every CheckBox in all pages
    31 public void RePopulateValues(Dictionary<string, bool> dic, GridView gdv)
    32 {
    33 foreach (GridViewRow row in gdv.Rows)
    34 {
    35 string currentValue = row.Cells[1].Text.Trim();
    36 CheckBox currentCbx = row.Cells[0].FindControl("CheckBox1") as CheckBox;
    37 if (dic[currentValue] == true)
    38 {
    39 currentCbx.Checked = true;
    40 }
    41 else
    42 {
    43 currentCbx.Checked = false;
    44 }
    45 }
    46 }
    47
    48 //Select all CheckBoxes in all pages
    49 public void SelectAll(Dictionary<string, bool> dic)
    50 {
    51 string[] keys = dic.Keys.ToArray();
    52 dic.Clear();
    53 foreach (string key in keys)
    54 {
    55 dic.Add(key, true);
    56 }
    57 }
    58
    59 //UnSelect all CheckBoxes in all pages
    60 public void UnSelectAll(Dictionary<string, bool> dic)
    61 {
    62 string[] keys = dic.Keys.ToArray();
    63 dic.Clear();
    64 foreach (string key in keys)
    65 {
    66 dic.Add(key, false);
    67 }
    68 }
    69 }
    70 }

     

  • 假设我们用赋值的方式模拟从数据中读取数据,生成DataTable,然后将此DataTable绑定到GridView数据源中实现分页显示。代码如下:
    1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Web;
    5 using System.Web.UI;
    6 using System.Web.UI.WebControls;
    7 using System.Data;
    8
    9 namespace FenYe
    10 {
    11 public partial class _Default : System.Web.UI.Page
    12 {
    13 //声明一个Pagination的类实例(调用其方法实现分页)
    14 Pagination mPage = new Pagination();
    15
    16 //声明一个Dictionary(并将其表明为ViewState属性),
    17 //其中Key值(string)代表User的ID(数据库中的主键),Value值(bool)表示该行的CheckBox是否选中
    18 Dictionary<string, bool> usersDic
    19 {
    20 get
    21 {
    22 return (ViewState["usersdic"]!= null)?(Dictionary<string, bool>)ViewState["usersdic"]:null;
    23 }
    24 set
    25 {
    26 ViewState["usersdic"] = value;
    27 }
    28 }
    29
    30 //声明一个DataTable(并将其标明为ViewState属性),
    31 //去记录User的所有信息,第一列填充的是UserID(数据库中的主键)
    32 DataTable mUsersDT
    33 {
    34 get
    35 {
    36 return (ViewState["usersdt"] != null) ? (DataTable)(ViewState["usersdt"]) : null;
    37 }
    38 set
    39 {
    40 ViewState["usersdt"] = value;
    41 }
    42 }
    43
    44 protected void Page_Load(object sender, EventArgs e)
    45 {
    46 //如果是第一次加载,则走if中的内容
    47 if (!Page.IsPostBack)
    48 {
    49 mUsersDT = GetUsersTable();
    50 FillUsersTable(mUsersDT);
    51 usersDic = InitializeUsersDic(mUsersDT);
    52 //GridView绑定数据源(DataTable)
    53 GridView1.DataSource = mUsersDT;
    54 GridView1.DataBind();
    55 }
    56 }
    57
    58 //当点击GridView不同的分页时,调用如下方法(这个方法需先注册:请看第一部分body的代码)
    59 protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
    60 {
    61 //记录原来分页面的所有CheckBox的状态
    62 mPage.RememberOldValues(usersDic, GridView1);
    63 GridView1.PageIndex = e.NewPageIndex;
    64 GridView1.DataSource = mUsersDT;
    65 GridView1.DataBind();
    66 //重构当前选中页面的CheckBox的状态
    67 mPage.RePopulateValues(usersDic, GridView1);
    68 }
    69
    70 //获得UsersTable(初始化DataTable的列属性ID和Name)
    71 protected DataTable GetUsersTable()
    72 {
    73 DataTable dt = new DataTable();
    74 string[] columns = { "ID", "Name"};
    75 foreach (string name in columns)
    76 {
    77 DataColumn column = dt.Columns.Add();
    78 column.ColumnName = name;
    79 }
    80 return dt;
    81 }
    82 //填充User的DataTable的内容
    83 protected void FillUsersTable(DataTable dt)
    84 {
    85 for (int i = 0; i < 20; i++)
    86 {
    87 DataRow row = dt.NewRow();
    88 row["ID"] = i.ToString();
    89 row["Name"] = "Name" + i.ToString();
    90 dt.Rows.Add(row);
    91 }
    92 }
    93
    94 //初始化Dictionary
    95 protected Dictionary<string, bool> InitializeUsersDic(DataTable dt)
    96 {
    97 Dictionary<string, bool> currentDic = new Dictionary<string, bool>();
    98 //将DataTable中的每一行的第一列内容存储到Dictionary中
    99 for (int i = 0; i < dt.Rows.Count; i++)
    100 {
    101 currentDic.Add(dt.Rows[i].ItemArray[0].ToString(), false);
    102 }
    103 return currentDic;
    104 }
    105
    106 //处理Button1的点击事件(选中所有)
    107 protected void Button1_Click(object sender, EventArgs e)
    108 {
    109 mPage.SelectAll(usersDic);
    110 mPage.RePopulateValues(usersDic, GridView1);
    111 }
    112
    113 //处理Button2的点击事件(不选中所有)
    114 protected void Button2_Click(object sender, EventArgs e)
    115 {
    116 mPage.UnSelectAll(usersDic);
    117 mPage.RePopulateValues(usersDic, GridView1);
    118 }
    119 }
    120 }
  • 如果想实现不同Web页面之间数据信息的传递,将上面的代码中ViewState字样换成Session即可,那么在其他页面就可以根据Session["Name"]中的Name进行区别获取Session信息。
posted @ 2010-11-16 20:03  Eric Sun  阅读(8524)  评论(18编辑  收藏  举报