擴展 TextBox 控制項 - 依 FormViewMode 來自行設定狀態

擴展 TextBox 控制項 - 依 FormViewMode 來自行設定狀態

摘要

延續前面「GridView+FormView 示範資料新增/修改/刪除(進階篇:伺服器控制項)」的文章,文章後記有提及若要達到零程式碼要求,上篇已實作「擴展 CommandField 類別 - Header 加入新增鈕」解決其中一個問題。另一個問題就要擴展 TextBox 控制項,讓 TextBox 可以自行判斷 FormView 的 CurrentMode 來決定 TextBox 的啟用狀態,本文接下來就是來說明如何擴展 TextBox 控制項來達到此需求。

TBFormViewModeStatus 類別

首先我們先定義 TBFormViewModeStatus 類別,此類別是用來設定控制項在每種 FormViewMode 的狀態。TBFormViewModeStatus 類別具有 InsertMode、EditMode、BrowseMode 三個屬性,分別用來設定 FormViewMode 為 Insert、Edit、ReadOnly 三種情形時,TextBox 控制項的啟用狀態。

    ''' <summary>
    ''' 控制項狀態列舉。
    ''' </summary>
    Public Enum EControlStatus
        ''' <summary>
        ''' 不設定。
        ''' </summary>
        NotSet = 0
        ''' <summary>
        ''' 啟用。
        ''' </summary>
        Enable = 1
        ''' <summary>
        ''' 不啟用。
        ''' </summary>
        Disable = 2
    End Enum

    ''' <summary>
    ''' 依 FormViewMode 來設定控制項狀態。
    ''' </summary>
    < _
    Serializable(), _
    TypeConverter(GetType(ExpandableObjectConverter)) _
    > _
    Public Class TBFormViewModeStatus
        Private FInsertMode As EControlStatus = EControlStatus.NotSet
        Private FEditMode As EControlStatus = EControlStatus.NotSet
        Private FBrowseMode As EControlStatus = EControlStatus.NotSet

        ''' <summary>
        ''' 在新增模式(FormViewMode=Insert)的控制項狀態。
        ''' </summary>
        < _
        NotifyParentProperty(True), _
        DefaultValue(GetType(EControlStatus), "NotSet") _
        > _
        Public Property InsertMode() As EControlStatus
            Get
                Return FInsertMode
            End Get
            Set(ByVal value As EControlStatus)
                FInsertMode = value
            End Set
        End Property

        ''' <summary>
        ''' 在編輯模式(FormViewMode=Edit)的控制項狀態。
        ''' </summary>
        < _
        NotifyParentProperty(True), _
        DefaultValue(GetType(EControlStatus), "NotSet") _
        > _
        Public Property EditMode() As EControlStatus
            Get
                Return FEditMode
            End Get
            Set(ByVal value As EControlStatus)
                FEditMode = value
            End Set
        End Property

        ''' <summary>
        ''' 在瀏覽模式(FormViewMode=ReadOnly)的控制項狀態。
        ''' </summary>
        < _
        NotifyParentProperty(True), _
        DefaultValue(GetType(EControlStatus), "NotSet") _
        > _
        Public Property BrowseMode() As EControlStatus
            Get
                Return FBrowseMode
            End Get
            Set(ByVal value As EControlStatus)
                FBrowseMode = value
            End Set
        End Property
    End Class

擴展 TBTextBox 控制項

接下來就是改寫 TextBox 控制項,我們繼承 TextBox 類別命名為 TBTextBox,加入一個 FormViewModeStatus 屬性( TBFormViewModeStatus 型別),用來設定控制項在每種 FormViewMode 的狀態,例如設定 FormViewModeStatus.InsertMode 可以設定 FormViewMode.Insert 情形時,控制項狀態為「不設定、啟用、不啟用」三擇一。主要的作法是覆寫 OnPreRender 方法,在此方法中去呼叫 DoFormViewModeStatus 方法,自行判斷 TextBox 所屬 FormView 的 CurrentMode 來決定本身的狀態。

 

Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Security.Permissions

Namespace WebControls
    < _
    Description("文字框控制項"), _
    ToolboxData("<{0}:TBTextBox runat=server></{0}:TBTextBox>") _
    > _
    Public Class TBTextBox
        Inherits TextBox
        Private FFormViewModeStatus As TBFormViewModeStatus

        ''' <summary>
        ''' 依 FormViewMode 來設定控制項狀態。
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        < _
        Description("依 FormViewMode 來設定控制項狀態"), _
        NotifyParentProperty(True), _
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), _
        PersistenceMode(PersistenceMode.InnerProperty), _
        DefaultValue("") _
        > _
        Public ReadOnly Property FormViewModeStatus() As TBFormViewModeStatus
            Get
                If FFormViewModeStatus Is Nothing Then
                    FFormViewModeStatus = New TBFormViewModeStatus
                End If
                Return FFormViewModeStatus
            End Get
        End Property

        ''' <summary>
        ''' 處理控制項狀態。
        ''' </summary>
        ''' <param name="ControlStatus">控制項狀態。</param>
        Private Sub DoControlStatus(ByVal ControlStatus As EControlStatus)
            Select Case ControlStatus
                Case EControlStatus.Enable
                    Me.Enabled = True
                Case EControlStatus.Disable
                    Me.Enabled = False
            End Select
        End Sub

        ''' <summary>
        ''' 依 FormView 的模式來處理控制項狀態。
        ''' </summary>
        Private Sub DoFormViewModeStatus()
            Dim oFormView As FormView

            '若控制項置於 FormView 中,則依 FormView 的模式來處理控制項狀態
            If TypeOf Me.BindingContainer Is FormView Then
                oFormView = DirectCast(Me.BindingContainer, FormView)
                Select Case oFormView.CurrentMode
                    Case FormViewMode.Insert
                        DoControlStatus(Me.FormViewModeStatus.InsertMode)
                    Case FormViewMode.Edit
                        DoControlStatus(Me.FormViewModeStatus.EditMode)
                    Case FormViewMode.ReadOnly
                        DoControlStatus(Me.FormViewModeStatus.BrowseMode)
                End Select
            End If
        End Sub

        ''' <summary>
        ''' 覆寫。引發 PreRender 事件。
        ''' </summary>
        Protected Overrides Sub OnPreRender(ByVal e As EventArgs)
            MyBase.OnPreRender(e)
            '依 FormView 的模式來處理控制項狀態
            DoFormViewModeStatus()
        End Sub

    End Class
End Namespace

 

使用 TBTextBox 控制項

將 TBTextBox 放置 FormView 的 EditItemTemplate(Edit 及 Insert 共用 Template,即 InsertItemTemplate=EditItemTemplate)中,在 TBTextBox 的屬性視窗中就可以直接設定 FormViewModeStatus 屬性即可。如此就可以不用麻煩的判斷 FormView 的 CurrentMode,又要 FindControl 來做相關設定,就可以真正達到零程式碼的要求了。

image

<bee:TBTextBox ID="txtEmployeeID" runat="server" Text='<%# Bind("EmployeeID") %>'>
    <FormViewModeStatus InsertMode="Enable" EditMode="Disable" />
</bee:TBTextBox>

ASP.NET 魔法學院