惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News | PayPal Newsroom
P
Proofpoint News Feed
Cyberwarzone
Cyberwarzone
C
Cisco Blogs
SecWiki News
SecWiki News
Know Your Adversary
Know Your Adversary
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Vercel News
Vercel News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
NISL@THU
NISL@THU
WordPress大学
WordPress大学
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
Threat Research - Cisco Blogs
AI
AI
Simon Willison's Weblog
Simon Willison's Weblog
Security Archives - TechRepublic
Security Archives - TechRepublic
有赞技术团队
有赞技术团队
L
LINUX DO - 热门话题
Hacker News: Ask HN
Hacker News: Ask HN
V
V2EX
G
GRAHAM CLULEY
TaoSecurity Blog
TaoSecurity Blog
Hugging Face - Blog
Hugging Face - Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
F
Fortinet All Blogs
博客园 - 叶小钗
博客园 - 三生石上(FineUI控件)
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
Latest news
Latest news
The Hacker News
The Hacker News
aimingoo的专栏
aimingoo的专栏
T
Troy Hunt's Blog
S
Schneier on Security
I
Intezer
Google DeepMind News
Google DeepMind News
A
Arctic Wolf
Apple Machine Learning Research
Apple Machine Learning Research
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threatpost
爱范儿
爱范儿
The Register - Security
The Register - Security
S
SegmentFault 最新的问题
Blog — PlanetScale
Blog — PlanetScale
博客园 - 聂微东
宝玉的分享
宝玉的分享
Recent Commits to openclaw:main
Recent Commits to openclaw:main
美团技术团队
B
Blog RSS Feed

博客园 - xiaolei1982

asp.net的ajax的实现 spring:bean生命周期(转贴) 在myeclipse下整合spring和hibernate(转贴) Struts+Spring+Hibernate练习(转贴) spring:bean注入(转贴) - xiaolei1982 - 博客园 解析eclipse下生成Hibernate DAO中的几个方法(转贴) ASP.NET ViewState 实现分析(转贴) 自定义控件源码(转贴) ASP.NET服务器控件的开发(4)(转贴) ASP.NET服务器控件的开发(2) (转贴) ASP.NET服务器控件的开发(1)(转贴) Web 页本是无状态而断续的(转贴) asp.net控件开发基础(3)(转贴) asp.net控件开发基础(6)(转贴) asp.net控件开发基础(5)(转贴) asp.net控件开发基础(4)(转贴) asp.net控件开发基础(2)(转贴) asp.net控件开发基础(1)(转贴) C#中使用反射显示程序集的所有类型和属性(转贴)
ASP.NET服务器控件的开发(3)(转贴)
xiaolei1982 · 2008-04-19 · via 博客园 - xiaolei1982

3.3          System.Web.UI.WebControls.Style类介绍

 
     该类是一个样式类,这个类可对由WebControl类继承的控件添加了样式属性,具体的做法我们在下面会介绍的。当然
我们也可以创建继承自该类的自定义样式类,为我们的控件添加更加多的样式特性。下面我们开始介绍Style类中的方法和属
性,最后我们会结合实例来说明自定义样式类的使用方法。
 
3.3.1     CopyFrom方法和MergeWith方法
 
    这两个方法我们在讲WebControl类的ApplyStyle和MergeStyle方法时已经有所提到。一般当我们创建自定义样式类的
时候都会重写这2个方法,将我们自定义的样式特性添加到自定义样式类中。当我们重写这两个方法时要记住调用父类Style
中的这两个方法。
 
3.3.2     AddAttributesToRender方法
 
    该方法是我们创建自定义样式类是比较重要的方法,我们一般会重写该方法将自定义样式特性添加到输出流。当然当我们
