ASP.NET控件开发学习笔记--第4回 为控件添加属性

 

4 为控件添加属性

上一回中我们制作了一个稍微复杂一些的控件,但这个控件存在着很多毛病,第一是导航条的标题栏名称被写死为“我的导航控件”,如果想把它改为其他的名称如“我的链接”就无能为力了。另外它完全依赖于xml文件“linksList.xml”,如果给xml文件改个名字就玩完了。有什么办法可以解决呢?当然是添加属性了,属性大家都很熟了,Visual Studio里专门有一个属性窗口来对属性进行设置。好,说做就做,首先打开控件源文件“linksList.cs”并在其中修改代码如下:

4-1代码1linksList.cs代码


using  System;
using  System.Web.UI;
using  System.Data;
using  System.Data.OleDb;
[assembly:TagPrefix(
" MyControl " " CG " )]
namespace  MyControl
{
    
public   class  LinksControl:Control
    {   
// 这里添加了两个用于属性的私有成员变量
         private   string  _titleText = "" ;
        
private   string  _xmlFileName = "" ;
        
// 下面添加了两个属性
         public   virtual   string  TitleText
        {
            
get  {  return  _titleText; }
            
set  { _titleText = value; }
        }
        
public   virtual   string  XmlFileName
        {
            
get  {  return  _xmlFileName; }
            
set  { _xmlFileName = value; }
        }
        
protected   override   void  Render(HtmlTextWriter writer)
        {
            writer.WriteLine(
" <ul> " );
            
// 这里先判断标题名称是否为空然后考虑是否添加标题
             if  (_titleText !=   "" )
            {
                writer.WriteLine(
" <li id='caption'> " + _titleText + " </li> " );
            }
            
string  s;
            
// 判断xml文件是否存在
             if  (_xmlFileName !=   "" )
            {
                DataSet ds
= new  DataSet();
                ds.ReadXml(Page.Server.MapPath(_xmlFileName));
                
foreach (DataRow row  in  ds.Tables[ " link " ].Rows)
                {
                    s
= " <li><a href=' " ;
                    s
+= row[ " url " ].ToString();
                    s
+= " 'target='_blank'> " ;
                    s
+= row[ " name " ].ToString();
                    s
+= " </a></li> " ;
                    writer.WriteLine(s);
                }
            }
            writer.WriteLine(
" </ul> " );
        }
    }
}

 

关于属性,如果有不明白的地方请参考:http://www.enet.com.cn/eschool/video/c/18.shtml 。这里需要注意的是,属性使用了virtual关键字,使这个属性变是虚拟属性,这样做可以使继承你的控件来写新控件的人可以重写这个属性。然后使用属性所指向的成员变量来代替代码中的硬编码部分:

writer.WriteLine("<li id='caption'>"+_titleText+"</li>");

ds.ReadXml(Page.Server.MapPath(_xmlFileName));

当然,新程序对两个属性值如果为空做了处理,但还没处理干净,比如xml文件的后缀名不对或文件不存在等等没有做进一步判断。为了简化代码,这些先暂不考虑。

下面更改aspx文件以使用新添加的属性,打开linkslist.aspx文件,更改代码如下:

4-1代码2linkslist.aspx代码

<% @Register TagPrefix = " CG "  Namespace = " MyControl "   %>
< html >
    
< head >
        
< title > Chapter 5: Background Images </ title >
        
< link  rel ='Stylesheet'  media ="screen"  type ='text/css'  href ='linkslist.css'  />
    
</ head >
    
< body >
    
< CG:LinksControl  TitleText ="我的链接"  XmlFileName ="linksList.xml"  runat ="server"   />
    
</ body >
</ html >
 

这里我们在声明控件时加上了(TitleText="我的链接" XmlFileName="linksList.xml")来设置控件的属性。保存并在浏览器中运行linkslist.aspx文件,看看是否和以前效果一样。为了验证属性的作用,更改TitleText属性看看会有什么效果。再更改xml文件的名称,然后相应地更改XmlFileName属性,看看能否运行成功?

好,现在这个控件貌似已经很不错,但你想在Visual Studio的属性窗口里直接设置属性,现在把控件装到Visual Studio里会在属性窗口里显示这两个新添加的属性吗?当然不行,不过要实现它很简单,只需添加一些特性就行了。打开控件源文件linksList.cs,更改代码如下:

4-2代码1linksList.cs代码

