位于WebControls命名空间的style类为顶级样式类.大部分标准控件都拥有其样式属性.
1.下面为设置样式方法
(1)你可以直接设置控件样式 Button1.BackColor = System.Drawing.Color.Red;
Button1.BackColor = System.Drawing.Color.Red;
(2)通过获取web控件的样式集合来设置
 Button1.ControlStyle.BackColor = System.Drawing.Color.Red;
Button1.ControlStyle.BackColor = System.Drawing.Color.Red;
(3)通过设置样式类,利用WebControl类的ApplyStyle方法来复制非空样式,并改写现有样式
 myStyle.BackColor = System.Drawing.Color.Red;
        myStyle.BackColor = System.Drawing.Color.Red;
 Button1.ApplyStyle(myStyle);
        Button1.ApplyStyle(myStyle);
(4)一直定义样式表属性,不使用控件属性,与定义HTML样式相同.
 style="background-color: red"
 style="background-color: red"
下面引出话题,为什么要使用样式?大家知道定义样式可以使用统一风格,定义好的样式,可以重复使用.再回来看上面设置样式方法.
2.了解WebControl.BackColor和Style.BackColor
(1)和(2)是差不多的.但(3)则不同,(3)的定义方法有通用性,你可以定义一种样式,然后利用控件的ApplyStyle方法来引用样式.给样式编程提供了方面
WebControl类定义了通用的样式.(1)和(2)使用的样式属性为
 WebControl.BackColor
WebControl.BackColor
(3)则不同,使用的为
 Style.BackColor
Style.BackColor
3.自定义样式属性
刚开始就讲了style类为通用的顶级样式类,但需求是会发生变化的. 好了,下面真正开始编码了.
下面以改写label控件为例子
(1)改写样式属性,让其默认背景为红色,相信大家一定看的懂
示例一
 namespace CustomComponents
namespace CustomComponents
 {
{
 [ToolboxData(@"<{0}:ImageLabel1
    [ToolboxData(@"<{0}:ImageLabel1 
 BackColor='Red'
    BackColor='Red'
 runat='server'></{0}:ImageLabel1>")
    runat='server'></{0}:ImageLabel1>")
 ]
    ]
 public class ImageLabel1 : Label
    public class ImageLabel1 : Label
 {
    {
 public override string Text
        public override string Text
 {
        {
 get { return ViewState["Text"] != null ? (string)ViewState["Text"] : base.ID; }
            get { return ViewState["Text"] != null ? (string)ViewState["Text"] : base.ID; }
 set { ViewState["Text"] = value; }
            set { ViewState["Text"] = value; }
 }
        }

 public override System.Drawing.Color BackColor
        public override System.Drawing.Color BackColor
 {
        {
 get
            get
 {
            {
 return base.BackColor = System.Drawing.Color.Red;
                return base.BackColor = System.Drawing.Color.Red;
 }
            }
 set
            set
 {
            {
 base.BackColor = value;
                base.BackColor = value;
 }
            }
 }
        }
 }
    }
 }
}
控件初始效果为下图

(2)为label新增一个背景图片的属性,重写了一下AddAttributesToRender方法,添加一个样式属性,AddAttributesToRender方法以前为大家讲过,这里不多讲了.
示例二
 namespace CustomComponents
namespace CustomComponents
 {
{
 public class ImageLabel2 : Label
    public class ImageLabel2 : Label
 {
    {
 [BrowsableAttribute(true)]
        [BrowsableAttribute(true)]
 [DescriptionAttribute("背景")]
        [DescriptionAttribute("背景")]
 [CategoryAttribute("Appearance")]
        [CategoryAttribute("Appearance")]
 public virtual String ImageUrl
        public virtual String ImageUrl
 {
        {
 get { return ViewState["imageUrl"] != null ? (string)ViewState["imageUrl"] : ""; }
            get { return ViewState["imageUrl"] != null ? (string)ViewState["imageUrl"] : ""; }
 set { ViewState["imageUrl"] = value; }
            set { ViewState["imageUrl"] = value; }
 }
        }
 override protected void AddAttributesToRender(HtmlTextWriter writer)
        override protected void AddAttributesToRender(HtmlTextWriter writer)
 {
        {
 writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, ImageUrl);
            writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, ImageUrl);
 base.AddAttributesToRender(writer);
            base.AddAttributesToRender(writer);
 }
        }
 }
    }
 }
}
使用控件效果如下

(3)上面示例二中我们定义了背景样式,其实.net已经为我们把工作做好了
从style类派生了很多样式类,扩展了style类的属性,满足不同控件样式的需求.
WebControl类中有一个CreateControlStyle 方法,其返回为一个样式集合.其默认情况下实现如下
 protected override Style CreateControlStyle()
        protected override Style CreateControlStyle()
 {
        {
 return new Style(ViewState);
            return new Style(ViewState);
 }
        }
我们可以通过改写此方法来使控件拥有style派生类的功能,改写后如下,让label控件拥有TableStyle类的样式
 protected override Style CreateControlStyle()
        protected override Style CreateControlStyle()
 {
        {
 return new TableStyle(ViewState);
            return new TableStyle(ViewState);
 }
        }