重写该方法时务必调用基类中的该方法。
这里我们先来看下Style类的构造函数代码:
//该构造函数一般在我们重写继承自WebControl类的控件的CreateControlStyle方法时使用
public Style(StateBag bag)
{
          //设置statebag为传入的StateBag类对象,一般为我们定义的控件的ViewState属性。
      this.statebag = bag;
      this.marked = false;
      this.setBits = 0;
}
下面我们来看下Style类中该方法的部分代码:
public virtual void AddAttributesToRender(HtmlTextWriter writer, WebControl owner)
{
      Color color1;
      Unit unit1;
          //将ViewState属性传给bag1,其实也就时将构造函数中设置的statebag成员传给bag1
      StateBag bag1 = this.ViewState;
      if (this.IsSet(2))
      {
                    //得到定义的CssClass特性值
            string text1 = (string) bag1["CssClass"];
            if (text1.Length > 0)
            {
                    //为输出流添加Class样式特性和值
                  writer.AddAttribute(HtmlTextWriterAttribute.Class, text1); 
            }
      }
      if (this.IsSet(4))
      {
            color1 = (Color) bag1["ForeColor"];
            if (!color1.IsEmpty)
            {
                  writer.AddStyleAttribute(HtmlTextWriterStyle.Color, ColorTranslator.ToHtml(color1));
            }
      }
……
……
……
}
看了这些代码应该知道如何使用该方法和重写该方法了吧!该方法有2个参数,第一个参数是我们指定的要将样式特性输出到
HtmlTextWrite输出流,第2个参数是要使用样式的控件,一般为我们定义的控件或其子控件。
 
3.3.3     Style类的属性
 
    ViewState属性,该属性是只读的,只能被继承访问。如何设置该属性的呢?我们可以调用该类的构造函数指定私有成
statebag的对象来设置该属性,当我们读取该属性时读取的就是私有成员statebag。该属性在我们调用或重写
AddAttributesToRender方法时要用到,在自定义的样式类属性里也要用到。看下该属性的代码:
protected internal StateBag ViewState
{
      get
      {
            if (this.statebag == null)
            {
                    //当statebag为空时时将为statebag成员创建新对象
                  this.statebag = new StateBag(false);
                  if (this.IsTrackingViewState)
                  {
                        this.statebag.TrackViewState();
                  }
            }
            return this.statebag;
      }
}
由于该属性的访问权限为protected internal,所以在使用时如何使用大家要注意。
     IsEmpty属性,该属性在我们自定义样式类中比较重要,因为该属性访问权限为protected internal所以我们
能在派生类中使用该属性,该属性是虚属性所以我们可以重写该属性,用于判断样式类是否有定义样式,该属性在
WebControl类的ApplyStyle和MergeStyle方法中被用到。具体看下面的例子。
     Style类中的其他属性还有BackColor,BorderStyle等分别与WebControl类中的样式属性对应。当然我们可以
为自定义的样式类创建更多的样式属性对应于HTML标记符中的样式特性。
 
3.3.4       自定义样式类及其使用实例
 
     本节我们将创建一个表格控件,为HTML表格添加cellpadding,cellspacing,border和background样式特性。
下面我们就来看看示例(例3-6)
例3-6:

using System;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.ComponentModel;

namespace style_table_3_6

{

//这里我们首先定义一个继承自Style的样式类

     public class AspTableStyle:Style

     {

         private bool isempty; //该变量用于判断自定义样式是否被设置

         public AspTableStyle()

         {

              isempty=true; //设置样式没被定义

         }

         public AspTableStyle(StateBag bag) : base(bag) //构造函数调用基类的构造函数

         {

              isempty=true;

         }

         public virtual int CellPadding //该属性指定表格的单元格边距

         {

              get

              {

                   if (base.ViewState["CellPadding"]!=null)

                   {

                       return (int) base.ViewState["CellPadding"];

                   }

                   return 0;

              }

              set

              {

                   if (value < -1) //当值不在范围内将抛出异常

                   {

                       throw new ArgumentOutOfRangeException("value");

                   }

                   base.ViewState["CellPadding"] = value;

                   isempty=false; //设置样式已被定义

              }

         }

         public virtual int CellSpacing   //该属性指定表格的单元格间距

         {

              get

              {

                   if (base.ViewState["CellSpacing"]!=null)

                   {

                       return (int) base.ViewState["CellSpacing"];

                   }

                   return 0;

              }

              set

              {

                   if (value < -1)

                   {

                       throw new ArgumentOutOfRangeException("value");

                   }

                   base.ViewState["CellSpacing"] = value;

                   isempty=false;

              }

         }

         public virtual int Border //该属性指定表格的边框粗细

         {

              get

              {

                   if (base.ViewState["Border"]!=null)

                   {

                       return (int) base.ViewState["Border"];

                   }

                   return 0;

              }

              set

              {

                   if (value < -1)

                   {

                       throw new ArgumentOutOfRangeException("value");

                   }

                   base.ViewState["Border"] = value;

                   isempty=false;

              }

         }

