2009-06-07 23 views
8

Tôi nghĩ rằng tôi hiểu ViewState khá tốt, nhưng sau đây là đem lại cho tôi một số khó khăn:Thậm chí nếu DropDownList có viestate khuyết tật của nó, SelectedValue vẫn phải trả lại một giá trị

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

điều khiển Postback chẳng hạn như danh sách thả xuống và hộp văn bản phục hồi trạng thái đã đăng của họ (mục được chọn của một dropdown ist 'posted') ngay cả khi ViewState bị vô hiệu hóa, bởi vì ngay cả với ViewState đã tắt, điều khiển vẫn có thể đăng giá trị của nó


Giả sử DropDownList đã EnableViewState thiết lập để sai, sau đó (theo trích dẫn ở trên) khi người dùng đưa ra một postback bằng cách chọn một mục trong DropDownList, đoạn code sau nên kết quả trong Label1 .Text hiển thị giá trị của một mục đã chọn (do đó DropDownList.SelectedValue phải trả lại giá trị được người dùng chọn, ngay cả khi bị tắt chế độ xem), nhưng thay vào đó tôi nhận được một chuỗi rỗng:

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 
    } 
} 


Tác giả của bài viết đó dường như là một chuyên gia về đề tài này, vì vậy tôi giả sử tôi đang làm một cái gì đó sai!?!


thanx

+1

Bạn thấy gì khi bạn kiểm tra Yêu cầu [DropDownList1.ClientID] trên postback? –

+0

Khi đăng lại yêu cầu [DropDownList1.ClientID] không trả về giá trị đã chọn – SourceC

+0

Tôi không chắc chắn rằng ClientID là lựa chọn tốt nhất ... Tôi là UniqueID là một trong đó phù hợp trong 'Request.Form [DropDownList1.UniqueID]' – Jaider

Trả lời

17

Không có giá trị được lựa chọn vì:

1) không có các mục trong danh sách thả xuống, bởi vì bạn chỉ được ràng buộc dữ liệu vào nó lần đầu tiên xung quanh . Thông thường đây là thực hành tốt, nhưng khi bạn đã tắt ViewState, bạn phải tạo lại dữ liệu cho điều khiển một cách rõ ràng mỗi lần.

2) Bạn đang ràng buộc dữ liệu sau điểm trong vòng đời của trang mà các giá trị Yêu cầu từ điển được áp dụng cho điều khiển (cụ thể là trong quá trình khôi phục ViewState để điều khiển.) Giá trị đã đăng tồn tại trong Từ điển yêu cầu, nhưng vì không có mục nào trong danh sách thả xuống, nó không thể thực sự làm được nhiều với nó. Mặc dù ViewState bị tắt, tác giả của bạn là chính xác - giá trị được đăng sẽ được áp dụng, tại thời điểm trong vòng đời nơi ViewState thường được áp dụng.

Nếu bạn muốn tạo lại dữ liệu cho danh sách trong Init(), thì danh sách thả xuống sẽ được áp dụng cho giá trị được đăng, nó sẽ được áp dụng và giá trị đã chọn sẽ có sẵn thời gian bạn đã tải(). Hy vọng điều đó rõ ràng. Một số mã hoạt động dưới đây:

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(); 
    } 
} 
+0

a) Tôi giả định Yêu cầu giá trị từ điển là áp dụng cho điều khiển trong giai đoạn LoadPostbackData ?! b) Có một câu hỏi ngu ngốc - nhưng nó sẽ không làm cho senese cho SelectedValue vẫn giữ một giá trị của một mục được chọn, ngay cả khi mục đó không còn tồn tại (do ViewState bị tắt)? Bằng cách đó, chúng ta có thể nhận được giá trị đã chọn mà không cần phải tạo lại dữ liệu trong DropDownList ?! – SourceC

+0

Tôi đã gặp phải vấn đề này. Tôi quyết định rằng tôi tốt hơn việc trích xuất các giá trị từ Request.Params ngày của riêng tôi hơn là kiểm soát repopulating vì lý do duy nhất của việc sử dụng .SelectedValue – Vnuk

1

Đây là một triển khai DropDownList thông minh hơn nhiều. Không phải để troll hoặc bất cứ điều gì, nhưng tôi không thể tin như thế nào hạn chế (đọc: ngu ngốc) một số các điều khiển ASP.Net là ....

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 
Các vấn đề liên quan