注意点:默认情况下,当label控件使用ApplyStyle复制除style之外的样式属性集合,将只返回默认style类的样式属性集合.
看了下面效果后请再回头再理解这句话.
看下面自定义控件代码,真是简单的不的了
示例三
 namespace CustomComponents
namespace CustomComponents
 {
{
 public class ImageLabel3 : Label
    public class ImageLabel3 : Label
 {
    {

 protected override Style CreateControlStyle()
        protected override Style CreateControlStyle()
 {
        {
 return new TableStyle(ViewState);
            return new TableStyle(ViewState);
 }
        }
 }
    }
 }
}
再看默认label控件与其的对比,因为没有给控件定义样式属性,所以只能通过编程的方式来定义样式,如下
示例四
 protected void Page_Load(object sender, EventArgs e)
    protected void Page_Load(object sender, EventArgs e)
 {
    {
 //默认label控件
        //默认label控件
 TableStyle a = new TableStyle();
        TableStyle a = new TableStyle();
 a.BackImageUrl = "images4.bmp";
        a.BackImageUrl = "images4.bmp";
 a.BackColor = System.Drawing.Color.Red;
        a.BackColor = System.Drawing.Color.Red;
 Label1.ApplyStyle(a);
        Label1.ApplyStyle(a);
 //自定义控件
        //自定义控件
 ImageLabel3_1.ApplyStyle(a);
        ImageLabel3_1.ApplyStyle(a);
 }
    }
看一下,使用的效果,看到下面效果再来理解下我上面说的注意点吧.我想这样会理解的更深刻.

(4)使用派生样式类,定义控件样式属性.示例四中说过了,没有定义控件样式属性,只改写了CreateControlStyle方法.那就意味了你定义的控件样式属性可以直接使用TableStyle类中的属性,但默认情况下的样式属性为style类中属性,所以需要强行转换.如下对比
默认情况下
 public override Color BackColor
        public override Color BackColor
 {
        {
 get
            get
 {
            {
 return ((Style)ControlStyle).BackColor;
                return ((Style)ControlStyle).BackColor;
 }
            }
 set
            set
 {
            {
 ((Style)ControlStyle).BackColor = value;
                ((Style)ControlStyle).BackColor = value;
 }
            }
 }
        }
定义TableStyle样式属性,必须转换为TableStyle类型
 public virtual string BackImageUrl
        public virtual string BackImageUrl
 {
        {
 get { return ((TableStyle)ControlStyle).BackImageUrl; }
            get { return ((TableStyle)ControlStyle).BackImageUrl; }
 set { ((TableStyle)ControlStyle).BackImageUrl = value; }
            set { ((TableStyle)ControlStyle).BackImageUrl = value; }
 }
        }
好了,讲清楚上面这一点.我们再来测试一下.看下面示例(还是采用我们第一讲的例子)
下面只给出定义样式属性的代码,其他的类似.

 #region 控件样式
       #region 控件样式

 protected override Style CreateControlStyle()
        protected override Style CreateControlStyle()
 {
        {

 return new TableStyle(ViewState);
            return new TableStyle(ViewState);
 }
        }

 [BrowsableAttribute(true)]
        [BrowsableAttribute(true)]
 [DescriptionAttribute("网格线")]
        [DescriptionAttribute("网格线")]
 [CategoryAttribute("Appearance")]
        [CategoryAttribute("Appearance")]
 public virtual GridLines GridLines
        public virtual GridLines GridLines
 {
        {
 get { return ((TableStyle)ControlStyle).GridLines; }
            get { return ((TableStyle)ControlStyle).GridLines; }
 set { ((TableStyle)ControlStyle).GridLines = value; }
            set { ((TableStyle)ControlStyle).GridLines = value; }
 }
        }

 [BrowsableAttribute(true)]
        [BrowsableAttribute(true)]
 [DescriptionAttribute("单元格间距")]
        [DescriptionAttribute("单元格间距")]
 [CategoryAttribute("Appearance")]
        [CategoryAttribute("Appearance")]
 public virtual int CellSpacing
        public virtual int CellSpacing
 {
        {
 get { return ((TableStyle)ControlStyle).CellSpacing; }
            get { return ((TableStyle)ControlStyle).CellSpacing; }
 set { ((TableStyle)ControlStyle).CellSpacing = value; }
            set { ((TableStyle)ControlStyle).CellSpacing = value; }
 }
        }

 [BrowsableAttribute(true)]
        [BrowsableAttribute(true)]
 [DescriptionAttribute("单元格边距")]
        [DescriptionAttribute("单元格边距")]
 [CategoryAttribute("Appearance")]
        [CategoryAttribute("Appearance")]
 public virtual int CellPadding
        public virtual int CellPadding
 {
        {
 get { return ((TableStyle)ControlStyle).CellPadding; }
            get { return ((TableStyle)ControlStyle).CellPadding; }
 set { ((TableStyle)ControlStyle).CellPadding = value; }
            set { ((TableStyle)ControlStyle).CellPadding = value; }
 }
        }

 [BrowsableAttribute(true)]
        [BrowsableAttribute(true)]
 [DescriptionAttribute("表水平对齐")]
        [DescriptionAttribute("表水平对齐")]
 [CategoryAttribute("Appearance")]
        [CategoryAttribute("Appearance")]
 public virtual HorizontalAlign HorizontalAlign
        public virtual HorizontalAlign HorizontalAlign
 {
        {
 get { return ((TableStyle)ControlStyle).HorizontalAlign; }
            get { return ((TableStyle)ControlStyle).HorizontalAlign; }
 set { ((TableStyle)ControlStyle).HorizontalAlign = value; }
            set { ((TableStyle)ControlStyle).HorizontalAlign = value; }
 }
        }

 [BrowsableAttribute(true)]
        [BrowsableAttribute(true)]
 [DescriptionAttribute("表背景图片")]
        [DescriptionAttribute("表背景图片")]
 [CategoryAttribute("Appearance")]
        [CategoryAttribute("Appearance")]
 public virtual string BackImageUrl
        public virtual string BackImageUrl
 {
        {
 get { return ((TableStyle)ControlStyle).BackImageUrl; }
            get { return ((TableStyle)ControlStyle).BackImageUrl; }
 set { ((TableStyle)ControlStyle).BackImageUrl = value; }
            set { ((TableStyle)ControlStyle).BackImageUrl = value; }
 }
        }

 #endregion
        #endregion