         public virtual string BackGround //指定表格的背景图片地址

         {

              get

              {

                   if (base.ViewState["BackGround"]!=null)

                   {

                       return (string) base.ViewState["BackGround"];

                   }

                   return string.Empty;

              }

              set

              {

                   if (value == null)

                   {

                       throw new ArgumentNullException("value");

                   }

                   base.ViewState["BackGround"] = value;

                   isempty=false;

              }

         }

         protected override bool IsEmpty //该属性用于判断样式属性是否被设置

         {

              get

              {

                   if(isempty==false)

                   {

                       return false;

                   }

//当我们自定义的样式没被设置时返回基类的属性,判断基类中是否有属性被设置

                   return base.IsEmpty; 

              }

         }

         public override void AddAttributesToRender(HtmlTextWriter writer, WebControl owner)

         {

              base.AddAttributesToRender (writer, owner);

              string text1 = this.BackGround;

              if (text1.Length != 0)

              {

                   writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, "url(" + text1 + ")"); //指定背景图片

              }

              int num1 = this.CellSpacing;

              if (num1 >= 0)

              {

                  writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, num1.ToString());

                   if (num1 == 0)

                   {

                       writer.AddStyleAttribute(HtmlTextWriterStyle.BorderCollapse, "collapse");

                   }

              }

              num1 = this.CellPadding;

              if (num1 >= 0)

              {

                   writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, num1.ToString());

              }

              num1 = this.Border;

              if (num1 >= 0)

              {

                   writer.AddAttribute(HtmlTextWriterAttribute.Border, num1.ToString());

              }

         }

         public override void CopyFrom(Style s) //这里重写了基类的方法

          {

              if ((s != null))

              {

                   base.CopyFrom(s);

                   if (s is AspTableStyle)

                   {

                       AspTableStyle style1 = (AspTableStyle) s;

                       if (style1.BackGround!=null)

                       {

                            this.BackGround = style1.BackGround;

                       }

                       this.CellPadding = style1.CellPadding;

                       this.CellSpacing = style1.CellSpacing;

                       this.Border=style1.Border;

                   }

              }

         }

         public override void MergeWith(Style s)

         {

              if ((s != null))

              {

                   if (this.IsEmpty)

                   {

                       this.CopyFrom(s);

                   }

                   else

                   {

                       base.MergeWith(s);

                       if (s is AspTableStyle)

                       {

                            AspTableStyle style1 = (AspTableStyle) s;

                            if (style1.BackGround==null)

                            {

                                 this.BackGround = style1.BackGround;

                            }

                            if (style1.CellPadding==0)

                            {

                                 this.CellPadding = style1.CellPadding;

                            }

                            if (style1.CellSpacing==0)

                            {

                                 this.CellSpacing = style1.CellSpacing;

                            }

                            if (style1.Border==0)

                            {

                                 this.Border= style1.Border;

                            }

                       }

                   }

              }

         }

         public override void Reset()

         {

              if (this.BackGround!=null)

              {

                   base.ViewState.Remove("BackImageUrl");

              }

              if (this.CellPadding!=0)

              {

                   base.ViewState.Remove("CellPadding");

              }

              if (this.CellSpacing!=0)

              {

                   base.ViewState.Remove("CellSpacing");

              }

              base.Reset();

         }

     }

     [DefaultProperty("Text"),

         ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")]

     public class WebCustomControl1 : System.Web.UI.WebControls.WebControl

     {

         public WebCustomControl1():base(HtmlTextWriterTag.Table)

         {

         }

         public virtual int CellPadding //设置控件本身的样式属性

         {

              get

              {

                   if (!base.ControlStyleCreated)

                   {

                       return -1;

                   }

                   return ((AspTableStyle) base.ControlStyle).CellPadding;

              }

              set

              {

                   ((AspTableStyle) base.ControlStyle).CellPadding = value;

              }

         }

         public virtual int CellSpacing

         {

              get

              {

                   if (!base.ControlStyleCreated)

                   {

                       return -1;

                   }

                   return ((AspTableStyle) base.ControlStyle).CellSpacing;

              }

              set

              {

                   ((AspTableStyle) base.ControlStyle).CellSpacing = value;

              }

         }

         public virtual int Border

         {

              get

              {

                   if (!base.ControlStyleCreated)

                   {

                       return -1;

                   }

                   return ((AspTableStyle) base.ControlStyle).Border;

              }

              set

              {

                   ((AspTableStyle) base.ControlStyle).Border= value;

              }

         }

         public virtual string BackGround

         {

              get

              {

                   if (!base.ControlStyleCreated)

                   {

                       return string.Empty;

                   }

                   return ((AspTableStyle) base.ControlStyle).BackGround;

              }

              set

              {

                   ((AspTableStyle) base.ControlStyle).BackGround = value;

              }

         }

         protected override Style CreateControlStyle() //重写基类方法创建自定义样式的实例

         {

              return new AspTableStyle(this.ViewState); //返回自定义样式的实例

         }

         protected override void RenderContents(HtmlTextWriter writer)

         {

              int num1=this.Controls.Count; //得到控件的子控件数

              int num2=0;

              int num3=0;

              if(num1%4!=0)

              {

                   num2=(num1/4)+1;

              }

              else

              {

                   num2=num1/4;

              }

              if(num1!=0)

              {

                   for(int num5=1;num5<=num2;num5++)

                   {

                       writer.RenderBeginTag(HtmlTextWriterTag.Tr);

                       for(int num6=1;num6<=4;num6++)

                       {

                            writer.RenderBeginTag(HtmlTextWriterTag.Td);

                            if(num3<num1)

                            {

                                 this.Controls[num3].RenderControl(writer); //显示单个子控件

                            }

                            else

                            {

                                 writer.Write("null");

                            }

                            num3++;

                            writer.RenderEndTag();

                       }

                       writer.RenderEndTag();

                   }

              }

              else

              {

                   writer.RenderBeginTag(HtmlTextWriterTag.Tr);

                   writer.RenderBeginTag(HtmlTextWriterTag.Td);

                   writer.Write("没有任何子控件");

                   writer.RenderEndTag();

                   writer.RenderEndTag();

              }

         }

     }

}
     代码确实比较长,但用到了我们前面提到的很多知识,请大家务必认真看下,当然如果你了解该方面的知识是不
