[ASP.NET 控件实作 Day27] 控件依 FormView CurrentMode 自行设定状态

GridView+FormView 示范数据 新增/修改/删除(进阶篇:服务器控件) 一文中,示范了扩展 GridView 及 FormView 控件,让 GridView 可以透过属性与 FormView 做关连来处理数据的「新增/修改/删除」的动作。因为在该案例中,只使用 FormView 的 EditTemplate 同时处理「新增」及「修改」的动作,所以还需要自行撰写部分程序代码去判断控件在新增或修改的启用状态,例如编号字段在新增时为启用,修改时就不启用。在该文最后也提及其实有辨法让这个案例达到零程序代码的目标,那就是让控件 (如 TextBox) 自行判断所在的 FormView 的 CurrentMode,自行决定本身是否要「启用/不启用」、「显示/隐藏」等状态。本文以 TextBox 为例,说明如何修改 TextBox 让它可以达到上述的需求。

程序代码下载:ASP.NET Server Control - Day27.rar
Northwnd 数据库下载:NORTHWND.rar

 

一、TBFormViewModeState 类别

[ASP.NET 控件实作 Day27] 控件依 FormView CurrentMode 自行设定状态

我们先定义 EControlState (控件状态) 列举,描述控件在特定模式的状态为何。

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

 

 

 

再来定义 TBFormViewModeState 类别,用来设定控件在各种 FormView 模式 (浏览、新增、修改) 中的控件状态。

''' <summary>
''' 依 FormViewMode 來設定控制項狀態。
''' </summary>
< _
Serializable(), _
TypeConverter(GetType(ExpandableObjectConverter)) _
> _
Public Class TBFormViewModeState
    Private FInsertMode As EControlState = EControlState.NotSet
    Private FEditMode As EControlState = EControlState.NotSet
    Private FBrowseMode As EControlState = EControlState.NotSet
 
    ''' <summary>
    ''' 在新增模式(FormViewMode=Insert)的控制項狀態。
    ''' </summary>
    < _
    NotifyParentProperty(True), _
    DefaultValue(GetType(EControlState), "NotSet") _
    > _
    Public Property InsertMode() As EControlState
        Get
            Return FInsertMode
        End Get
        Set(ByVal value As EControlState)
            FInsertMode = value
        End Set
    End Property
 
    ''' <summary>
    ''' 在編輯模式(FormViewMode=Edit)的控制項狀態。
    ''' </summary>
    < _
    NotifyParentProperty(True), _
    DefaultValue(GetType(EControlState), "NotSet") _
    > _
    Public Property EditMode() As EControlState
        Get
            Return FEditMode
        End Get
        Set(ByVal value As EControlState)
            FEditMode = value
        End Set
    End Property
 
    ''' <summary>
    ''' 在瀏覽模式(FormViewMode=ReadOnly)的控制項狀態。
    ''' </summary>
    < _
    NotifyParentProperty(True), _
    DefaultValue(GetType(EControlState), "NotSet") _
    > _
    Public Property BrowseMode() As EControlState
        Get
            Return FBrowseMode
        End Get
        Set(ByVal value As EControlState)
            FBrowseMode = value
        End Set
    End Property
End Class

 

 

 

定义为 TBFormViewModeState 型别的属性是属于复杂属性,要套用 TypeConverter(GetType(ExpandableObjectConverter)),让该属性可在属性窗口 (PropertyGrid) 扩展以便设定属性值,如下图所示。

[ASP.NET 控件实作 Day27] 控件依 FormView CurrentMode 自行设定状态

 

二、让 TextBox 控件可自行维护状态