使用此控件
 <custom:CreditCardForm6 BackColor="Black" ForeColor="White" runat="server" ID="example"
    <custom:CreditCardForm6 BackColor="Black" ForeColor="White" runat="server" ID="example"
 Font-Bold="true" Font-Italic="true" GridLines="None" CellSpacing="5"
      Font-Bold="true" Font-Italic="true" GridLines="None" CellSpacing="5" 
 BackImageUrl="images4.bmp" Font-Size="Larger"
      BackImageUrl="images4.bmp" Font-Size="Larger"
 BorderColor="Yellow" BorderWidth="20px" BorderStyle="Ridge" HorizontalAlign="NotSet" EnableViewState="False" />
      BorderColor="Yellow" BorderWidth="20px" BorderStyle="Ridge" HorizontalAlign="NotSet" EnableViewState="False" />
效果如下

好了,上面的基础讲完了.希望大家能够有所理解.下面还我们要讲一个重点的东西.
4.自定义类型化样式属性
如果样式属性无法满足你需求,则你可以通过自定义类型化样式来实现.
什么是自定义类型化样式?就是该类从style类派生,对其进行修改和扩充(书上就这么写了...我就这么理解了-_-)
如Table控件,一方面控件自身定义的样式属性,另一方面又定义了TableStyle类.你可以在使用控件样式属性和TableStyle类中进行选择.
但TableStyle类具有通用性,具有一定的灵活性.好了下面我们又要开始看代码了.当然从简单开始
(1)简单呈现样式属性
需要说明的注意点如下
1.重写LabelStyle(StateBag viewState)构造函数
2.样式属性需用视图状态来声明
3.Style类的重载的AddAttributesToRender方法需用两个参数的方法
AddAttributesToRender(HtmlTextWriter writer, WebControl owner)
示例5 自定义类型化样式:LabelStyle类
 public class LabelStyle :Style
    public class LabelStyle :Style
 {
    {
 public LabelStyle() { }
        public LabelStyle() { }
 public LabelStyle(StateBag viewState) : base(viewState) { }
        public LabelStyle(StateBag viewState) : base(viewState) { }

 public virtual String ImageUrl
        public virtual String ImageUrl
 {
        {
 get { return ViewState["imageUrl"] != null ? (string)ViewState["imageUrl"] : ""; }
            get { return ViewState["imageUrl"] != null ? (string)ViewState["imageUrl"] : ""; }
 set { ViewState["imageUrl"] = value; }
            set { ViewState["imageUrl"] = value; }
 }
        }

 public override void AddAttributesToRender(HtmlTextWriter writer, WebControl owner)
        public override void AddAttributesToRender(HtmlTextWriter writer, WebControl owner)
 {
        {
 writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, ImageUrl);
            writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, ImageUrl);

 
            
 base.AddAttributesToRender(writer, owner);
            base.AddAttributesToRender(writer, owner);
 }
        }
 }
    }
下面再来看控件实现方法,注意此处CreateControlStyle方法返回为自己定义的LabelStyle(ViewState)
示例6
 public class ImageLabel4 : Label
    public class ImageLabel4 : Label
 {
    {
 protected override Style CreateControlStyle()
        protected override Style CreateControlStyle()
 {
        {
 return new LabelStyle(ViewState);
            return new LabelStyle(ViewState);
 }
        }

 [Bindable(true),
        [Bindable(true),
 Category("Appearance"),
        Category("Appearance"),
 DefaultValue(""),
        DefaultValue(""),
 Description("背景图片")
        Description("背景图片")
 ]
        ] 
 public virtual String ImageUrl
        public virtual String ImageUrl
 {
        {
 get { return ((LabelStyle)ControlStyle).ImageUrl; }
            get { return ((LabelStyle)ControlStyle).ImageUrl; }
 set { ((LabelStyle)ControlStyle).ImageUrl = value; }
            set { ((LabelStyle)ControlStyle).ImageUrl = value; }
 }
        }
 }
    }
