为了帮助您理解《Asp.Net Forums2.0深入分析》之 Asp.Net Forums是如何实现代码分离和换皮肤的,现在我们一起来写一个代码分离带换皮肤功能的登陆页面:
第一步:新建ThemeDemo项目
第二步:添加基类SkinnedWebControl.cs
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
namespace WebUC.ThemeDemo.Controls
{
[
ParseChildren(
true)
]
/// <summary>
/// 换皮肤控件基类
/// </summary>
public abstract class SkinnedWebControl : WebControl, INamingContainer
{
string skinFilename =
null;
protected override void CreateChildControls()
{
Control skin;
// 装载用户控件文件
skin = LoadSkin();
// 初始化控件和对控件绑定
InitializeSkin(skin);
Controls.Add(skin);
}
/// <summary>
/// 装载用户控件文件
/// </summary>
/// <returns></returns>
protected Control LoadSkin()
{
Control skin;
// 用户控件文件默认放在Themes目录下
string skinPath = "Themes/" + SkinFilename;
// 是否定义了用户控件文件?
if (SkinFilename ==
null)
throw new Exception("必须定义SkinFilename属性,指定用户控件文件路径");
// 通过Page.LoadControl(defaultSkinPath)方法,从用户控件文件中获取 UserControl 对象
try
{
skin = Page.LoadControl(skinPath);
}
catch (FileNotFoundException)
{
throw new Exception("用户控件文件未找到!");
}
return skin;
}
/// <summary>
/// 初始化控件,并绑定控件数据
/// </summary>
/// <param name="skin"></param>
protected abstract void InitializeSkin(Control skin);
/// <summary>
/// 用户控件文件路径
/// </summary>
public string SkinFilename
{
get {
return skinFilename;}
set { skinFilename =
value; }
}
}
}
第三步:创建Themes目录,并创建两个用户控件文件Login.ascx和Login1.ascx。布局样式不同,但是都必须包含以下控件:
TextBox Username
TextBox Password
Button LoginButton
Label Result
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"/>
第四步:创建Login控件Login.cs
using System;
using System.Web;
using System.Web.UI.WebControls;
namespace WebUC.ThemeDemo.Controls
{
/// <summary>
/// 登陆控件,继承自SkinnedWebControl
/// </summary>
public class Login : SkinnedWebControl
{
string skinFilename = "Login.ascx";
// 指定默认皮肤样式
TextBox username;
// 帐号输入框
TextBox password;
// 密码输入框
Button loginButton;
// 登陆按钮
Label result;
// 显示登陆结果
public Login()
{
if (SkinFilename ==
null)
SkinFilename = skinFilename;
}
/// <summary>
/// 重写InitializeSkin,初始化控件和对控件进行绑定
/// </summary>
/// <param name="skin"></param>
protected override void InitializeSkin(System.Web.UI.Control skin)
{
// 查找ascx页中ID是username的textbox控件
username = (TextBox) skin.FindControl("Username");
// 绑定数据
username.Text = "demo";
// 查找ascx页中ID是password的textbox控件
password = (TextBox) skin.FindControl("Password");
// 绑定数据
password.Attributes.Add("value","demo");
// 初始化Result控件
result = (Label) skin.FindControl("Result");
// 找到登陆按钮
loginButton = (Button) skin.FindControl("LoginButton");
loginButton.Click +=
new System.EventHandler(LoginButton_Click);
// 绑定登陆按钮的Click事件
}
/// <summary>
/// 响应登陆按钮事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void LoginButton_Click(Object sender, EventArgs e)
{
if (username.Text == "demo" && password.Text == "demo")
result.Text = "<font color='blue'>登陆成功!";
else
result.Text = "<font color='red'>登陆失败,用户名密码不匹配!";
}
}
}
第五步:新建两个aspx页,分别把两种风格的登陆控件加入。
Login.aspx
<%@ Register TagPrefix="uc" Namespace="WebUC.ThemeDemo.Controls" Assembly="ThemeDemo" %>
<HTML>
<HEAD>
<title>换皮肤控件测试——默认皮肤</title>
</HEAD>
<body>
<form runat="server">
<uc:Login runat="server"/>
</form>
</body>
</HTML>
Login1.aspx
<%@ Register TagPrefix="uc" Namespace="WebUC.ThemeDemo.Controls" Assembly="ThemeDemo" %>
<HTML>
<HEAD>
<title>换皮肤控件测试——另一皮肤</title>
</HEAD>
<body>
<form runat="server">
<uc:Login runat="server" SkinFilename="Login1.ascx"/>
</form>
</body>
</HTML>
最后,分别运行看看效果:)
源码下载