小强


For my summer
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Community Starter Kit中如何加载外观

Posted on 2005-07-06 01:59  小 强  阅读(1196)  评论(3编辑  收藏  举报
以下内容来自MSDN提供的文档(Architecture.htm)

Community Starter Kit是建立在ASP.NET Forums Application(在www.ASP.net网站上可以见到)基础之上的。与Forums Application一样,Community Starter Kit通过外观将用户接口从代码中分割出来。

Community Starter Kit使用如下四种类型的外观:

·  页面外观 - 页面外观用于确定整个页面的布局。例如,页面外观可用于确定区导航菜单的位置。通常,一个社区只选用一个页面外观。

·  内容外观 - 内容外观应用于页面中的内容区域。例如,有一种内容外观用于登陆界面以确定该页面的外观样式。通常,社区中每个页面有一个内容外观相对应。

·  控件外观 - 控件外观用于定制控件的外观样式。例如,区导航控件就是一个外观化的控件。通过将不同的外观应用于该控件,可以改变区导航菜单的外观。

·  模板外观 - 模板外观用于确定控件模板的外观样式(如Repeater控件中的ItemTemplateHeaderTemplate模板)。不同的注释视图--直线式视图、内嵌视图、嵌套视图,通过不同的模板外观来实现。

每当加载一个Community Starter Kit页面,同时会加载许多个外观来确定该页面的外观。例如,如果你选择了主题Robotico并需要进入登陆页面的话,下面的外观将被加载(这里还不是全部的列表):

·  Robotico的页面外观,位于\Themes\Robotico\Skins\PageSkins\Default.ascx

·  登陆页面的内容外观,位于\Themes\Robotico\Skins\ContentSkins\Users_Login.ascx

·  区菜单的控件外观,位于\Themes\Robotico\Skins\ControlSkins\Sections_SectionMenu.ascx

外观具有的可继承性使得外观操作变得更加复杂。如果某个外观不能加载到特定的主题上去,默认主题的外观会加载这很重要,意味着当你创建一个新主题时,你不用为每个页面和控件都创建一个外观。你只需要覆盖你想要修改的外观就可以了。

外观 是作为一个只包含HTML内容和ASP.NET控件(无代码)的ASP.NET用户控件而被执行的。例如,登陆页面的Users_Login.ascx 外观如下所示:

 

<%@ Control %>

<p>

Login

</p>

Please enter your username and password below.

<br>

If you are a new user, click <a href="Users_Register.aspx">here</a> to register.

 

<asp:Panel id="pnlInvalidUsername" Runat="Server">

          The username you entered is invalid!

</asp:Panel>

 

<asp:Panel id="pnlInvalidPassword" Runat="Server">

          The password you entered is invalid!

</asp:Panel>

 

<table>

<tr>

          <td>Username:</td>

          <td><asp:TextBox id="txtUsername" Columns="20" runat="server" /></td>

</tr>

<tr>

          <td>Password:</td>

          <td><asp:TextBox id="txtPassword" Columns="20" TextMode="Password" runat="server" /></td>

</tr>

<tr>

          <td colspan="2"><asp:Button id="btnLogin" runat="server" Text="Login" /></td>

</tr>

</table>

 

<p>

Click <asp:HyperLink id="lnkPasswordReminder" Runat="Server" Text="here" /> for a password reminder.

</p>

 

 

请注意,该外观只包含HTMLASP.NET控件,如TextBox控件。

Community Starter Kit中的所有页面从根本上说都是继承自基类SkinnedCommunityControl。基类SkinnedCommunityControl规定了控件所需加载的外观的所有细节。

基类SkinnedCommunityControl有一个很重要的属性(property)和一个很重要的方法(method)必须覆盖,即SkinType属性和InitializeSkin方法。SkinType属性是与控件有关的外观的类型:内容外观,控件外观或模板外观。InitializeSkin方法从外观中返回所有的控件,可以在代码中处理控件的属性。

例如,登陆页面对应的类(Login.cs class)如下所示:

Login.cs

 

namespace ASPNET.StarterKit.Communities {

 

    using System;

    using System.Web.UI;

    using System.Web.UI.WebControls;

    using ASPNET.StarterKit.Communities;

    using System.Web.Security;

 

    //*********************************************************************

    //

    // Login Class

    //

    // Represents the user login page which enables

    // users to login to the community.

    //

    //*********************************************************************

 

    public class Login : SkinnedCommunityControl {

   

        string _skinFileName = "Users_Login.ascx";

 

        TextBox txtUsername;

        TextBox txtPassword;

        CheckBox chkPersist;

        Button btnLogin;

        Panel pnlInvalidUsername;

        Panel pnlInvalidPassword;

        HyperLink lnkPasswordReminder;

 

 

 

        //*********************************************************************

        //

        // Login Constructor

        //

        // Calls the base SkinnedCommunityControl constructor

        // and assigns the default page skin.

        //

        //*********************************************************************

 

                    public Login() : base() {

            // Assign a default skin file name

            if (SkinFileName == null)

                SkinFileName = _skinFileName;

        }

       

 

        //*********************************************************************

        //

        // SkinType Property

        //

        // Specifies the skins directory where this page's skin file is located.

        //

        //*********************************************************************

       

        override protected string SkinType {

            get { return "ContentSkins"; }

        }

 

 

        //*********************************************************************

        //

        // InitializeSkin Method

        //

        // Retrieves all the controls from the Page Skin

        //

        //*********************************************************************

 

        override protected void InitializeSkin(Control skin) {

            // Find the Username TextBox

            txtUsername = (TextBox)GetControl(skin, "txtUsername");

 

            // Find the Password TextBox

            txtPassword = (TextBox)GetControl(skin, "txtPassword");

            txtPassword.TextChanged += new System.EventHandler(btnLogin_Click);

 

            // Find the Persist Checkbox (Optional)

            chkPersist = (CheckBox)GetOptionalControl(skin, "chkPersist");

           

            // Find the Invalid Username Panel

            pnlInvalidUsername = (Panel)GetControl(skin, "pnlInvalidUsername");

            pnlInvalidUsername.Visible = false;

           

            // Find the Invalid Password Panel

            pnlInvalidPassword = (Panel)GetControl(skin, "pnlInvalidPassword");

            pnlInvalidPassword.Visible = false;

                       

            // Find Login Button

            btnLogin = (Button)GetControl(skin, "btnLogin");

                     btnLogin.Click += new System.EventHandler(btnLogin_Click);

 

            // Find password reminder

            lnkPasswordReminder = (HyperLink)GetControl(skin, "lnkPasswordReminder");

            lnkPasswordReminder.NavigateUrl = "~/Users_PasswordReminder.aspx";

        }

 

       

        //*********************************************************************

        //

        // btnLogin_Click Method

        //

        // Checks username and password against database. If

        // everything checks, logins the user.

        //

        //*********************************************************************

       

        void btnLogin_Click(Object s, EventArgs e) {

            bool blPersist = false;

           

            // Determine whether password should be persisted

            if (chkPersist != null)

                blPersist = chkPersist.Checked;

           

            // Either login or display error message

            switch ( UserUtility.LoginUser(txtUsername.Text,txtPassword.Text) ) {

                case 0: // Success!

                    FormsAuthentication.SetAuthCookie(txtUsername.Text, blPersist);

                    string redirectUrl = FormsAuthentication.GetRedirectUrl(txtUsername.Text, blPersist).ToLower();

                    if (redirectUrl.IndexOf("users_logout.aspx") == -1)

                        Context.Response.Redirect(redirectUrl);

                    else

                        Context.Response.Redirect(CommunityGlobals.ResolveBase("default.aspx"));

                    break;

                case 1: // Invalid Password

                    pnlInvalidPassword.Visible = true;

                    pnlInvalidUsername.Visible = false;

                    break;

                case 2: // Invalid Username

                    pnlInvalidUsername.Visible = true;

                    pnlInvalidPassword.Visible = false;

                    break;

            }   

        }      

 

 

 

    }

}

 

Login 类的SkinType属性将与该类相关的外观识别为内容外观。这意味着控件将从Themes 文件夹下的ContentSkins子目录中加载外观。

InitializeSkin方法通过调用GetControl()方法从内容外观中返回所有控件。GetControl()方法是SkinnedCommunityControl基类的一个方法,用以从外观中返回某个特定的控件。在上例中,InitializeSkin方法从内容外观中返回了txtUsername txtPassword TextBoxes btnLogin Button控件

btnLogin Button控件从内容外观中返回后,便与btnLogin_Click事件响应相关联。点击登陆按钮后,就会执行btnLogin_Click方法,通过数据库验证用户的身份。

Community Starter Kit 中的所有页面的实现方法都与登陆页面一样。每个页面包含一个类和一个外观。外观 决定了页面的外观,类实现了页面的所有功能。

Community Starter Kit 中的所有页面都通过执行InitializeSkin方法从与页面有关的内容外观中加载控件。当控件加载完毕后,控件的属性可以被修改。

用于生成页面的这种方法的优点在于,仅仅通过为页面加载不同的外观就可以显著地改变页面外观。如果你选择不同的主题比如Arc, Robotico, Professional –就会有不同的外观与页面相关联,社区站点的外观也就改变了。(以上内容来自MSDN提供的文档(Architecture.htm))

Community Starter Kit的源码我也只是看了半天,也不能清楚的说明到底是如何工作的,但在下面的内容或许会能你点参考

Skin.ascx文件中会有这样的写法:<community:SectionMenu CssClass="SectionMenu" Runat="Server">(页面顶部会有这样的语句:<%@ Register TagPrefix="community" Namespace="ASPNET.StarterKit.Communities" Assembly="ASPNET.StarterKit.Communities" %>)

你可以在类视图中找到SectionMenu类,它同样继承自SkinnedCommunityControl基类,而SkinnedCommunityControl基类是继承自WebControl的,所以页面中的那种写发实际上就是在用一个自己写的WebControl,了解这一点就容易理解了,你可以自己的看看SectionMenu类和SkinnedCommunityControl基类,在基类中重载了CreateChildControls这个方法(通知使用基于合成的实现的服务器控件创建它们包含的任何子控件,以便为回发或呈现做准备(来自.NET2003帮助文档)),它是在CommunityDefault.aspx页面中的Page_Init方法执行完后自动执行的(这个我还不清楚为什么是在这个时候执行)。

诸如加载外观,加载外观里的控件以及绑定数据的操作都是在CreateChildControls方法中完成的。这样一来,页面才算是真正的生成了。

由于我看得也不是很透彻,所以即使是这点简单的描述也难免会有错误,所以有错误请大家尽量的指出来,这样会加快大家学习Community Starter Kit的过程!让我们共同进步!