在 ASP.NET 中,控件的属性与 ViewState 有着密不可分的关系,透过 ViewState 才有辨法维护控件的属性值。在本文中将介绍属性与 ViewState 的关系,并说明属性如何存取 ViewState 是比较有效率的方式。

 

一、属性与 VIewState

当你加入一个「ASP.NET 服务器控件」时,类别中预设会有一个 Text 属性写法的范例如下所示,属性的读写都是直接存取 ViewState,这是一般常见的控件属性写法。可是这种属性的写法是没有效率的,因为 ViewState 的成员是 Object 型别,每次读取属性时都是由 ViewState 取出指定键值的成员再转型为属性的型别,写入属性的动作也是直接写入 ViewState 中。

 

    Property Text() As String
        Get
            Dim s As String = CStr(ViewState("Text"))
            If s Is Nothing Then
                Return String.Empty
            Else
                Return s
            End If
        End Get
 
        Set(ByVal Value As String)
            ViewState("Text") = Value
        End Set
    End Property

 

比较好的方式应该是读取 ViewState 成员只做一次型别转换的动作,而写入 ViewState 的动作可以在 Render 前做批次写入的动作即可。为了达到这样的需求,我们可以覆写 LoadViewState 及 SaveViewState 方法来处理属性与 ViewState 的存取动作;当控件初始化后会执行 LoadViewState 方法,来加载 ViewState 还原的控件状态,当控件 Render 之前,会执行 SaveViewState 方法,将控件的最终状态存入 ViewState 中,也就是在此方法之后对控件所做的任何变更都将会被忽略。

我们改写属性的写法,不直接用 ViewState 来存取属性,而是改用「属性区域变量」来存取属性,在 LoadViewState 时加载 ViewState 到属性区域变量,而 SaveViewState 时再将属性区域变量写入 ViewState 中。我们依此方式将 Text 属性改写如下。

    Private FText As String
 
    Property Text() As String
        Get
            Return FText
        End Get
        Set(ByVal Value As String)
            FText = Value
        End Set
    End Property
 
    ''' <summary>
    ''' 載入 ViewState 還原控制項狀態。
    ''' </summary>
    Protected Overrides Sub LoadViewState(ByVal savedState As Object)
        If Not (savedState Is Nothing) Then
            ' Load State from the array of objects that was saved at vedViewState.
            Dim myState As Object() = CType(savedState, Object())
 
            If Not (myState(0) Is Nothing) Then
                MyBase.LoadViewState(myState(0))
            End If
 
            If Not (myState(1) Is Nothing) Then
                FText = CType(myState(1), String)
            End If
        End If
    End Sub
 
    ''' <summary>
    ''' 將控制項狀態寫入 ViewState 中。
    ''' </summary>
    Protected Overrides Function SaveViewState() As Object
        Dim baseState As Object = MyBase.SaveViewState()
        Dim myState(1) As Object
        myState(0) = baseState
        myState(1) = FText
        Return myState
    End Function

 

 

利用上述的方式,我们可以在 LoadViewState 批次加载所有属性值,而在 SaveViewState 批次写入属性值,如此在读取属性就不用一直做型别转换的动作以改善效率。

 

二、结语

虽然属性一般都是储存于 ViewState 中,不过若是一些无关紧要的属性或是完全不会执行阶段就变更的属性,可以考虑不需要将这些属性储存于 ViewState 中;因为 ViewState 是个两面刃,ViewState 可以很轻易帮我们维护属性值,不过相对的也增加了面页的传输量,所以可以视实际情形来决定属性是否要储存于 ViewState 中。

 

备注:本文同步发布于「第一届iT邦帮忙铁人赛」,如果你觉得这篇文章对您有帮助,记得连上去推鉴此文增加人气 ^^
http://ithelp.ithome.com.tw/question/10011745

posted on 2008-10-14 07:00  jeff377  阅读(448)  评论(0编辑  收藏  举报