ASP.NET服务器控件的开发(3)

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方法中用到了该方法来显示控件的每一个子控件,关于该方法的用法就如上面的例子所示。
    关于样式类的使用及如何创建自定义样式类我们就讲到这里为止了,下面我们会对控件开发相关的接口进行下介绍。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值