让我们来测试一下,你会发现界面上并未呈现背景图片,给控件加一个属性CssClass=""以后效果就出来了,如下

让我们来思考为什么在未定义CssClass=""属性时无法呈现自定义属性.
Style类有一个IsEmpty属性用来判断已在的视图状态中是否定义了样式属性,
默认情况下为true,当定义了样式属性后,则为false.CssClass属性为空时,默认情况下即认为定义了样式属性,只不过样式属性个数为0.
若要在默认情况下呈现自定义样式属性则需重写IsEmpty属性.如下,只要判断自定义的样式属性视图状态是否为空即可.
示例7
 //判断视图状态是否为空
        //判断视图状态是否为空
 internal bool IsSet(string key)
        internal bool IsSet(string key)
 {
        {
 return ViewState[key] != null;
            return ViewState[key] != null;
 }
        }

 /// <summary>
        /// <summary>
 /// 是否定义样式元素
        /// 是否定义样式元素
 /// </summary>
        /// </summary>
 public override bool IsEmpty
        public override bool IsEmpty
 {
        {
 get
            get
 {
            {
 return base.IsEmpty && !IsSet("imageUrl");
                return base.IsEmpty && !IsSet("imageUrl");
 }
            }
 }
        }
(2)使用编程
下面我们以编程方式,给控件添加自定义样式属性.
发现BackColor属性能够呈现但ImageUrl 无法呈现,那说明我们刚才自定义的类就失去意义了,也说明我们还未重写某个方法.
 LabelStyle a = new LabelStyle();
   LabelStyle a = new LabelStyle();
 a.ImageUrl = "images4.bmp";
        a.ImageUrl = "images4.bmp";
 a.BackColor = System.Drawing.Color.Red;
        a.BackColor = System.Drawing.Color.Red;
 ImageLabel4_1.ApplyStyle(a);
        ImageLabel4_1.ApplyStyle(a);
Style类有三个操作样式的方法,复制,合并和清除样式.WebControl类也一样.重写一下,我们的目的就达到了.看下面代码
示例8

 #region 方法
#region 方法


 /// <summary>
        /// <summary>
 ///  复制样式
        ///  复制样式
 /// </summary>
        /// </summary>
 /// <param name=""></param>
        /// <param name=""></param>
 public override void CopyFrom(Style s)
        public override void CopyFrom(Style s)
 {
        {
 if (s == null)
            if (s == null)
 return;
                return;

 base.CopyFrom(s);
            base.CopyFrom(s);
 LabelStyle ls = s as LabelStyle;
            LabelStyle ls = s as LabelStyle;
 if (ls == null || ls.IsEmpty)
            if (ls == null || ls.IsEmpty)
 return;
                return;

 if (ls.IsSet("imageUrl"))
            if (ls.IsSet("imageUrl"))
 this.ImageUrl = ls.ImageUrl;
                this.ImageUrl = ls.ImageUrl;
 }
        }

 /// <summary>
        /// <summary>
 /// 整合样式
        /// 整合样式
 /// </summary>
        /// </summary>
 /// <param name="s"></param>
        /// <param name="s"></param>
 public override void MergeWith(Style s)
        public override void MergeWith(Style s)
 {
        {
 if (s == null)
            if (s == null)
 return;
                return;

 if (IsEmpty)
            if (IsEmpty)
 {
            {
 CopyFrom(s);
                CopyFrom(s);
 return;
                return;
 }
            }

 LabelStyle ls = s as LabelStyle;
            LabelStyle ls = s as LabelStyle;
 if (ls == null || ls.IsEmpty)
            if (ls == null || ls.IsEmpty)
 return;
                return;

 if (ls.IsSet("imageUrl") && !IsSet("imageUrl"))
            if (ls.IsSet("imageUrl") && !IsSet("imageUrl"))
 this.ImageUrl = ls.ImageUrl;
                this.ImageUrl = ls.ImageUrl;
 }
        }

 /// <summary>
        /// <summary>
 /// 清除样式
        /// 清除样式
 /// </summary>
        /// </summary>
 public override void Reset()
        public override void Reset()
 {
        {
 base.Reset();
            base.Reset();
 if (IsEmpty)
            if (IsEmpty)
 return;
                return;

 if (IsSet("imageUrl"))
            if (IsSet("imageUrl"))
 ViewState.Remove("imageUrl");
                ViewState.Remove("imageUrl");
 }
        }
 #endregion
        #endregion
好了,再次编译测试一下,效果也出来了.
这里再写一点.再呈现的时候可以重写另一个方法来代替AddAttributesToRender方法,如下
 protected override void FillStyleAttributes(CssStyleCollection attributes, IUrlResolutionService urlResolver)
