C# ListBox实现了IPostBackDataHandler,但为什么';当EnableViewState设置为false时,它是否会像文本框一样保持其状态?

C# ListBox实现了IPostBackDataHandler,但为什么';当EnableViewState设置为false时,它是否会像文本框一样保持其状态?,c#,asp.net,webforms,postback,viewstate,C#,Asp.net,Webforms,Postback,Viewstate,在这篇文章中,作者说: 在开发人员中,一个常见的误解是视图状态在某种程度上负责让文本框、复选框、下拉列表和其他Web控件在回发过程中记住它们的值。事实并非如此,因为这些值是通过回发表单字段值标识的,并在LoadPostData()方法中为那些实现IPostBackDataHandler的控件分配的 因此,当我禁用文本框的视图状态时,它仍然会在回发过程中保持其文本值,根据上面的描述,这是正确的 但是,当我禁用ListBox的视图状态时(它也实现了IPostBackDataHandler),它不会在

在这篇文章中,作者说:

在开发人员中,一个常见的误解是视图状态在某种程度上负责让文本框、复选框、下拉列表和其他Web控件在回发过程中记住它们的值。事实并非如此,因为这些值是通过回发表单字段值标识的,并在LoadPostData()方法中为那些实现IPostBackDataHandler的控件分配的

因此,当我禁用文本框的视图状态时,它仍然会在回发过程中保持其文本值,根据上面的描述,这是正确的

但是,当我禁用ListBox的视图状态时(它也实现了IPostBackDataHandler),它不会在回发中保持其状态。例如,下面提供的代码应该在单击按钮(在同一webform中)时添加重复项(使用空的事件处理程序),但它没有

我是不是遗漏了什么

protected void Page_Load(object sender, EventArgs e)
{
        lbox.Items.Add("1");
        lbox.Items.Add("2");
        lbox.Items.Add("3");
}

在您引用的句子中,“值”一词专门指用户提交表单时浏览器向服务器发布的表单字段值。这些值由以下参数定义:

  • 对于呈现为
    元素的文本框控件,浏览器会发布在文本框中输入的文本。TextBox控件的读取此值并将其指定给Text属性
  • 对于呈现为
    元素的列表框控件,浏览器将发布每个选定
    值。(浏览器不会发布整个
    元素列表。)列表框控件读取这些值并相应地选择/取消选择每个列表项。(该实现不添加任何项。)
重要的一点是,无论视图状态是启用还是禁用,浏览器都会发布这些值。因此,即使视图状态被禁用,
TextBox.Text
ListBox.SelectedValue
也会在回发过程中保留用户的输入


但是,浏览器通常不发布的任何其他内容(如列表框中的选项列表)都需要启用视图状态,以便在回发过程中保留它。

我认为可以从下图中找到答案。(和测试时)

正如您在步骤1中所注意到的,lblMessage.Text中的值是“Hello World!”,没有任何用于引发回发事件阶段的内容,因此该值按原样保留

接下来,对于文本框,即使您禁用特定控件/整个页面的视图状态,也会保存回发事件,这就是为什么如果您查看步骤3,前一次回发会作为加载视图状态阶段的一部分加载,这会使已实例化的“Hello World!”被覆盖

顺便说一句,此解释仅适用于不使用DataSource的控件事件,其他需要DataSource的控件似乎在文档中隐式定义


@kenlacoste您指的是额外的“}”吗?我删除了它。这个答案并没有解释实现IPostBackDataHandler(如TextBox)的控件如何在回发过程中保持其值。是的,我感谢您的缺点,您能够比我更准确地解释问题。:)@埃尔坎纳:很高兴能帮忙!
<asp:Label runat="server" ID="lblMessage" 
  Font-Name="Verdana" Text="Hello, World!"></asp:Label>
<br />
<asp:Button runat="server" 
  Text="Change Message" ID="btnSubmit"></asp:Button>
<br />
<asp:Button runat="server" Text="Empty Postback"></asp:Button>
private void btnSubmit_Click(object sender, EventArgs e)
{
  lblMessage.Text = "Goodbye, Everyone!";
}