zoukankan      html  css  js  c++  java
  • asp.net Forums 之控件研究

    今天看了一下asp.net Forums,来说说它的皮肤控件。

    首先说说它的皮肤控件基类:SkinnedForumWebControl,这个类位于AspNetForums.Controls命名空间下。

    代码
    #region VSS

    /*
    * $Header: /HiForums/Controls/BaseClasses/SkinnedForumWebControl.cs 1 05-10-26 15:04 Jacky $
    *
    * $History: SkinnedForumWebControl.cs $
    *
    * ***************** Version 1 *****************
    * User: Jacky Date: 05-10-26 Time: 15:04
    * Created in $/HiForums/Controls/BaseClasses
    *
    * ***************** Version 1 *****************
    * User: Jacky Date: 05-10-21 Time: 14:20
    * Created in $/HiForums/Controls/BaseClasses
    *
    * ***************** Version 3 *****************
    * User: Jacky Date: 05-09-20 Time: 19:15
    * Updated in $/ASP.NET Forums/Controls/BaseClasses
    */

    #endregion

    using System;
    using System.IO;
    using System.Web.UI;
    using AspNetForums.Components;
    using AspNetForums.Enumerations;

    namespace AspNetForums.Controls
    {
    [
    ParseChildren(
    true)
    ]
    /// <summary>
    /// 皮肤控件基类
    /// </summary>
    public abstract class SkinnedForumWebControl : Control, INamingContainer
    {
    #region 成员字段

    private ForumContext forumContext = ForumContext.Current;
    private string skinFilename = null;
    private string skinName = null;
    // string returnURL = null;
    private ITemplate inlineSkin = null;
    private ForumMode mode = ForumMode.User;

    #endregion

    #region 构造函数

    // *********************************************************************
    // SkinnedForumWebControl
    //
    /// <summary>
    /// Constructor
    /// </summary>
    // ***********************************************************************/
    public SkinnedForumWebControl()
    {
    // What skin should be used?
    //
    if (forumContext.User.IsAnonymous)
    {
    skinName
    = Globals.Skin;
    }
    else
    {
    skinName
    = forumContext.User.Theme;
    }

    }

    #endregion

    #region 子控件创建

    // *********************************************************************
    // CreateChildControls
    //
    /// <summary>
    /// This event handler adds the children controls.
    /// </summary>
    // ***********************************************************************/
    protected override void CreateChildControls()
    {
    Control skin
    = null;

    if (inlineSkin != null)
    {
    inlineSkin.InstantiateIn(
    this);

    InitializeSkin(
    this);

    }
    else
    {
    // Load the skin
    skin = LoadSkin();

    // Initialize the skin
    InitializeSkin(skin);

    Controls.Add(skin);
    }
    }

    #endregion

    #region 调用皮肤

    // *********************************************************************
    // LoadControlSkin
    //
    /// <summary>
    /// Loads the names control template from disk.
    /// </summary>
    // ***********************************************************************/
    protected Control LoadSkin()
    {
    Control skin;
    string skinPath = Globals.GetSkinPath() + "/Skins/" + SkinFilename.TrimStart('/');
    string defaultSkinPath = Globals.ApplicationPath + "/Themes/default/Skins/" + SkinFilename.TrimStart('/');

    // Do we have a skin?
    if (SkinFilename == null)
    throw new Exception("You must specify a skin.");

    // Attempt to load the control. If this fails, we're done
    try
    {
    skin
    = Page.LoadControl(skinPath);
    }
    catch (FileNotFoundException)
    {
    // Ok we couldn't find the skin, let's attempt to load the default skin instead
    try
    {
    skin
    = Page.LoadControl(defaultSkinPath);
    }
    catch (FileNotFoundException)
    {
    throw new Exception("错误:皮肤文件 " + skinPath + " 没有找到. 皮肤必须被指定,以用于控件的呈现.");
    }
    }

    return skin;
    }

    #endregion

    #region 皮肤初始化(抽像类)

    // *********************************************************************
    // InitializeSkin
    //
    /// <summary>
    /// Initialize the control template and populate the control with values
    /// </summary>
    // ***********************************************************************/
    protected abstract void InitializeSkin(Control skin);

    #endregion

    #region 公有属性:皮肤文件名

    // *********************************************************************
    // SkinName
    //
    /// <summary>
    /// Allows the default control template to be overridden
    /// </summary>
    // ***********************************************************************/
    public string SkinFilename
    {
    get { return skinFilename; }
    set { skinFilename = value; }
    }

    #endregion

    #region 皮肤名

    // *********************************************************************
    // SkinName
    //
    /// <summary>
    /// Used to construct paths to images, etc. within controls.
    /// </summary>
    ///
    // ********************************************************************/
    protected string SkinName
    {
    get { return skinName; }
    set { skinName = value; }
    }

    #endregion

    #region 公有属性:皮肤

    public ITemplate Skin
    {
    get { return inlineSkin; }
    set { inlineSkin = value; }
    }

    #endregion

    #region 公有属性:论坛模式

    public ForumMode Mode
    {
    get { return mode; }
    set { mode = value; }
    }

    #endregion
    }
    }

    它继承于Control, INamingContainer,Control是所有控件的基类,而INamingContainer按口标识在 System.Web.UI.Page 对象的控件层次结构内创建新 ID 命名空间的容器控件,也就是说实现了此接口,它能够帮你完成父子控件的命名工作,实现如下效果:“tr1_td1_control1”。

    SkinnedForumWebControl基类的主要工作是重写了基类的CreateChildControls方法。

    代码
    protected override void CreateChildControls()
    {
    Control skin
    = null;

    if (inlineSkin != null)
    {
    inlineSkin.InstantiateIn(
    this);

    InitializeSkin(
    this);

    }
    else
    {
    // Load the skin
    skin = LoadSkin();

    // Initialize the skin
    InitializeSkin(skin);

    Controls.Add(skin);
    }
    }


    当内部皮肤控件不为空时,加载内部皮肤控件。
    注:这个内部皮肤控件是一个ITemplate(模板接口)里面可以放任意服务器端控件。

    不然,由LoadSkin()方法加载经子类指定了用户控件名称的皮肤控件初始化后添加到Controls中。

    InitializeSkin()是一个abstract方法,由子类来实现数据绑定,注册事件等行为。

    LoadSkin方法如下:

    代码
    protected Control LoadSkin()
    {
    Control skin;
    string skinPath = Globals.GetSkinPath() + "/Skins/" + SkinFilename.TrimStart('/');
    string defaultSkinPath = Globals.ApplicationPath + "/Themes/default/Skins/" + SkinFilename.TrimStart('/');

    // Do we have a skin?
    if (SkinFilename == null)
    throw new Exception("You must specify a skin.");

    // Attempt to load the control. If this fails, we're done
    try
    {
    skin
    = Page.LoadControl(skinPath);
    }
    catch (FileNotFoundException)
    {
    // Ok we couldn't find the skin, let's attempt to load the default skin instead
    try
    {
    skin
    = Page.LoadControl(defaultSkinPath);
    }
    catch (FileNotFoundException)
    {
    throw new Exception("错误:皮肤文件 " + skinPath + " 没有找到. 皮肤必须被指定,以用于控件的呈现.");
    }
    }

    return skin;
    }

     基类完成后,我们要做的就是实现各种皮肤的用户控件和子类控件。然后在网页上通过ContentContainer控件来调用。

    这就是Asp.Net Forums的换肤原理,欢迎各位达人指正。

  • 相关阅读:
    redis数据结构底层剖析学习笔记2
    redis数据结构底层剖析学习笔记1
    java正则表达式学习笔记
    springmvc sessionfilter 登录过滤器
    Java中JSON字符串与java对象的互换实例详解
    用9种办法解决 JS 闭包经典面试题之 for 循环取 i
    近期流行的JavaScript框架与主题
    JavaScript 中的 this 问题总结 !
    常见前端面试题及答案(下)
    常见前端面试题及答案(上)
  • 原文地址:https://www.cnblogs.com/Jesong/p/1751423.html
Copyright © 2011-2022 走看看