代码改变世界

利用APSX页面作为模版文件的实现(二)

2007-08-22 22:26  麦舒  阅读(2776)  评论(8编辑  收藏  举报
 

在上一篇里,给大家介绍了模版页面的读取,很感谢各位朋友的参与。现在就再给大家具体介绍一下如何实现在VS里实现模版“所见即所得”。

采用模版这种技术,其目的主要是为了方便美工设计页面,如果我们所提供的模版页面能提供“所见即所得”的编辑模式,无疑是更便于他们进行设计。

现在我们还是先从一个小例子里来开始我们学习。打开项目中的“WebExample2”工程,其结构如图所示。


点击下面的链接下载源文件:


/Files/ansiboy/Project1.rar
















打开该项目“
Default1.aspx”文件,代码如:

<%@ Page Language="C#" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    
<title>Untitled Page</title>
</head>
<body>
    
<form id="form1" runat="server">
        
<div>
            
<img id="image1" src="Template/<%=ConfigurationManager.AppSettings["TemplateName"] %>/Images/Sidebar.gif"/>
        
</div>
    
</form>
</body>
</html>

切换到“设计模式”,显示如下,很明显,无法正把图片显示出来。

现在再打开项目“Default2.aspx”文件,代码如下:

<%@ Page Language="C#" %>
<%@ Register Namespace="Kolo.BBS.Web.Controls" TagPrefix="Kolo" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title>Untitled Page</title>
</head>
<body>
    
<form id="form1" runat="server">
    
<div>
    
<Kolo:Image ID="image1" Src="Style1/Images/Sidebar.gif" runat="server" />
    
</div>
    
</form>
</body>
</html>


切换到“设计模式”,显示如下,可以看到,现在能把图片显示出来了。


现在我们来解决两个问题:

1、 Default1.aspx”为什么不能正确显示图片?

2、 Default2.aspx”如何正确地显示图片?

先来解决第一个问题:
“default.aspx"文件的图片呈现语句如下:

<img id="image1" src="Template/<%=ConfigurationManager.AppSettings["TemplateName"] %>/Images/Sidebar.gif"/>

语句包含了一个运行时的变量,也就是“<%=ConfigurationManager.AppSettings["TemplateName"] %>”,它的值,只能在运行时才能确定,因为,当页面仅处于设计模式,该数值无法正确计算,因此无没将该图片正确显示。如果我们在“设计模式”下,能够给VS提供该数值,那岂不是就能正确把图片给显示出来了?没错,这就是我们解决问题的方法,不过实现起来,稍微复杂。

现在我们就来解决第二个问题,先把“Default2.aspx”中呈现图片的语句找出来:

<Kolo:Image ID="image1" Src="Style1/Images/Sidebar.gif" runat="server" />

其中的“Kolo:Image”标记,表示的是一个Kolo.BBS.Web.Controls.Image的类,在App_Code/Image.cs文件中,打开该文件,如下:

using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.Design;

/// <summary>
/// Summary description for Class2
/// </summary>

namespace Kolo.BBS.Web.Controls
{
    [Designer(
typeof(ImageDesinger))]
    
public class Image : Control
    
{
        
private string src = string.Empty;
        
private string alt = string.Empty;
        
private string style;

        
public string Src
        
{
            
get return src; }
            
set { src = value; }
        }


        
public string Alt
        
{
            
get return alt; }
            
set { alt = value; }
        }


        
public string Style
        
{
            
get return style; }
            
set { style = value; }
        }


        
protected override void Render(HtmlTextWriter writer)
        
{
            
if (Visible)
            
{
                
string pathName = Page.Request.ApplicationPath + "/Template/" + src;
                writer.WriteLine(
string.Format(@"<img src=""{0}"" alt=""{1}"" style=""{2}"" />",
                    pathName, alt, style)); 
            }

        }


    }


    
class ImageDesinger : ControlDesigner
    
{
        
private string path;

        
public override void Initialize(IComponent component)
        
{
            
base.Initialize(component);
            IWebApplication webApp 
= (IWebApplication)Component.Site.GetService(typeof(IWebApplication));
            path 
= webApp.RootProjectItem.PhysicalPath + "Template/";
        }


        
public override string GetDesignTimeHtml()
        
{
            
string html;
            Image image 
= (Image)Component;
            html 
= string.Format(@"<img src=""{0}"" alt=""{1}"" style=""{2}"" />"
                path 
+ image.Src, image.Alt, image.Style);
            
return html;
        }

    }
 
}


 

我们可以看到,该文件所了包Image类外,还包含了一个命为ImageDesinger的类,该类主要负责控件设计时的呈现。在Image类的初始化函数中,有这样一条语句:

[Designer(typeof(ImageDesinger))]

这条语句将ImageDesinger指定为Image类的设计器,在VS的“设计模式”, VS在加载了Image控件后,先调用ImageDesinger. Initialize进行初始化,再调用ImageDesinger. GetDesignTimeHtml方法,实现控件的设计时的呈现。
从而实现了“所见即所得”的设计模式。