ASP.NET控件开发基础之自定义控件样式属性浅析

开发 后端
ASP.NET控件开发基础之自定义控件样式属性主要向你讲述自定义控件样式属性的基本情况,希望你对自定义控件样式属性有所了解。

ASP.NET控件开发基础之自定义控件样式属性是怎么样的呢?首先让我们来看看,位于WebControls命名空间的style类为顶级样式类.大部分标准控件都拥有其样式属性.

ASP.NET控件开发基础之自定义控件样式属性1.下面为设置样式方法

(1)你可以直接设置控件样式

Button1.BackColor = System.Drawing.Color.Red;

(2)通过获取web控件的样式集合来设置

Button1.ControlStyle.BackColor = System.Drawing.Color.Red;

(3)通过设置样式类,利用WebControl类的ApplyStyle方法来复制非空样式,并改写现有样式

  1. myStyle.BackColor = System.Drawing.Color.Red;  
  2.  
  3. Button1.ApplyStyle(myStyle); 

(4)一直定义样式表属性,不使用控件属性,与定义HTML样式相同.

 style="background-color: red"

下面引出话题,为什么要使用样式?大家知道定义样式可以使用统一风格,定义好的样式,可以重复使用.再回来看上面设置样式方法.

ASP.NET控件开发基础之自定义控件样式属性2.了解WebControl.BackColor和Style.BackColor

(1)和(2)是差不多的.但(3)则不同,(3)的定义方法有通用性,你可以定义一种样式,然后利用控件的ApplyStyle方法来引用样式.给样式编程提供了方面

WebControl类定义了通用的样式.(1)和(2)使用的样式属性为

WebControl.BackColor

(3)则不同,使用的为

Style.BackColor

3.自定义样式属性

刚开始就讲了style类为通用的顶级样式类,但需求是会发生变化的. 好了,下面真正开始编码了.

下面以改写label控件为例子

(1)改写样式属性,让其默认背景为红色,相信大家一定看的懂