接下来扩展 TextBox 控件,继承 TextBox 命名为 TBTextBox。新增 FormViewModeState 属性 (TBFormViewModeState 型别),依 FormView Mode 来设定控件状。并覆写 PreRender 方法,在此方法中呼叫 DoFormViewModeStatus 私有方法,依 FormView 的模式来处理控件状态。

    ''' <summary>
    ''' 文字框控制項。
    ''' </summary>
    < _
    Description("文字框控制項。"), _
    ToolboxData("<{0}:TBTextBox runat=server></{0}:TBTextBox>") _
    > _
    Public Class TBTextBox
        Inherits TextBox
        Private FFormViewModeState As TBFormViewModeState
 
        ''' <summary>
        ''' 依 FormViewMode 來設定控制項狀態。
        ''' </summary>
        < _
        Description("依 FormViewMode 來設定控制項狀態。"), _
        Category(WebCommon.Category.Behavior), _
        NotifyParentProperty(True), _
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), _
        PersistenceMode(PersistenceMode.InnerProperty), _
        DefaultValue("") _
        > _
        Public ReadOnly Property FormViewModeState() As TBFormViewModeState
            Get
                If FFormViewModeState Is Nothing Then
                    FFormViewModeState = New TBFormViewModeState
                End If
                Return FFormViewModeState
            End Get
        End Property
 
        ''' <summary>
        ''' 處理控制項狀態。
        ''' </summary>
        ''' <param name="ControlStatus">控制項狀態。</param>
        Private Sub DoControlStatus(ByVal ControlStatus As EControlState)
            Select Case ControlStatus
                Case EControlState.Enable
                    Me.Enabled = True
                Case EControlState.Disable
                    Me.Enabled = False
                Case EControlState.Hide
                    Me.Visible = 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.FormViewModeState.InsertMode)
                    Case FormViewMode.Edit
                        DoControlStatus(Me.FormViewModeState.EditMode)
                    Case FormViewMode.ReadOnly
                        DoControlStatus(Me.FormViewModeState.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

 

 

三、测试程序

1. 设定控件相关属性

我们使用 Northwnd 数据库的 Products数据表为例,以 GridView+FormView 示范数据「新增/修改/删除」的操作。在页面拖曳 SqlDataSource 控件后,在页面上的使用 TBGridView 来显示浏览数据。TBGridView 的 FormViewID 设为关连的 TBFormVIew 控件;另外有使用到 TBCommandField,设定 ShowHeaderNewButton=True,让命令列具有「新增」钮。

        <bee:TBGridView ID="TBGridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID"
            DataSourceID="SqlDataSource1" CellPadding="4" ForeColor="#333333" 
            GridLines="None" AllowPaging="True" FormViewID="TBFormView1">
            <RowStyle BackColor="#EFF3FB" />
            <Columns>
                <bee:TBCommandField ShowDeleteButton="True" ShowEditButton="True" 
                    ShowHeaderNewButton="True" >
                </bee:TBCommandField>
                
                '省略
                
            </Columns>
        </bee:TBGridView>

 

 

 

 

接下来设定做为新增、编辑使用的 TBFormView 控件,我们只使用 EditItemTemplate 来同时处理新增、删除,所以 EditItemTemplate 需要同时具有「新增」、「更新」、「取消」三个按钮。其中 ProductID 为主索引字段,所以我们使用 TBTextBox 来系结 ProductID 字段,设定 FormViewModeState.InsertMode="Enable" 使控件在新增模式时为可编辑,设定 FormViewModeState.EditMode="Disable" 使控件在修改模式是只读的。

        <bee:TBFormView ID="TBFormView1" runat="server" DataKeyNames="ProductID" DataSourceID="SqlDataSource1"
            DefaultMode="Edit" SingleTemplate="EditItemTemplate" BackColor="White" BorderColor="#CCCCCC"
            BorderStyle="None" BorderWidth="1px" CellPadding="3" GridLines="Both" Visible="False">
            <FooterStyle BackColor="White" ForeColor="#000066" />
            <RowStyle ForeColor="#000066" />
            <EditItemTemplate>
                ProductID:
                <bee:TBTextBox ID="TextBox1" runat="server" Text='<%# Bind("ProductID") %>'> 
                  <FormViewModeState EditMode="Disable" InsertMode="Enable">
                  </FormViewModeState>
                </bee:TBTextBox>
 
                '省略
 
                <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True" CommandName="Insert"
                    Text="新增" />
                &nbsp;<asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" CommandName="Update"
                    Text="更新" />
                &nbsp;<asp:LinkButton ID="UpdateCancelButton" runat="server" CausesValidation="False"
                    CommandName="Cancel" Text="取消" />
            </EditItemTemplate>
        </bee:TBFormView>

 

 

 

2. 测试新增模式

接下来执行程序,一开始为浏览模式,以 TBGridView 来呈现数据。

 

[ASP.NET 控件实作 Day27] 控件依 FormView CurrentMode 自行设定状态

按下 Header 的「新增」钮,就会隐藏 TBGridView,而切换到 TBFormView 的新增模式。其中系结 ProductID 字段的 TBTextBox 为可编辑模式,而下方的按钮只会显示「新增」及「取消」钮。

[ASP.NET 控件实作 Day27] 控件依 FormView CurrentMode 自行设定状态

在新增模式输入完毕后,按下「新增」钮,数据录就会被写入数据库。

[ASP.NET 控件实作 Day27] 控件依 FormView CurrentMode 自行设定状态

3. 测试修改模式

接下来测试修改模式,按下「编辑」钮,就会隐藏 TBGridView,而切换到 TBFormView 的修改模式。其中系结 ProductID 字段的 TBTextBox 为只读模式,而下方的按钮只会显示「更新」及「取消」钮。

 

[ASP.NET 控件实作 Day27] 控件依 FormView CurrentMode 自行设定状态

在修改模式输入完毕后,按下「更新」钮,数据录就会被写入数据库。

[ASP.NET 控件实作 Day27] 控件依 FormView CurrentMode 自行设定状态

4. 页面程序代码

示范了上述的操作后,接下来我们回头看一下页面的程序代码。你没看错,笔者也没贴错,真的是一行程序代码都没有,因为所有相关动作都由控件处理掉了。

Partial Class Day27
    Inherits System.Web.UI.Page
 
 
End Class

 

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

转载于:https://www.cnblogs.com/jeff377/archive/2008/10/28/1321652.html