如何在启用了分页的网格视图中维护控件的状态
本文关键字:视图 维护 控件 状态 网格 启用 分页 | 更新日期: 2023-09-27 18:00:43
我有一个由4列组成的网格视图,其中一列为Approve。Approve有一个复选框,绑定后将对数据集的所有行重复该复选框。我已经使allowpageg=true&pageindexsize为10。现在,假设我选中了第2行和第5行的复选框,然后移到第2页,回到第1页,我在第1页选中的(第2行)复选框将重置为未选中状态。我知道原因,这是由于我们对onpageindexchangeing事件所做的网格视图的绑定。但是,即使我们从一个页面移动到另一个页面,是否有任何方法可以保持复选框的状态。
感谢
您可以使用Session来维护这些值。一页索引更改事件,您需要向会话添加值并重新绑定复选框。
这里有几个链接可以帮助你
- http://forums.asp.net/p/1368550/2852029.aspx
- http://myaspsnippets.blogspot.com/2010/08/maintaining-state-of-checkboxes-while.html
Try,(您必须将两个事件Checkbox_Checked和Checkbox_PreRender设置为网格中的Checkbox控件。此外,还必须在网格中设置DataKey,以便Checks数组中有索引。)
protected bool[] Checks
{
get { return (bool[])(ViewState["Checks"] ?? new bool[totalLengthOfDataSource]); }
set { ViewState["Checks"] = value; }
}
protected void Checkbox_Checked(object sender, EventArgs e)
{
CheckBox cb = (CheckBox)sender;
bool[] checks = Checks;
checks[(int)GetRowDataKeyValue(sender)] = cb.Checked;
Checks = checks;
}
protected void Checkbox_PreRender(object sender, EventArgs e)
{
CheckBox cb = (CheckBox)sender;
bool[] checks = Checks;
cb.Checked = checks[(int)GetRowDataKeyValue(sender)];
}
这些在静态GridViewUtils类中效果最好。
public static GridViewRow GetRow(object sender)
{
Control c = (Control)sender;
while ((null != c) && !(c is GridViewRow))
c = c.NamingContainer;
return (GridViewRow)c;
}
/// <summary>
/// Get the Grid the row is in
/// </summary>
/// <param name="row"></param>
/// <returns></returns>
public static GridView GetGrid(this GridViewRow row)
{
Control c = (Control)row;
while ((null != c) && !(c is GridView))
c = c.NamingContainer;
return (GridView)c;
}
/// <summary>
/// Get the ID field value based on DataKey and row's index
/// </summary>
/// <param name="sender">Any web-control object in the grid view</param>
/// <returns></returns>
public static object GetRowDataKeyValue(object sender)
{
try
{
GridViewRow row = GetRow(sender);
GridView grid = row.GetGrid();
return grid.DataKeys[row.RowIndex].Value;
}
catch
{
return null;
}
}
另一种方法:
在名为"userSelected"(或类似的)的可绑定对象上创建一个bool属性根据可绑定列表对象的对象ID创建索引器在grid_RowDataBound上,将可绑定对象的ID作为属性添加到复选框中在grid_RowDataBound上,还将复选框的checked属性设置为obj.userSelected在checkch_CheckChaged中,使用索引器设置可绑定对象的userSelected属性
感谢
我尝试了@Chuck的PreRender技术,但对我不起作用(VS2005、ASP.net2、SQLsrv2005)。也许技术太老了,但这就是客户所拥有的。
所以我尝试了简单的myaspsnippets技术,经过一些修改,效果非常好!
我的Gridview
<asp:GridView ID="gvFTUNSENT" runat="server"
AutoGenerateColumns="False" CellPadding="4" ForeColor="Black" AllowSorting="False" CssClass="gvCSS" Width="100%"
DataKeyNames="StudentID,StudentUnitID" DataSourceID="sdsFTUNSENT"
GridLines="None" AllowPaging="True" PageSize="10" BackColor="White" BorderColor="#DEDFDE" BorderStyle="None" BorderWidth="1px"
OnPageIndexChanged="GridView_PageIndexChanged"
OnPageIndexChanging="GridView_PageIndexChanging">
<RowStyle Wrap="True" Height="48px" />
<Columns>
...etc...
</Columns>
<FooterStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" Height="100%" />
<PagerStyle CssClass="cssPager" BackColor="#6B696B" ForeColor="White" HorizontalAlign="Left" Height="100%" />
<HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" />
</asp:GridView>
我使用的分页方法有:
protected void GridView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView gv = (GridView)sender;
//saves a "copy" of the page before it's changed over to the next one
SavePageState(gv);
gv.PageIndex = e.NewPageIndex;
gv.DataBind();
}
和
protected void GridView_PageIndexChanged(object sender, EventArgs e)
{
...your code to handle anything after the page has changed
gv.DataSource = dt;
gv.DataSourceID = null;
gv.DataBind();
//reload any checkboxes that were session saved in the page
LoadPageState(gv);
}
}
}
}
因此SAVE和LOAD方法如下:
private void SavePageState(GridView gv)
{
ArrayList categoryIDList = new ArrayList();
Int32 index = -1;
foreach (GridViewRow row in gv.Rows)
{
HiddenField hfStudentUnitID = (HiddenField)row.FindControl("hfStudentUnitID");
if (hfStudentUnitID != null)
{
if (hfStudentUnitID.Value.Length > 0)
{
index = Convert.ToInt32(hfStudentUnitID.Value.ToString()); //gv.DataKeys[row.RowIndex]["StudentUnitID"];
bool result = ((CheckBox)row.FindControl("cbSEND")).Checked;
// Check in the Session
if (Session["CHECKED_ITEMS"] != null)
categoryIDList = (ArrayList)Session["CHECKED_ITEMS"];
if (result)
{
if (!categoryIDList.Contains(index))
categoryIDList.Add(index);
}
else
categoryIDList.Remove(index);
}
}
}
if (categoryIDList != null && categoryIDList.Count > 0)
Session["CHECKED_ITEMS"] = categoryIDList;
}
和
private void LoadPageState(GridView gv)
{
ArrayList categoryIDList = (ArrayList)Session["CHECKED_ITEMS"];
if (categoryIDList != null && categoryIDList.Count > 0)
{
foreach (GridViewRow row in gv.Rows)
{
HiddenField hfStudentUnitID = (HiddenField)row.FindControl("hfStudentUnitID");
if (hfStudentUnitID != null)
{
if (hfStudentUnitID.Value.Length > 0)
{
Int32 index = Convert.ToInt32(hfStudentUnitID.Value.ToString()); //gv.DataKeys[row.RowIndex]["StudentUnitID"];
if (categoryIDList.Contains(index))
{
CheckBox myCheckBox = (CheckBox)row.FindControl("cbSEND");
myCheckBox.Checked = true;
}
}
}
}
}
}
为了实现这一点,您需要将Paging方法调用放入GridView中,将CheckBox ID从cbSEND更改为您所使用的,并将HiddenFields指向其他具有行唯一标识符的控件或值不要使用RowIndex
,因为它在GridView中的整个数据长度中都不是唯一的。
工作起来很有魅力!