示例一

  1. namespace CustomComponents  
  2. {  
  3.     [ToolboxData(@"﹤{0}:ImageLabel1   
  4.     BackColor='Red' 
  5.     runat='server'﹥﹤/{0}:ImageLabel1﹥")  
  6.     ]  
  7.     public class ImageLabel1 : Label  
  8.     {  
  9.         public override string Text  
  10.         {  
  11.             get { return ViewState["Text"] != null ? (string)ViewState["Text"] : base.ID; }  
  12.             set { ViewState["Text"] = value; }  
  13.         }  
  14.  
  15.         public override System.Drawing.Color BackColor  
  16.         {  
  17.             get 
  18.             {  
  19.                 return base.BackColor = System.Drawing.Color.Red;  
  20.             }  
  21.             set 
  22.             {  
  23.                 base.BackColor = value;  
  24.             }  
  25.         }  
  26.     }  

控件初始效果为下图

控件初始效果 

(2)为label新增一个背景图片的属性,重写了一下AddAttributesToRender方法,添加一个样式属性,AddAttributesToRender方法以前为大家讲过,这里不多讲了.

示例二

  1. namespace CustomComponents  
  2. {  
  3.     public class ImageLabel2 : Label  
  4.     {  
  5.         [BrowsableAttribute(true)]  
  6.         [DescriptionAttribute("背景")]  
  7.         [CategoryAttribute("Appearance")]  
  8.         public virtual String ImageUrl  
  9.         {  
  10.             get { return ViewState["imageUrl"] != null ? (string)ViewState["imageUrl"] : ""; }  
  11.             set { ViewState["imageUrl"] = value; }  
  12.         }  
  13.         override protected void AddAttributesToRender(HtmlTextWriter writer)  
  14.         {  
  15.             writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, ImageUrl);  
  16.             base.AddAttributesToRender(writer);  
  17.         }  
  18.     }  

使用控件效果如下

使用控件效果 

(3)上面示例二中我们定义了背景样式,其实.net已经为我们把工作做好了

从style类派生了很多样式类,扩展了style类的属性,满足不同控件样式的需求.

WebControl类中有一个CreateControlStyle 方法,其返回为一个样式集合.其默认情况下实现如下

  1. protected override Style CreateControlStyle()  
  2. {  
  3.     return new Style(ViewState);  

我们可以通过改写此方法来使控件拥有style派生类的功能,改写后如下,让label控件拥有TableStyle类的样式

  1. protected override Style CreateControlStyle()  
  2. {  
  3.     return new TableStyle(ViewState);  

注意点:默认情况下,当label控件使用ApplyStyle复制除style之外的样式属性集合,将只返回默认style类的样式属性集合.

看了下面效果后请再回头再理解这句话.

看下面自定义控件代码,真是简单的不的了

示例三

  1. namespace CustomComponents  
  2. {  
  3.     public class ImageLabel3 : Label  
  4.     {  
  5.  
  6.         protected override Style CreateControlStyle()  
  7.         {  
  8.             return new TableStyle(ViewState);  
  9.         }  
  10.     }  

再看默认label控件与其的对比,因为没有给控件定义样式属性,所以只能通过编程的方式来定义样式,如下

示例四

  1. protected void Page_Load(object sender, EventArgs e)  
  2. {  
  3.     //默认label控件  
  4.     TableStyle a = new TableStyle();  
  5.     a.BackImageUrl = "images4.bmp";  
  6.     a.BackColor = System.Drawing.Color.Red;  
  7.     Label1.ApplyStyle(a);  
  8.     //自定义控件  
  9.     ImageLabel3_1.ApplyStyle(a);  

看一下,使用的效果,看到下面效果再来理解下我上面说的注意点吧.我想这样会理解的更深刻.

控件效果 

(4)使用派生样式类,定义控件样式属性.示例四中说过了,没有定义控件样式属性,只改写了CreateControlStyle方法.那就意味了你定义的控件样式属性可以直接使用TableStyle类中的属性,但默认情况下的样式属性为style类中属性,所以需要强行转换.如下对比

默认情况下

  1. public override Color BackColor  
  2. {  
  3.     get 
  4.     {  
  5.         return ((Style)ControlStyle).BackColor;  
  6.     }  
  7.     set 
  8.     {  
  9.         ((Style)ControlStyle).BackColor = value;  
  10.     }  

定义TableStyle样式属性,必须转换为TableStyle类型

  1. public virtual string BackImageUrl  
  2. {  
  3.     get { return ((TableStyle)ControlStyle).BackImageUrl; }  
  4.     set { ((TableStyle)ControlStyle).BackImageUrl = value; }  

好了,讲清楚上面这一点.我们再来测试一下.看下面示例(还是采用我们第一讲的例子)

下面只给出定义样式属性的代码,其他的类似.


控件样式#region 控件样式

  1. protected override Style CreateControlStyle()  
  2. {  
  3.  
  4.     return new TableStyle(ViewState);  
  5. }  
  6.  
  7. [BrowsableAttribute(true)]  
  8. [DescriptionAttribute("网格线")]  
  9. [CategoryAttribute("Appearance")]  
  10. public virtual GridLines GridLines  
  11. {  
  12.     get { return ((TableStyle)ControlStyle).GridLines; }  
  13.     set { ((TableStyle)ControlStyle).GridLines = value; }  
  14. }  
  15.  
  16. [BrowsableAttribute(true)]  
  17. [DescriptionAttribute("单元格间距")]  
  18. [CategoryAttribute("Appearance")]  
  19. public virtual int CellSpacing  
  20. {  
  21.     get { return ((TableStyle)ControlStyle).CellSpacing; }  
  22.     set { ((TableStyle)ControlStyle).CellSpacing = value; }  
  23. }  
  24.  
  25. [BrowsableAttribute(true)]  
  26. [DescriptionAttribute("单元格边距")]  
  27. [CategoryAttribute("Appearance")]  
  28. public virtual int CellPadding  
  29. {  
  30.     get { return ((TableStyle)ControlStyle).CellPadding; }  
  31.     set { ((TableStyle)ControlStyle).CellPadding = value; }  
  32. }  
  33.  
  34. [BrowsableAttribute(true)]  
  35. [DescriptionAttribute("表水平对齐")]  
  36. [CategoryAttribute("Appearance")]  
  37. public virtual HorizontalAlign HorizontalAlign  
  38. {  
  39.     get { return ((TableStyle)ControlStyle).HorizontalAlign; }  
  40.     set { ((TableStyle)ControlStyle).HorizontalAlign = value; }  
  41. }  
  42.  
  43. [BrowsableAttribute(true)]  
  44. [DescriptionAttribute("表背景图片")]  
  45. [CategoryAttribute("Appearance")]  
  46. public virtual string BackImageUrl  
  47. {  
  48.     get { return ((TableStyle)ControlStyle).BackImageUrl; }  
  49.     set { ((TableStyle)ControlStyle).BackImageUrl = value; }  
  50. }  
  51.  
  52. #endregion 

使用此控件

  1. ﹤custom:CreditCardForm6 BackColor="Black" ForeColor="White" runat="server" ID="example" 
  2.   Font-Bold="true" Font-Italic="true" GridLines="None" CellSpacing="5"   
  3.   BackImageUrl="images4.bmp" Font-Size="Larger" 
  4.   BorderColor="Yellow" BorderWidth="20px" BorderStyle="Ridge" HorizontalAlign="NotSet" EnableViewState="False" /﹥ 

效果如下

控件效果 

好了,上面的基础讲完了.希望大家能够有所理解.下面还我们要讲一个重点的东西.

ASP.NET控件开发基础之自定义控件样式属性4.自定义类型化样式属性

如果样式属性无法满足你需求,则你可以通过自定义类型化样式来实现.

什么是自定义类型化样式?就是该类从style类派生,对其进行修改和扩充(书上就这么写了...我就这么理解了-_-)

如Table控件,一方面控件自身定义的样式属性,另一方面又定义了TableStyle类.你可以在使用控件样式属性和TableStyle类中进行选择.

但TableStyle类具有通用性,具有一定的灵活性.好了下面我们又要开始看代码了.当然从简单开始

(1)简单呈现样式属性

ASP.NET控件开发基础之自定义控件样式属性需要说明的注意点如下

1.重写LabelStyle(StateBag viewState)构造函数

2.样式属性需用视图状态来声明

3.Style类的重载的AddAttributesToRender方法需用两个参数的方法

AddAttributesToRender(HtmlTextWriter writer, WebControl owner)

示例5  自定义类型化样式:LabelStyle类  

  1. public class LabelStyle :Style  
  2. {  
  3.     public LabelStyle() { }  
  4.     public LabelStyle(StateBag viewState) : base(viewState) { }  
  5.  
  6.     public virtual String ImageUrl  
  7.     {  
  8.         get { return ViewState["imageUrl"] != null ? (string)ViewState["imageUrl"] : ""; }  
  9.         set { ViewState["imageUrl"] = value; }  
  10.     }  
  11.  
  12.     public override void AddAttributesToRender(HtmlTextWriter writer, WebControl owner)  
  13.     {  
  14.         writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, ImageUrl);  
  15.  
  16.           
  17.         base.AddAttributesToRender(writer, owner);  
  18.     }  

下面再来看控件实现方法,注意此处CreateControlStyle方法返回为自己定义的LabelStyle(ViewState)

示例6

  1. public class ImageLabel4 : Label  
  2. {  
  3.     protected override Style CreateControlStyle()  
  4.     {  
  5.         return new LabelStyle(ViewState);  
  6.     }  
  7.  
  8.     [Bindable(true),  
  9.     Category("Appearance"),  
  10.     DefaultValue(""),  
  11.     Description("背景图片")  
  12.     ]   
  13.     public virtual String ImageUrl  
  14.     {  
  15.         get { return ((LabelStyle)ControlStyle).ImageUrl; }  
  16.         set { ((LabelStyle)ControlStyle).ImageUrl = value; }  
  17.     }  

让我们来测试一下,你会发现界面上并未呈现背景图片,给控件加一个属性CssClass=""以后效果就出来了,如下

控件效果 

让我们来思考为什么在未定义CssClass=""属性时无法呈现自定义属性.

Style类有一个IsEmpty属性用来判断已在的视图状态中是否定义了样式属性,
默认情况下为true,当定义了样式属性后,则为false.CssClass属性为空时,默认情况下即认为定义了样式属性,只不过样式属性个数为0.

若要在默认情况下呈现自定义样式属性则需重写IsEmpty属性.如下,只要判断自定义的样式属性视图状态是否为空即可.

示例7

  1. //判断视图状态是否为空  
  2. internal bool IsSet(string key)  
  3. {  
  4.     return ViewState[key] != null;  
  5. }  
  6.  
  7. /**//// ﹤summary﹥  
  8. /// 是否定义样式元素  
  9. /// ﹤/summary﹥  
  10. public override bool IsEmpty  
  11. {  
  12.     get 
  13.     {  
  14.         return base.IsEmpty && !IsSet("imageUrl");  
  15.     }  

(2)使用编程

下面我们以编程方式,给控件添加自定义样式属性.
发现BackColor属性能够呈现但ImageUrl 无法呈现,那说明我们刚才自定义的类就失去意义了,也说明我们还未重写某个方法.

  1. LabelStyle a = new LabelStyle();  
  2.      a.ImageUrl = "images4.bmp";  
  3.      a.BackColor = System.Drawing.Color.Red;  
  4.      ImageLabel4_1.ApplyStyle(a); 

Style类有三个操作样式的方法,复制,合并和清除样式.WebControl类也一样.重写一下,我们的目的就达到了.看下面代码

示例8

方法#region 方法

  1. /**//// ﹤summary﹥  
  2. ///  复制样式  
  3. /// ﹤/summary﹥  
  4. /// ﹤param name=""﹥﹤/param﹥  
  5. public override void CopyFrom(Style s)  
  6. {  
  7.     if (s == null)  
  8.         return;  
  9.  
  10.     base.CopyFrom(s);  
  11.     LabelStyle ls = s as LabelStyle;  
  12.     if (ls == null || ls.IsEmpty)  
  13.         return;  
  14.  
  15.     if (ls.IsSet("imageUrl"))  
  16.         this.ImageUrl = ls.ImageUrl;  
  17. }  
  18.  
  19. /**//// ﹤summary﹥  
  20. /// 整合样式  
  21. /// ﹤/summary﹥  
  22. /// ﹤param name="s"﹥﹤/param﹥  
  23. public override void MergeWith(Style s)  
  24. {  
  25.     if (s == null)  
  26.         return;  
  27.  
  28.     if (IsEmpty)  
  29.     {  
  30.         CopyFrom(s);  
  31.         return;  
  32.     }  
  33.  
  34.     LabelStyle ls = s as LabelStyle;  
  35.     if (ls == null || ls.IsEmpty)  
  36.         return;  
  37.  
  38.     if (ls.IsSet("imageUrl") && !IsSet("imageUrl"))  
  39.         this.ImageUrl = ls.ImageUrl;  
  40. }  
  41.  
  42. /**//// ﹤summary﹥  
  43. /// 清除样式  
  44. /// ﹤/summary﹥  
  45. public override void Reset()  
  46. {  
  47.     base.Reset();  
  48.     if (IsEmpty)  
  49.         return;  
  50.  
  51.     if (IsSet("imageUrl"))  
  52.         ViewState.Remove("imageUrl");  
  53. }  
  54. #endregion 

好了,再次编译测试一下,效果也出来了.

这里再写一点.再呈现的时候可以重写另一个方法来代替AddAttributesToRender方法,如下

  1. protected override void FillStyleAttributes(CssStyleCollection attributes, IUrlResolutionService urlResolver)  
  2. {  
  3.     base.FillStyleAttributes(attributes, urlResolver);  
  4.     attributes.Add(HtmlTextWriterStyle.BackgroundImage, ImageUrl);  

关于对样式的理解基本的东西就先写这么多吧.大家看完了再回去看看,注意步骤就可以了.重在理解.

好久没写了发现自己写的又挺长的,写的好累呀...希望对大家有帮助吧.

ASP.NET控件开发基础之自定义控件样式属性的基本情况就向你介绍到这里,希望对你有所帮助。

【编辑推荐】

  1. ASP.NET控件开发基础之事件处理浅析
  2. ASP.NET服务器控件之RenderContents简介
  3. ASP.NET服务器控件之RenderContents应用示例
  4. ASP.NET控件开发基础之RenderContents使用浅析
  5. ASP.NET自定义控件属性浅析
责任编辑:仲衡 来源: 博客园
相关推荐

2009-08-06 09:18:01

ASP.NET自定义控ASP.NET控件开发

2009-08-06 17:13:56

ASP.NET自定义控

2009-07-28 09:32:41

ASP.NET自定义控

2009-08-10 14:16:59

ASP.NET自定义控

2009-08-07 11:12:58

ASP.NET控件开发

2009-07-31 10:23:09

ASP.NET源码DateTimePic

2011-04-19 10:33:16

ASP.NET自定义控

2009-08-06 18:18:27

ASP.NET控件开发ASP.NET复合控件

2009-08-04 13:35:16

ASP.NET自定义样

2009-08-07 13:31:41

ASP.NET控件开发

2009-08-07 14:05:21

ASP.NET控件

2009-08-07 10:34:56

ASP.NET控件开发

2009-08-06 15:21:45

ASP.NET控件开发RenderConte

2009-08-07 15:24:16

ASP.NET模板控件

2009-07-28 16:21:03

Asp.net AjaAutoComplet

2009-08-06 13:08:23

ASP.NET控件开发

2009-08-06 18:32:00

ASP.NET控件开发ASP.NET复合控件

2009-08-05 18:46:21

ComboBox显示ASP.NET控件开发

2009-08-05 17:11:51

ASP.NET控件开发ASP.NET服务器控

2009-08-07 15:34:15

ASP.NET数据绑定
点赞
收藏

51CTO技术栈公众号