ASP Forum2.0学习笔记之三---换肤的vb实现

来源:互联网 发布:c语言中exchange 编辑:程序博客网 时间:2024/06/06 00:10

继续,换肤功能的实现:master pages保持的是框架,但要做到真正的个性化,还得需要自己写代码。接下来,让我们看看内容的换肤。

以下代码来自于宝玉的BLOGhttp://webuc.net/dotey/archive/2004/05/28/835.aspx。不过,是c#的,没有VB的,我改了一下。同时,讲得不细,不合一般入门级用户,我补充细一点。

(1)    打开一个Project

    新建一个Themes的文件夹,然后加入两个文件:

    ·Login.ascx

    其代码如下:

<P>登陆页的默认皮肤样式</P>

<P>用户名:<asp:TextBox id="Username" runat="server"></asp:TextBox></P>

<P> 码:<asp:TextBox id="Password" runat="server" TextMode="Password" /></P>

<P><asp:Button id="LoginButton" runat="server" Text="登陆" /></P>

<P><asp:Label id="Result" runat="server" /></P>

 

 

   ·Login1.ascx

  代码如下:

<P>登陆页的皮肤样式1</P>

用户名:<asp:TextBox id="Username" runat="server" />

码:<asp:TextBox id="Password" runat="server" TextMode="Password" />

<asp:Button id="LoginButton" runat="server" Text="登陆" /><asp:Label id="Result" runat="server" />

  注意:VS自动生成的代码都可以删除掉,因为不需要。这里的代码只一个模板的作用。

 

 

 

 

(2)    新建一个Class的文件夹

加入一个SkinnedWebControl类,这是我们所有外观页面的基类

代码如下:

Imports System

Imports System.Web

Imports System.Web.UI

Imports System.Web.UI.WebControls

Imports System.IO

 

 

 

 

 

 

Namespace WebUC.ThemeDemo.Controls

 

 

 

 

    Public MustInherit Class SkinnedWebControl

        '/ <summary>

        '/ 换皮肤控件基类

        '/ </summary>

        Inherits WebControl

        Implements INamingContainer 'ToDo: Add Implements Clauses for implementation methods of these interface(s)

 

 

        Private skinFilenamePrv As String = Nothing

 

 

 

 

 

 

        Protected Overrides Sub CreateChildControls()

            Dim skin As Control

 

 

            ' 装载用户控件文件

            skin = LoadSkin()

 

 

            ' 初始化控件和对控件绑定

            InitializeSkin(skin)

 

 

            Controls.Add(skin)

        End Sub 'CreateChildControls

 

 

 

 

 

 

        '/ <summary>

        '/ 装载用户控件文件

        '/ </summary>

        '/ <returns></returns>

        Protected Function LoadSkin() As Control

            Dim skin As Control

 

 

            ' 用户控件文件默认放在Themes目录下

            Dim skinPath As String = "Themes/" + skinFilenamePrv

 

 

            ' 是否定义了用户控件文件?

            If skinFilenamePrv Is Nothing Then

                Throw New Exception("必须定义SkinFilename属性,指定用户控件文件路径")

            End If

            ' 通过Page.LoadControl(defaultSkinPath)方法,从用户控件文件中获取 UserControl 对象

            Try

                skin = Page.LoadControl(skinPath)

            Catch

            End Try

 

 

            Return skin

        End Function 'LoadSkin

 

 

 

 

 

 

        '/ <summary>

        '/ 初始化控件,并绑定控件数据

        '/ </summary>

        '/ <param name="skin"></param>

        Protected MustOverride Sub InitializeSkin(ByVal skin As Control)

 

 

        '/ <summary>

        '/ 用户控件文件路径

        '/ </summary>

        Public Property SkinFilename() As String

            Get

                Return skinFilenamePrv

            End Get

            Set(ByVal Value As String)

                skinFilenamePrv = Value

            End Set

        End Property

    End Class 'SkinnedWebControl

End Namespace 'WebUC.ThemeDemo.Controls

这段代码的类图如下:

继承自WebControl基类,引入INameingContainer接口,防止重名。

重载CreateChildControls方法,此方法调用自定义LoadSkin方法装入皮肤。皮肤最后是使用Page.LoadControl(defaultSkinPath)方法,从用户控件文件中获取 UserControl 对象实现的。

 

 

再新类一个Login.vb的文件:

写入以下代码:

Imports System

Imports System.Web