protected override void FillStyleAttributes(CssStyleCollection attributes, IUrlResolutionService urlResolver)
 {
{
 base.FillStyleAttributes(attributes, urlResolver);
    base.FillStyleAttributes(attributes, urlResolver);
 attributes.Add(HtmlTextWriterStyle.BackgroundImage, ImageUrl);
    attributes.Add(HtmlTextWriterStyle.BackgroundImage, ImageUrl);
 }
}
关于对样式的理解基本的东西就先写这么多吧.大家看完了再回去看看,注意步骤就可以了.重在理解.
1.下面为设置样式方法
(1)你可以直接设置控件样式
 Button1.BackColor = System.Drawing.Color.Red;
Button1.BackColor = System.Drawing.Color.Red;(2)通过获取web控件的样式集合来设置
 Button1.ControlStyle.BackColor = System.Drawing.Color.Red;
Button1.ControlStyle.BackColor = System.Drawing.Color.Red;(3)通过设置样式类,利用WebControl类的ApplyStyle方法来复制非空样式,并改写现有样式
 myStyle.BackColor = System.Drawing.Color.Red;
        myStyle.BackColor = System.Drawing.Color.Red; Button1.ApplyStyle(myStyle);
        Button1.ApplyStyle(myStyle);(4)一直定义样式表属性,不使用控件属性,与定义HTML样式相同.
 style="background-color: red"
 style="background-color: red"下面引出话题,为什么要使用样式?大家知道定义样式可以使用统一风格,定义好的样式,可以重复使用.再回来看上面设置样式方法.
2.了解WebControl.BackColor和Style.BackColor
(1)和(2)是差不多的.但(3)则不同,(3)的定义方法有通用性,你可以定义一种样式,然后利用控件的ApplyStyle方法来引用样式.给样式编程提供了方面
WebControl类定义了通用的样式.(1)和(2)使用的样式属性为
 WebControl.BackColor
WebControl.BackColor(3)则不同,使用的为
 Style.BackColor
Style.BackColor3.自定义样式属性
刚开始就讲了style类为通用的顶级样式类,但需求是会发生变化的. 好了,下面真正开始编码了.
下面以改写label控件为例子
(1)改写样式属性,让其默认背景为红色,相信大家一定看的懂
示例一
 namespace CustomComponents