using  System;
using  System.Web;
using  System.Web.UI;
using  System.Data;
using  System.Data.OleDb;
using  System.ComponentModel;
[assembly:TagPrefix(
" MyControl " " CG " )]
namespace  MyControl
{
    [DefaultPropertyAttribute(
" TitleText " )]
    [ToolboxData(
" <{0}:LinksControl  " +
                 
" TitleText='我的链接'  " +  
                 
" XmlFileName='linksList.xml'  " +
                 
" runat='server'></{0}:LinksControl> " )]
    
public   class  LinksControl:Control
    {   
// 这里添加了两个用于属性的私有成员变量
         private   string  _titleText = " 我的链接 " ;
        
private   string  _xmlFileName = "" ;
        
// 下面添加了两个属性
        [BrowsableAttribute( true )]
        [DescriptionAttribute(
" 设置标题栏的名称 " )]
        [DefaultValueAttribute(
" 我的链接 " )]
        [CategoryAttribute(
" 外观 " )]
        
public   virtual   string  TitleText
        {
            
get  {  return  _titleText; }
            
set  { _titleText = value; }
        }
        [BrowsableAttribute(
true )]
        [DescriptionAttribute(
" 存放链接的xml文件名 " )]
        [DefaultValueAttribute(
"" )]
        [CategoryAttribute(
" 数据 " )]
        
public   virtual   string  XmlFileName
        {
            
get  {  return  _xmlFileName; }
            
set  { _xmlFileName = value; }
        }
        
protected   override   void  Render(HtmlTextWriter writer)
        {
            writer.WriteLine(
" <ul> " );
            
// 这里先判断标题名称是否为空然后考虑是否添加标题
             if  (_titleText != "" )
            {
                writer.WriteLine(
" <li id='caption'> " + _titleText + " </li> " );
            }
            
string  s;
            
// 判断xml文件是否存在
             if  (_xmlFileName != "" )
            {
                DataSet ds
= new  DataSet();
                ds.ReadXml(Page.Server.MapPath(_xmlFileName));
                
foreach (DataRow row  in  ds.Tables[ " link " ].Rows)
                {
                    s
= " <li><a href=' " ;
                    s
+= row[ " url " ].ToString();
                    s
+= " 'target='_blank'> " ;
                    s
+= row[ " name " ].ToString();
                    s
+= " </a></li> " ;
                    writer.WriteLine(s);
                }
            }
            writer.WriteLine(
" </ul> " );
        }
    }
}
 

然后保存文件,并把文件剪切到虚拟目录下,然后新建一CompilelinksList.bat文件,用记事本打开,输入代码如下:

4-2代码2CompilelinksList.bat代码

set indir = H:\ASP\linksList.cs
set outdir
= H:\ASP\bin\linksList.dll
csc 
/ t:library  / out: % outdir %   % indir %
pause
 

记住,indiroutdir这两个路径根据你自己的实际情况进行更改。在虚拟目录下新建一bin文件夹,双击CompilelinksList.bat文件编译程序集。然后查看bin文件夹下是否生成linksList.dll文件,如果成功,接着下面步骤。

打开Visual Studio,新建一个ASP.NET Web应用程序,在工具箱内把以前我们加上去的控件删掉(在控件上点右键删除),再把我们新做的控件加上去。加完后把它拖到设计窗体,看到了什么?晕了吧,出错!如图4-1所示:

ASP.NET控件开发学习笔记--第4回 为控件添加属性
 

不要慌张,这只是设计期的错误,无关大局。怎么样在设计期访问xml及显示正确的东西我现在还没搞清楚,学到后面应该就知道了吧!哪位大侠知道的话麻烦告诉我一声,哈哈!好,继续工作。在【解决方案资源管理器】中右键选中项目,选中【添加】|【现有项】把linkslist.csslinksList.xml这两个文件加进来,然后拖动linkslist.css文件到设计窗体。好运行程序看看效果如何!是不是和前面的一样?好,下面就来讲解代码。

代码所更改的地方是增加了一些特性,所以需要引入如下命名空间:

using System.ComponentModel;

先来看第一个增加的特性:

[DefaultPropertyAttribute("TitleText")]

从名字就可以猜出它的作用,“默认属性”,也就是说,用它来指定在属性窗口中默认高亮显示的属性是哪个。再看下一个:

[ToolboxData("<{0}:LinksControl "+

                    "TitleText='我的链接' "+

                    "XmlFileName='linksList.xml' "+

                    "runat='server'></{0}:LinksControl>")]

这个也很好理解,如果刚才做的例子没有关的话,看看源代码,注意控件声明的地方:

    <CG:LinksControl ID="LinksControl1" runat="server" TitleText="我的链接"

        XmlFileName="linksList.xml">

    </CG:LinksControl>

跟上面对比一下,很相似吧!只是{0}这个参数被CG所替代。这个特性的作用就是当拖动控件到设计窗体时,定制声明这个控件的代码。

[BrowsableAttribute(true)]

指定一个属性 (Property) 或事件是否应显示在“属性”窗口中。它在哪个属性前面使用就指的是这个属性。

[DescriptionAttribute("设置标题栏的名称")]

属性的描述,当一个属性处于选中状态时,属性窗口最下方会显示有关这个属性的描述,这个特性就是设置这个描述信息的。

[DefaultValueAttribute("")]

属性的默认值,也就是第一次拖动控件到设计窗体时,属性窗口中这个属性所显示的值是什么。

[CategoryAttribute("外观")]

当属性窗口分类显示时,里面有好几个栏,你希望把这个属性放到哪个栏里呢?想放哪就放哪,设置这个特性值就OK了。

好,喝茶时间到,还有什么问题下一回再解决。


你可能感兴趣的:(asp.net)