用看了,因为这比较的基础。如果大家想运行下该控件可以下载该控件的源代码。
下面我们来看看如何使用该控件,我们先将该控件加入自己的页面然后可以修改后置代码(.cs文件)的
InitializeComponent方法如下:

         private void InitializeComponent()

         {   

              Button bt1=new Button();  //新建一个Button控件

              bt1.Text="Button1";

              Button bt2=new Button();

              bt2.Text="Button2";

              Button bt3=new Button();

              bt3.Text="Button3";

              Button bt4=new Button();

              bt4.Text="Button4";

              Button bt5=new Button();

              bt5.Text="Button5";

              Button bt6=new Button();

              bt6.Text="Button6";

              //定义一个自定义的样式对象

              style_table_3_6.AspTableStyle ats=new style_table_3_6.AspTableStyle();

              ats.CellPadding=9; //设置样式属性

              ats.CellSpacing=9;

              ats.BorderColor=Color.Blue;

              WebCustomControl11.ApplyStyle(ats); //用自定义样式覆盖控件样式

              WebCustomControl11.Border=3; //定义控件本身的样式属性

              WebCustomControl11.Controls.Add(bt1); //添加子控件

              WebCustomControl11.Controls.Add(bt2);

              WebCustomControl11.Controls.Add(bt3);

              WebCustomControl11.Controls.Add(bt4);

              WebCustomControl11.Controls.Add(bt5);

              WebCustomControl11.Controls.Add(bt6);

         }

为方便我将Button控件的创建都定义在该方法里了。

下面看看运行结果吧(图3-9)

3-9

在上面的例子中我们首先定义了一个样式类AspTableStyle,重写了几个基类的方法,这几个方法我们在上面已经介绍过了,具体的用法大家还要从代码中认真揣摩下。我们也重写了IsEmpty属性,我个人认为重写IsEmpty属性是判断自定义的样式属性是否被设置最简单的做法。

    在上面这个例子的最后我们还使用RenderControl方法来显示子控件,关于该方法我们在上面没有提到,其实该方法是在Control类中定义的,RenderChildren方法中用到了该方法来显示控件的每一个子控件,关于该方法的用法就如上面的例子所示。

    关于样式类的使用及如何创建自定义样式类我们就讲到这里为止了,下面我们会对控件开发相关的接口进行下介绍。