namespace CustomComponents {
{ [ToolboxData(@"<{0}:ImageLabel1
    [ToolboxData(@"<{0}:ImageLabel1  BackColor='Red'
    BackColor='Red' runat='server'></{0}:ImageLabel1>")
    runat='server'></{0}:ImageLabel1>") ]
    ] public class ImageLabel1 : Label
    public class ImageLabel1 : Label {
    { public override string Text
        public override string Text {
        { get { return ViewState["Text"] != null ? (string)ViewState["Text"] : base.ID; }
            get { return ViewState["Text"] != null ? (string)ViewState["Text"] : base.ID; } set { ViewState["Text"] = value; }
            set { ViewState["Text"] = value; } }
        }
 public override System.Drawing.Color BackColor
        public override System.Drawing.Color BackColor {
        { get
            get {
            { return base.BackColor = System.Drawing.Color.Red;
                return base.BackColor = System.Drawing.Color.Red; }
            } set
            set {
            { base.BackColor = value;
                base.BackColor = value; }
            } }
        } }
    } }
}控件初始效果为下图

(2)为label新增一个背景图片的属性,重写了一下AddAttributesToRender方法,添加一个样式属性,AddAttributesToRender方法以前为大家讲过,这里不多讲了.
示例二
 namespace CustomComponents
namespace CustomComponents {
{ public class ImageLabel2 : Label
    public class ImageLabel2 : Label {
    { [BrowsableAttribute(true)]
        [BrowsableAttribute(true)] [DescriptionAttribute("背景")]
        [DescriptionAttribute("背景")] [CategoryAttribute("Appearance")]
        [CategoryAttribute("Appearance")] public virtual String ImageUrl
        public virtual String ImageUrl {
        { get { return ViewState["imageUrl"] != null ? (string)ViewState["imageUrl"] : ""; }
            get { return ViewState["imageUrl"] != null ? (string)ViewState["imageUrl"] : ""; } set { ViewState["imageUrl"] = value; }
            set { ViewState["imageUrl"] = value; } }
        } override protected void AddAttributesToRender(HtmlTextWriter writer)
        override protected void AddAttributesToRender(HtmlTextWriter writer) {
        { writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, ImageUrl);
            writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, ImageUrl); base.AddAttributesToRender(writer);
            base.AddAttributesToRender(writer); }
        } }
    } }
}使用控件效果如下

(3)上面示例二中我们定义了背景样式,其实.net已经为我们把工作做好了
从style类派生了很多样式类,扩展了style类的属性,满足不同控件样式的需求.
WebControl类中有一个CreateControlStyle 方法,其返回为一个样式集合.其默认情况下实现如下
 protected override Style CreateControlStyle()
        protected override Style CreateControlStyle() {
        { return new Style(ViewState);
            return new Style(ViewState); }
        }我们可以通过改写此方法来使控件拥有style派生类的功能,改写后如下,让label控件拥有TableStyle类的样式
 protected override Style CreateControlStyle()
        protected override Style CreateControlStyle() {
        { return new TableStyle(ViewState);
            return new TableStyle(ViewState); }
        }注意点:默认情况下,当label控件使用ApplyStyle复制除style之外的样式属性集合,将只返回默认style类的样式属性集合.
看了下面效果后请再回头再理解这句话.
看下面自定义控件代码,真是简单的不的了
示例三
 namespace CustomComponents
namespace CustomComponents {
{ public class ImageLabel3 : Label
    public class ImageLabel3 : Label {
    {
 protected override Style CreateControlStyle()
        protected override Style CreateControlStyle() {
        { return new TableStyle(ViewState);
            return new TableStyle(ViewState); }
        } }
    } }
}再看默认label控件与其的对比,因为没有给控件定义样式属性,所以只能通过编程的方式来定义样式,如下
示例四
 protected void Page_Load(object sender, EventArgs e)
    protected void Page_Load(object sender, EventArgs e) {
    { //默认label控件
        //默认label控件 TableStyle a = new TableStyle();
        TableStyle a = new TableStyle(); a.BackImageUrl = "images4.bmp";
        a.BackImageUrl = "images4.bmp"; a.BackColor = System.Drawing.Color.Red;
        a.BackColor = System.Drawing.Color.Red; Label1.ApplyStyle(a);
        Label1.ApplyStyle(a); //自定义控件
        //自定义控件 ImageLabel3_1.ApplyStyle(a);
        ImageLabel3_1.ApplyStyle(a); }
    }看一下,使用的效果,看到下面效果再来理解下我上面说的注意点吧.我想这样会理解的更深刻.

(4)使用派生样式类,定义控件样式属性.示例四中说过了,没有定义控件样式属性,只改写了CreateControlStyle方法.那就意味了你定义的控件样式属性可以直接使用TableStyle类中的属性,但默认情况下的样式属性为style类中属性,所以需要强行转换.如下对比
默认情况下
 public override Color BackColor
        public override Color BackColor {
        { get
            get {
            { return ((Style)ControlStyle).BackColor;
                return ((Style)ControlStyle).BackColor; }
            } set
            set {
            { ((Style)ControlStyle).BackColor = value;
                ((Style)ControlStyle).BackColor = value; }
            } }
        }定义TableStyle样式属性,必须转换为TableStyle类型
 public virtual string BackImageUrl
        public virtual string BackImageUrl {
        { get { return ((TableStyle)ControlStyle).BackImageUrl; }
            get { return ((TableStyle)ControlStyle).BackImageUrl; } set { ((TableStyle)ControlStyle).BackImageUrl = value; }
            set { ((TableStyle)ControlStyle).BackImageUrl = value; } }
        }好了,讲清楚上面这一点.我们再来测试一下.看下面示例(还是采用我们第一讲的例子)
下面只给出定义样式属性的代码,其他的类似.

