asp.net GridView是否能够使用ViewState?

时间:2016-08-13 02:38:12

标签: c# asp.net .net gridview viewstate

我正在开发一个源自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,然后挖掘以确定哪些行的复选框已经选中。它根据检查的行进行后续处理。

  • 旧站点代码执行IsPostBack检查,只有在错误时才调用DataBind。
  • 根据MSDN,页面没有定义EnableViewState或ViewStateMode,这意味着它们都默认为true。
  • 在母版页或任何内容中都没有调用DataBind。
  • 旧网站代码不会对ViewState字典进行任何手动持久化。
  • 令人惊讶的是,这个网站的制作版本确实有效。

由于我一直在努力,我发现只有线程和文章讨论GridView如何实际使用ViewState,以及如何使用发送给用户的数据,DataTable用作DataSource必须手动插入后面的代码中的ViewState等。

我正在处理的网站版本已转换为Web应用程序项目,并且它的目标是.NET 4.5。当我调试站点并中断Page_LoadSubmit_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。

1 个答案:

答案 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,我相信这就是它始终有效的方式。

相关问题