我正在开发一个源自Visual Studio网站项目的旧网站,除了其他工作之外,我还要转换为Web应用程序。网站上的一个页面使用GridView,并使用DataTable在代码隐藏中设置DataSource。 GridView公开了几个BoundFields,以及一个包含复选框的TemplateField。 GridView配置为使用EnableViewState。
<asp:GridView ID="Results" runat="server" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None" EnableViewState="true">
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<Columns>
<asp:BoundField DataField="Type" HeaderText="Type"/>
<asp:BoundField DataField="ProcessDate" HeaderText="Process Date" />
<asp:BoundField DataField="Classification" HeaderText="Classification" />
<asp:BoundField DataField="Email" HeaderText="Email" />
<asp:TemplateField HeaderText="Notify?" ItemStyle-HorizontalAlign="Center">
<EditItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" onclick="EnableSubmit(this);" />
</EditItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" onclick="EnableSubmit(this);" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
该页面还有一个Submit按钮,在_Click处理程序中,代码尝试抓取Results.Rows
,然后挖掘以确定哪些行的复选框已经选中。它根据检查的行进行后续处理。
由于我一直在努力,我发现只有线程和文章讨论GridView如何实际使用ViewState,以及如何使用发送给用户的数据,DataTable用作DataSource必须手动插入后面的代码中的ViewState等。
我正在处理的网站版本已转换为Web应用程序项目,并且它的目标是.NET 4.5。当我调试站点并中断Page_Load
或Submit_Click
时,Results
GridView具有空数据源,而Rows属性具有0计数。这似乎与目前关于GridView&#34;如何工作的传统智慧一致。&#34;
我很清楚,对于这个网站正在做什么,这是一个令人发指的实施,并且有更好的方法来做到这一点。但是,我最关心的是,我无法找到旧版本如何工作的任何解释。
GridView在其历史记录的某个时刻是否更改了忽略其EnableViewState属性? GridView上的EnableViewState实际上做了什么?这可能是网站和Web应用程序项目之间的区别吗?
这怎么可能有用?
更新:基于Bert Evans&#39;示例页面,我尝试了这个修改过的页面。
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
public class Thing
{
public int ID { get; set; }
public string Name { get; set; }
}
IEnumerable<Thing> Things
{
get
{
var things = new List<Thing>();
things.Add(new Thing { ID = 1, Name = "One" });
things.Add(new Thing { ID = 2, Name = "Two" });
things.Add(new Thing { ID = 3, Name = "Three" });
things.Add(new Thing { ID = 4, Name = "Four" });
things.Add(new Thing { ID = 5, Name = "Five" });
return things;
}
}
void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ThingGridView.DataSource = Things;
ThingGridView.DataBind();
}
pageLoadLabel.Text = string.Format("On page Load, row count: '{0}'", ThingGridView.Rows.Count);
}
void OnClickMe(object sender, EventArgs e)
{
onClickLabel.Text = string.Format("On click, row count: '{0}'", ThingGridView.Rows.Count);
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView runat="server" ID="ThingGridView">
<Columns>
<asp:BoundField HeaderText="Name" DataField="Name" />
</Columns>
</asp:GridView>
</div>
<asp:Button runat="server" ID="ThingButton" Text="Click Me!" OnClick="OnClickMe" />
<asp:Label runat="server" ID="onClickLabel" Text="[set on click]" />
<asp:Label runat="server" ID="pageLoadLabel" Text="[set on page load]" />
</form>
</body>
</html>
唯一的区别是打印出页面正文中行数的标签。执行此页面时。第一个Page_Load调用将行计数5打印到页面;但是,在回发中,页面加载和OnClick方法中的行计数为0。
答案 0 :(得分:1)
数据绑定是将控件的指定数据源转换为呈现给页面的控件树的过程。对于GridView
来说,实际上,设置DataSource
属性并调用DataBind
方法会转换IEnumerable
或从IEnumerable
提取的其他来源,如DataSet
1}}或DataTable
,放入包含数据的控件的HTML表格中。
呈现在表格单元格中的每个控件都维护它自己的ViewState
,这样当页面回发到服务器时,GridView
会重建控件结构,并使用ViewState
中的数据(或者更确切地说,Page启动控制结构的重建,而GridView
只是参与)。
DataSource
未保存到ViewState
,只保存为渲染控件的状态。
禁用ViewState
上的GridView
会阻止它保存自己状态的某些元素,这会阻止它执行分页和排序等操作。此外,如果您禁用ViewState
上的GridView
,并执行回发(在客户端触发将页面提交回服务器的事件),则GridView
将在重新呈现页面时不显示任何内容,因为EnableViewState
是继承的,并且将阻止子控件保存自己的状态。在回发后让GridView
禁用ViewState
再次显示数据的唯一方法是重新绑定数据(再次使用包含数据的数据源调用DataBind
)或已对ViewState
内禁用GridView
内的子控件手动启用ViewState
。您提到您正在处理的页面上的DataBind
受!IsPostback
保护,因此它只对页面的初始加载进行绑定。
我不知道有任何变化,GridView
在某个时间点保存了DataSource
,我相信这就是它始终有效的方式。