 #region 控件样式
       #region 控件样式
 protected override Style CreateControlStyle()
        protected override Style CreateControlStyle() {
        {
 return new TableStyle(ViewState);
            return new TableStyle(ViewState); }
        }
 [BrowsableAttribute(true)]
        [BrowsableAttribute(true)] [DescriptionAttribute("网格线")]
        [DescriptionAttribute("网格线")] [CategoryAttribute("Appearance")]
        [CategoryAttribute("Appearance")] public virtual GridLines GridLines
        public virtual GridLines GridLines {
        { get { return ((TableStyle)ControlStyle).GridLines; }
            get { return ((TableStyle)ControlStyle).GridLines; } set { ((TableStyle)ControlStyle).GridLines = value; }
            set { ((TableStyle)ControlStyle).GridLines = value; } }
        }
 [BrowsableAttribute(true)]
        [BrowsableAttribute(true)] [DescriptionAttribute("单元格间距")]
        [DescriptionAttribute("单元格间距")] [CategoryAttribute("Appearance")]
        [CategoryAttribute("Appearance")] public virtual int CellSpacing
        public virtual int CellSpacing {
        { get { return ((TableStyle)ControlStyle).CellSpacing; }
            get { return ((TableStyle)ControlStyle).CellSpacing; } set { ((TableStyle)ControlStyle).CellSpacing = value; }
            set { ((TableStyle)ControlStyle).CellSpacing = value; } }
        }
 [BrowsableAttribute(true)]
        [BrowsableAttribute(true)] [DescriptionAttribute("单元格边距")]
        [DescriptionAttribute("单元格边距")] [CategoryAttribute("Appearance")]
        [CategoryAttribute("Appearance")] public virtual int CellPadding
        public virtual int CellPadding {
        { get { return ((TableStyle)ControlStyle).CellPadding; }
            get { return ((TableStyle)ControlStyle).CellPadding; } set { ((TableStyle)ControlStyle).CellPadding = value; }
            set { ((TableStyle)ControlStyle).CellPadding = value; } }
        }
 [BrowsableAttribute(true)]
        [BrowsableAttribute(true)] [DescriptionAttribute("表水平对齐")]
        [DescriptionAttribute("表水平对齐")] [CategoryAttribute("Appearance")]
        [CategoryAttribute("Appearance")] public virtual HorizontalAlign HorizontalAlign
        public virtual HorizontalAlign HorizontalAlign {
        { get { return ((TableStyle)ControlStyle).HorizontalAlign; }
            get { return ((TableStyle)ControlStyle).HorizontalAlign; } set { ((TableStyle)ControlStyle).HorizontalAlign = value; }
            set { ((TableStyle)ControlStyle).HorizontalAlign = value; } }
        }
 [BrowsableAttribute(true)]
        [BrowsableAttribute(true)] [DescriptionAttribute("表背景图片")]
        [DescriptionAttribute("表背景图片")] [CategoryAttribute("Appearance")]
        [CategoryAttribute("Appearance")] public virtual string BackImageUrl
        public virtual string BackImageUrl {
        { get { return ((TableStyle)ControlStyle).BackImageUrl; }
            get { return ((TableStyle)ControlStyle).BackImageUrl; } set { ((TableStyle)ControlStyle).BackImageUrl = value; }
            set { ((TableStyle)ControlStyle).BackImageUrl = value; } }
        }
 #endregion
        #endregion使用此控件
 <custom:CreditCardForm6 BackColor="Black" ForeColor="White" runat="server" ID="example"
    <custom:CreditCardForm6 BackColor="Black" ForeColor="White" runat="server" ID="example" Font-Bold="true" Font-Italic="true" GridLines="None" CellSpacing="5"
      Font-Bold="true" Font-Italic="true" GridLines="None" CellSpacing="5"  BackImageUrl="images4.bmp" Font-Size="Larger"
      BackImageUrl="images4.bmp" Font-Size="Larger" BorderColor="Yellow" BorderWidth="20px" BorderStyle="Ridge" HorizontalAlign="NotSet" EnableViewState="False" />
      BorderColor="Yellow" BorderWidth="20px" BorderStyle="Ridge" HorizontalAlign="NotSet" EnableViewState="False" />效果如下

好了,上面的基础讲完了.希望大家能够有所理解.下面还我们要讲一个重点的东西.
4.自定义类型化样式属性
如果样式属性无法满足你需求,则你可以通过自定义类型化样式来实现.
什么是自定义类型化样式?就是该类从style类派生,对其进行修改和扩充(书上就这么写了...我就这么理解了-_-)
如Table控件,一方面控件自身定义的样式属性,另一方面又定义了TableStyle类.你可以在使用控件样式属性和TableStyle类中进行选择.
但TableStyle类具有通用性,具有一定的灵活性.好了下面我们又要开始看代码了.当然从简单开始
(1)简单呈现样式属性
需要说明的注意点如下
1.重写LabelStyle(StateBag viewState)构造函数
2.样式属性需用视图状态来声明
3.Style类的重载的AddAttributesToRender方法需用两个参数的方法
AddAttributesToRender(HtmlTextWriter writer, WebControl owner)
示例5 自定义类型化样式:LabelStyle类
 public class LabelStyle :Style
    public class LabelStyle :Style {
    { public LabelStyle() { }
        public LabelStyle() { } public LabelStyle(StateBag viewState) : base(viewState) { }
        public LabelStyle(StateBag viewState) : base(viewState) { }
 public virtual String ImageUrl
        public virtual String ImageUrl {
        { get { return ViewState["imageUrl"] != null ? (string)ViewState["imageUrl"] : ""; }
            get { return ViewState["imageUrl"] != null ? (string)ViewState["imageUrl"] : ""; } set { ViewState["imageUrl"] = value; }
            set { ViewState["imageUrl"] = value; } }
        }
 public override void AddAttributesToRender(HtmlTextWriter writer, WebControl owner)
        public override void AddAttributesToRender(HtmlTextWriter writer, WebControl owner) {
        { writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, ImageUrl);
            writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, ImageUrl);
 
             base.AddAttributesToRender(writer, owner);
            base.AddAttributesToRender(writer, owner); }
        } }
    }下面再来看控件实现方法,注意此处CreateControlStyle方法返回为自己定义的LabelStyle(ViewState)
示例6
 public class ImageLabel4 : Label
    public class ImageLabel4 : Label {
    { protected override Style CreateControlStyle()
        protected override Style CreateControlStyle() {
        { return new LabelStyle(ViewState);
            return new LabelStyle(ViewState); }
        }
 [Bindable(true),
        [Bindable(true), Category("Appearance"),
        Category("Appearance"), DefaultValue(""),
        DefaultValue(""), Description("背景图片")
        Description("背景图片") ]
        ]  public virtual String ImageUrl
        public virtual String ImageUrl {
        { get { return ((LabelStyle)ControlStyle).ImageUrl; }
            get { return ((LabelStyle)ControlStyle).ImageUrl; } set { ((LabelStyle)ControlStyle).ImageUrl = value; }
            set { ((LabelStyle)ControlStyle).ImageUrl = value; } }
        } }
    }让我们来测试一下,你会发现界面上并未呈现背景图片,给控件加一个属性CssClass=""以后效果就出来了,如下