Imports System.Web.UI.WebControls

 

 

 

 

Namespace WebUC.ThemeDemo.Controls

 

 

    '/ <summary>

    '/ 登陆控件,继承自SkinnedWebControl

    '/ </summary>

    Public Class Login1

        Inherits SkinnedWebControl

 

 

        Private skinFilename1 As String = "Login.ascx" ' 指定默认皮肤样式

        Private username As TextBox ' 帐号输入框

        Private password As TextBox ' 密码输入框

        Private loginButton As Button ' 登陆按钮

        Private result As Label

        ' 显示登陆结果

        Public Sub New()

            If SkinFilename Is Nothing Then

                SkinFilename = skinFilename1

            End If

        End Sub 'New

 

 

        '/ <summary>

        '/ 重写InitializeSkin,初始化控件和对控件进行绑定

        '/ </summary>

        '/ <param name="skin"></param>

        Protected Overrides Sub InitializeSkin(ByVal skin As System.Web.UI.Control)

            ' 查找ascx页中IDusernametextbox控件

            username = CType(skin.FindControl("Username"), TextBox)

            ' 绑定数据

            username.Text = "demo"

 

 

            ' 查找ascx页中IDpasswordtextbox控件

            password = CType(skin.FindControl("Password"), TextBox)

            ' 绑定数据

            password.Attributes.Add("value", "demo")

 

 

            ' 初始化Result控件

            result = CType(skin.FindControl("Result"), Label)

 

 

            ' 找到登陆按钮

            loginButton = CType(skin.FindControl("LoginButton"), Button)

            AddHandler loginButton.Click, AddressOf LoginButton_Click ' 绑定登陆按钮的Click事件

        End Sub 'InitializeSkin

 

 

 

 

        '/ <summary>

        '/ 响应登陆按钮事件

        '/ </summary>

        '/ <param name="sender"></param>

        '/ <param name="e"></param>

        Public Sub LoginButton_Click(ByVal sender As [Object], ByVal e As EventArgs)

            If username.Text = "demo" And password.Text = "demo" Then

                result.Text = "<font color='blue'>登陆成功!"

            Else

                result.Text = "<font color='red'>登陆失败,用户名密码不匹配!"

            End If

        End Sub 'LoginButton_Click

    End Class 'Login

End Namespace 'WebUC.ThemeDemo.Controls

注意:

由于我们前面使用了Login.ascx用户控件。它会自动生成一个Login类。这个类是不需要的。可以删除它的代码。为了方便起见。在这儿,我们的类叫Login1,而不是Login

这是类图。最重要的是这个类,重写了InitializeSkin方法。此方法中

' 找到登陆按钮

            loginButton = CType(skin.FindControl("LoginButton"), Button)

            AddHandler loginButton.Click, AddressOf LoginButton_Click ' 绑定登陆按钮的Click事件

这样的方式来处理控件和事件。此前这些代码由系统自动生成,现在则不得不新自来处理。这算是一种代价吧。

(3)    新建一个SkinTest.aspx页面。

代码如下:

<%@ Page Language="vb" AutoEventWireup="false" Codebehind="SkinTest.aspx.vb" Inherits="hello.SkinTest"%>

<%@ Register TagPrefix="uc" Namespace="hello.WebUC.ThemeDemo.Controls" assembly="hello" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

       <HEAD>

              <title>SkinTest</title>

              <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">

              <meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">

              <meta name="vs_defaultClientScript" content="JavaScript">

              <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">

       </HEAD>

       <body MS_POSITIONING="GridLayout">

              <form id="Form1" method="post" runat="server">

                            <uc:Login1 runat="server" ID="Login" NAME="Login"/>

                            <uc:Login1 runat="server" SkinFilename="Login1.ascx" ID="Login1" NAME="Login1"/>

 

 

              </form>

       </body>

</HTML>

在这里,我们将展示一下新的用户控件方式:

<%@ Register TagPrefix="uc" Namespace="hello.WebUC.ThemeDemo.Controls" assembly="hello" %>而不是<%@ Register TagPrefix="uc1" TagName="Login" Src="Themes/Login.ascx" %>。后一种方式可以由VS自动产生,前一种就不行了,又是手动。

注意:namespace那儿一定要跟类视图一致。

 

 

OK,看一下成果吧。

总结一下:

使用换肤功能:有得有失,得到的是更好的界面。失去的,是不得不手动写的代码和方便。

 

 

原创粉丝点击