首页 文章

即使DropDownList禁用了viestate,SelectedValue仍应返回一个值

提问于
浏览
8

我想我很了解ViewState,但以下是给我一些麻烦:

http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/truly-understanding-viewstate.aspx

即使ViewState被禁用,回发控件(如下拉列表和文本框)也会恢复其发布状态(下拉列表的选定项目已发布),因为即使禁用了ViewState,控件仍然可以发布其值

假设DropDownList将EnableViewState设置为false,那么(根据上面的引用)当用户通过选择DropDownList中的项目发出回发时,以下代码应该导致Label1.Text显示所选项目的值(因此DropDownList.SelectedValue应该返回用户选择的值,即使viewstate被禁用),但我得到一个空字符串:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        string[] number = {"first","second","third"};
        DropDownList1.DataSource = number;
        this.DataBind();

    }
    if (IsPostBack)
    {
       Label1.Text = DropDownList1.SelectedValue; // displays empty string
       // Label1.Text = DropDownList1.SelectedItem.Text; // causes an exception           
       // Label1.Text = DropDownList1.SelectedIndex.ToString(); // displays empty string
    }
}

该文章的作者似乎是这方面的专家,所以我假设我做错了什么!?!

感谢名单

2 回答

  • 1

    没有选定的值,因为:

    1)下拉列表中没有项目,因为您只是第一次将数据绑定到它 . 通常这是一种很好的做法,但是当您关闭ViewState时,您必须每次都为控件显式重新创建数据 .

    2)您正在页面生命周期中将请求字典值应用于控件的点之后(即,在将ViewState恢复到控件期间)绑定数据 . 已发布的值存在于Request字典中,但由于没有项目在下拉列表中,它无法真正做到这一点 . 即使ViewState已关闭,您的作者也是正确的 - 将在生命周期中通常应用ViewState的点处应用已发布的值 .

    如果您要在Init()中为列表重新创建数据,那么将填充下拉列表以显示要应用的已发布值,将应用该下拉列表,并且在您到达时,所选值将可用加载() . 希望这很清楚 . 一些工作代码如下:

    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                Label1.Text = DropDownList1.SelectedValue;
            }
        }
    
        protected void Page_Init(object sender, EventArgs e)
        {
            string[] number = { "first", "second", "third" };
            DropDownList1.DataSource = number;
            DropDownList1.DataBind();
        }
    }
    
  • 17

    这是一个更智能的DropDownList实现 . 不是巨魔或任何东西,但我不敢相信有些限制(阅读:愚蠢)一些ASP.Net控件....

    Public Class DropDownList
        Inherits System.Web.UI.WebControls.DropDownList
    
        Private _SelectedIndex As Integer? = -1
        Private _SelectedValue As String = Nothing
        Private _StateFromClient As Boolean = False
        Private _StateFromLocal As Boolean = False
    
        Protected Overrides Sub OnInit(ByVal e As EventArgs)
            MyBase.OnInit(e)
            Page.RegisterRequiresControlState(Me)
        End Sub
    
        Public Overrides Property SelectedIndex() As Integer
            Get
                If Not _StateFromLocal Then
                    Me.LoadStateFromClient()
    
                    If _StateFromClient Then
                        Return _SelectedIndex
                    End If
                End If
    
                Return MyBase.SelectedIndex
            End Get
            Set(ByVal value As Integer)
                _StateFromLocal = True
                MyBase.SelectedIndex = value
            End Set
        End Property
    
        Public Overrides Property SelectedValue() As String
            Get
                If Not _StateFromLocal Then
                    LoadStateFromClient()
    
                    If _StateFromClient Then
                        Return _SelectedValue
                    End If
                End If
    
                Return MyBase.SelectedValue
            End Get
            Set(ByVal value As String)
                _StateFromLocal = True
                MyBase.SelectedValue = value
            End Set
        End Property
    
        Private Sub LoadStateFromClient()
            If _StateFromClient Then Return
            If _StateFromLocal Then Return
            If Me.IsViewStateEnabled Then Return
            If Not Me.Page.IsPostBack Then Return
    
            If Not _SelectedIndex.HasValue Then
                Throw New Exception("ControlState has not yet been loaded and so state does not exist.")
            End If
            _SelectedValue = Me.Page.Request.Form(Me.UniqueID)
            _StateFromClient = True
        End Sub
    
        Protected Overrides Sub PerformSelect()
            ' Called when DataBound() is called, which can affect the Selected* property values
            _StateFromLocal = True
            MyBase.PerformSelect()
        End Sub
    
        Protected Overrides Function SaveControlState() As Object
            Dim state As Object = MyBase.SaveControlState()
    
            If Me.SelectedIndex >= 0 Then
                If state IsNot Nothing Then
                    Return New Pair(state, Me.SelectedIndex)
                Else
                    Return Me.SelectedIndex
                End If
            Else
                Return state
            End If
        End Function
    
        Protected Overrides Sub LoadControlState(ByVal state As Object)
            If state IsNot Nothing Then
                Dim p As Pair = TryCast(state, Pair)
                If p IsNot Nothing Then
                    MyBase.LoadControlState(p.First)
                    _SelectedIndex = CInt(p.Second)
                Else
                    If (TypeOf (state) Is Integer) Then
                        _SelectedIndex = CInt(state)
                    Else
                        MyBase.LoadControlState(state)
                    End If
                End If
            End If
            MyBase.SelectedIndex = _SelectedIndex
        End Sub
    
    End Class
    

相关问题