让我们来思考为什么在未定义CssClass=""属性时无法呈现自定义属性.
Style类有一个IsEmpty属性用来判断已在的视图状态中是否定义了样式属性,
默认情况下为true,当定义了样式属性后,则为false.CssClass属性为空时,默认情况下即认为定义了样式属性,只不过样式属性个数为0.
若要在默认情况下呈现自定义样式属性则需重写IsEmpty属性.如下,只要判断自定义的样式属性视图状态是否为空即可.
示例7
 //判断视图状态是否为空
        //判断视图状态是否为空 internal bool IsSet(string key)
        internal bool IsSet(string key) {
        { return ViewState[key] != null;
            return ViewState[key] != null; }
        }
 /// <summary>
        /// <summary> /// 是否定义样式元素
        /// 是否定义样式元素 /// </summary>
        /// </summary> public override bool IsEmpty
        public override bool IsEmpty {
        { get
            get {
            { return base.IsEmpty && !IsSet("imageUrl");
                return base.IsEmpty && !IsSet("imageUrl"); }
            } }
        }(2)使用编程
下面我们以编程方式,给控件添加自定义样式属性.
发现BackColor属性能够呈现但ImageUrl 无法呈现,那说明我们刚才自定义的类就失去意义了,也说明我们还未重写某个方法.
 LabelStyle a = new LabelStyle();
   LabelStyle a = new LabelStyle(); a.ImageUrl = "images4.bmp";
        a.ImageUrl = "images4.bmp"; a.BackColor = System.Drawing.Color.Red;
        a.BackColor = System.Drawing.Color.Red; ImageLabel4_1.ApplyStyle(a);
        ImageLabel4_1.ApplyStyle(a);Style类有三个操作样式的方法,复制,合并和清除样式.WebControl类也一样.重写一下,我们的目的就达到了.看下面代码
示例8

 #region 方法
#region 方法

 /// <summary>
        /// <summary> ///  复制样式
        ///  复制样式 /// </summary>
        /// </summary> /// <param name=""></param>
        /// <param name=""></param> public override void CopyFrom(Style s)
        public override void CopyFrom(Style s) {
        { if (s == null)
            if (s == null) return;
                return;
 base.CopyFrom(s);
            base.CopyFrom(s); LabelStyle ls = s as LabelStyle;
            LabelStyle ls = s as LabelStyle; if (ls == null || ls.IsEmpty)
            if (ls == null || ls.IsEmpty) return;
                return;
 if (ls.IsSet("imageUrl"))
            if (ls.IsSet("imageUrl")) this.ImageUrl = ls.ImageUrl;
                this.ImageUrl = ls.ImageUrl; }
        }
 /// <summary>
        /// <summary> /// 整合样式
        /// 整合样式 /// </summary>
        /// </summary> /// <param name="s"></param>
        /// <param name="s"></param> public override void MergeWith(Style s)
        public override void MergeWith(Style s) {
        { if (s == null)
            if (s == null) return;
                return;
 if (IsEmpty)
            if (IsEmpty) {
            { CopyFrom(s);
                CopyFrom(s); return;
                return; }
            }
 LabelStyle ls = s as LabelStyle;
            LabelStyle ls = s as LabelStyle; if (ls == null || ls.IsEmpty)
            if (ls == null || ls.IsEmpty) return;
                return;
 if (ls.IsSet("imageUrl") && !IsSet("imageUrl"))
            if (ls.IsSet("imageUrl") && !IsSet("imageUrl")) this.ImageUrl = ls.ImageUrl;
                this.ImageUrl = ls.ImageUrl; }
        }
 /// <summary>
        /// <summary> /// 清除样式
        /// 清除样式 /// </summary>
        /// </summary> public override void Reset()
        public override void Reset() {
        { base.Reset();
            base.Reset(); if (IsEmpty)
            if (IsEmpty) return;
                return;
 if (IsSet("imageUrl"))
            if (IsSet("imageUrl")) ViewState.Remove("imageUrl");
                ViewState.Remove("imageUrl"); }
        } #endregion
        #endregion好了,再次编译测试一下,效果也出来了.
这里再写一点.再呈现的时候可以重写另一个方法来代替AddAttributesToRender方法,如下
 protected override void FillStyleAttributes(CssStyleCollection attributes, IUrlResolutionService urlResolver)
protected override void FillStyleAttributes(CssStyleCollection attributes, IUrlResolutionService urlResolver) {
{ base.FillStyleAttributes(attributes, urlResolver);
    base.FillStyleAttributes(attributes, urlResolver); attributes.Add(HtmlTextWriterStyle.BackgroundImage, ImageUrl);
    attributes.Add(HtmlTextWriterStyle.BackgroundImage, ImageUrl); }
}关于对样式的理解基本的东西就先写这么多吧.大家看完了再回去看看,注意步骤就可以了.重在理解.
 
                    
                 



 
     
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号