为什么DropDownList.SelectedValue依赖于viewstate?

Roy*_*mir 9 forms asp.net viewstate

如果我在我的页面上设置:EnableViewState="true" ViewStateMode="Disabled"- 然后 - 该页面禁用Viewstate(除非覆盖...)

然后,尝试读取(假设控件已在最后一个转储中填充到屏幕并选择了一个值):

MyDDL.SelectedValue 会屈服 ""

这是因为禁用的viewstate:

但我的问题是更高层次:

  • 如果它只是一个表单值(我仍然可以得到Request.Form[MyDDL.UniqueID]) - 我们正在讨论一个输入,它不需要任何东西来保存它的价值.

  • 为什么DropDownList名为(SelectedValue)的属性依赖于ViewState?

ps TextBox onchangeevent确实依赖于viewstate,虽然控件是一个输入(不需要viewstate) - 它保存了文本的值,然后在回发时比较它.但是当你设置onchange事件时它只依赖于viewstate(和autopostback) )

Abh*_*lks 7

SelectedValue依赖于ViewState因为在回发它重建其ListItems从所述ViewState,然后设置在所选择的值DropDownList从所述Request对象.

它不是直接的Request价值SelectedValue.这反过来是因为,ASP.Net可以检查发布DropDownList是否未被客户端篡改.它是通过首先反序列化原始项目来实现的ViewState.然后它Request在项目中找到Value并将其Selected属性设置为true.只有现在,该SelectedValue物业是可用的.(或者SelectedIndex就此而言).它应该能够立即发起一个SelectedIndexChanged事件.

这也是您不需要DropDownList再次绑定的原因PageLoad.列表项自动从中检索ViewState.

如果ViewState禁用,则该中将没有原始列表项,ViewState并且将为空.因此,它将无法将任何项目标记为已选中.因此,SelectedValue将为0或SelectedItem将为null.我认为这次SelectedIndexChanged活动也不会开火.对于在这种情况下工作的事情,需要进行数据绑定,最好是在init.

然而,有一些解决方法.

完整参考:http://msdn.microsoft.com/en-us/library/ms972976.aspx

编辑 :(在Op的评论之后)

在页面生命周期之后查看SelectedValue依赖于哪里ViewState:

阶段1初始化:构建控件层次结构.如果此处绑定了DropDownList或以声明方式添加了ListItem,则此处将填充List.

第2阶段加载ViewState:在PostBack上,ViewState在此处进行验证并加载到DropDownList中.这里没有 SelectedValue.

阶段3加载PostBack数据:此处获取RequestValue(来自表单请求),然后应用于控件.在这种情况下DropDownList,现在设置SelectedValue从接收到的Request对象的值,内部实现是这样的:

string selectedValue = HttpContext.Current.Request.Form[DropDownList_Id];
Items.FindByValue(selectedValue).Selected = true;
Run Code Online (Sandbox Code Playgroud)

这里重要的是,如果ViewState不存在且DropDownList不是数据绑定的,那么ListItem集合将为空,因此SelectedValue属性为0.这与属性的内部实现无关.

如果ViewState不存在(禁用)且DropDownList是数据绑定的,则ListItem集合将存在,相应的项目将被标记为选中,因此SelectedValue属性将返回正确的值.

如果项集合是新的(通过重新绑定不同的数据集或ViewState无效),则Request在项集合中找不到Form值,并且再次SelectedValue无效.

第4阶段页面加载:此时已加载ViewState(或数据绑定)和PostBack数据.

阶段5提升PostBack事件:在此阶段,OnSelectedIndexChanged如果在阶段3中更改了索引,则会触发DropDownList事件.

因此,SelectedValue在第3阶段依赖于ViewState.当然,如果控件是适当的数据绑定,那么它将不依赖于ViewState作为推论.

SelectedValue依赖于ViewState来确保在设置之前填充了项目集合.数据绑定/重新绑定只是确保填充项集合的另一种方法.

希望澄清一下.


Gre*_*reg 6

概要:如果您希望控件在没有ViewState的情况下工作,则需要在每次回发时填充/绑定Items集合.我建议在Page_Init事件中使用它(即OnInit方法).

首先,我总是推荐这篇很棒的文章:TRULY了解ViewState.

SelectedValue不需要ViewState.查看ListControl的代码,DropDownList继承自的代码,我们看到代码:

public virtual string SelectedValue
{
  get
  {
    int selectedIndex = this.SelectedIndex;
    if (selectedIndex >= 0)
      return this.Items[selectedIndex].Value;
    else
      return string.Empty;
  }
Run Code Online (Sandbox Code Playgroud)

从这段代码中删除的重要一点是必须填充Items列表以获取SelectedValue.

如果你使用ViewState的,Items集合保持到/从ViewState中,它允许SelectedValue属性,而无需重新绑定控制工作负载.