asp.net控件开发基础(6)

    技术2022-05-11  61

    位于WebControls命名空间的style类为顶级样式类.大部分标准控件都拥有其样式属性. 1.下面为设置样式方法 (1)你可以直接设置控件样式 Button1.BackColor  =  System.Drawing.Color.Red; (2)通过获取web控件的样式集合来设置 Button1.ControlStyle.BackColor  =  System.Drawing.Color.Red; (3)通过设置样式类,利用WebControl类的ApplyStyle方法来复制非空样式,并改写现有样式         myStyle.BackColor  =  System.Drawing.Color.Red;        Button1.ApplyStyle(myStyle); (4)一直定义样式表属性,不使用控件属性,与定义HTML样式相同.  style = " background-color: red " 下面引出话题,为什么要使用样式?大家知道定义样式可以使用统一风格,定义好的样式,可以重复使用.再回来看上面设置样式方法. 2.了解WebControl.BackColor和Style.BackColor (1)和(2)是差不多的.但(3)则不同,(3)的定义方法有通用性,你可以定义一种样式,然后利用控件的ApplyStyle方法来引用样式.给样式编程提供了方面 WebControl类定义了通用的样式.(1)和(2)使用的样式属性为 WebControl.BackColor (3)则不同,使用的为 Style.BackColor 3.自定义样式属性刚开始就讲了 style类为通用的顶级样式类,但需求是会发生变化的. 好了,下面真正开始编码了. 下面以改写label控件为例子 (1)改写样式属性,让其默认背景为红色,相信大家一定看的懂 示例一 namespace  CustomComponents {    [ToolboxData(@"<{0}:ImageLabel1     BackColor='Red'    runat='server'></{0}:ImageLabel1>")    ]    public class ImageLabel1 : Label    {        public override string Text        {            get return ViewState["Text"!= null ? (string)ViewState["Text"] : base.ID; }            set { ViewState["Text"= value; }        }        public override System.Drawing.Color BackColor        {            get            {                return base.BackColor = System.Drawing.Color.Red;            }            set            {                base.BackColor = value;            }        }    }} 控件初始效果为下图 (2)为label新增一个背景图片的属性,重写了一下AddAttributesToRender方法,添加一个样式属性,AddAttributesToRender方法以前为大家讲过,这里不多讲了. 示例二 namespace  CustomComponents {    public class ImageLabel2 : Label    {        [BrowsableAttribute(true)]        [DescriptionAttribute("背景")]        [CategoryAttribute("Appearance")]        public virtual String ImageUrl        {            get return ViewState["imageUrl"!= null ? (string)ViewState["imageUrl"] : ""; }            set { ViewState["imageUrl"= value; }        }        override protected void AddAttributesToRender(HtmlTextWriter writer)        {            writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, ImageUrl);            base.AddAttributesToRender(writer);        }    }} 使用控件效果如下 (3)上面示例二中我们定义了背景样式,其实.net已经为我们把工作做好了 从style类派生了很多样式类,扩展了style类的属性,满足不同控件样式的需求. WebControl类中有一个CreateControlStyle 方法,其返回为一个样式集合.其默认情况下实现如下          protected   override  Style CreateControlStyle()         {            return new Style(ViewState);        } 我们可以通过改写此方法来使控件拥有style派生类的功能,改写后如下,让label控件拥有TableStyle类的样式          protected   override  Style CreateControlStyle()         {            return new TableStyle(ViewState);        } 注意点:默认情况下,当label控件使用ApplyStyle复制除style之外的样式属性集合,将只返回默认style类的样式属性集合.看了下面效果后请再回头再理解这句话.看下面自定义控件代码,真是简单的不的了示例三 namespace  CustomComponents {    public class ImageLabel3 : Label    {        protected override Style CreateControlStyle()        {            return new TableStyle(ViewState);        }    }} 再看默认label控件与其的对比,因为没有给控件定义样式属性,所以只能通过编程的方式来定义样式,如下示例四      protected   void  Page_Load( object  sender, EventArgs e)     {        //默认label控件        TableStyle a = new TableStyle();        a.BackImageUrl = "images4.bmp";        a.BackColor = System.Drawing.Color.Red;        Label1.ApplyStyle(a);        //自定义控件        ImageLabel3_1.ApplyStyle(a);    } 看一下,使用的效果,看到下面效果再来理解下我上面说的注意点吧.我想这样会理解的更深刻.(4)使用派生样式类,定义控件样式属性.示例四中说过了,没有定义控件样式属性,只改写了CreateControlStyle方法.那就意味了你定义的控件样式属性可以直接使用TableStyle类中的属性,但默认情况下的样式属性为style类中属性,所以需要强行转换.如下对比默认情况下          public   override  Color BackColor         {            get            {                return ((Style)ControlStyle).BackColor;            }            set            {                ((Style)ControlStyle).BackColor = value;            }        } 定义TableStyle样式属性,必须转换为TableStyle类型          public   virtual   string  BackImageUrl         {            get return ((TableStyle)ControlStyle).BackImageUrl; }            set { ((TableStyle)ControlStyle).BackImageUrl = value; }        } 好了,讲清楚上面这一点.我们再来测试一下.看下面示例(还是采用我们第一讲的例子) 下面只给出定义样式属性的代码,其他的类似. 使用此控件      < custom:CreditCardForm6  BackColor ="Black"  ForeColor ="White"  runat ="server"  ID ="example"       Font-Bold ="true"  Font-Italic ="true"  GridLines ="None"  CellSpacing ="5"        BackImageUrl ="images4.bmp"  Font-Size ="Larger"       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 LabelStyle() { }        public LabelStyle(StateBag viewState) : base(viewState) { }        public virtual String ImageUrl        {            get return ViewState["imageUrl"!= null ? (string)ViewState["imageUrl"] : ""; }            set { ViewState["imageUrl"= value; }        }        public override void AddAttributesToRender(HtmlTextWriter writer, WebControl owner)        {            writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, ImageUrl);                        base.AddAttributesToRender(writer, owner);        }    } 下面再来看控件实现方法,注意此处CreateControlStyle方法返回为自己定义的LabelStyle(ViewState) 示例6      public   class  ImageLabel4 : Label     {        protected override Style CreateControlStyle()        {            return new LabelStyle(ViewState);        }        [Bindable(true),        Category("Appearance"),        DefaultValue(""),        Description("背景图片")        ]         public virtual String ImageUrl        {            get return ((LabelStyle)ControlStyle).ImageUrl; }            set { ((LabelStyle)ControlStyle).ImageUrl = value; }        }    } 让我们来测试一下,你会发现界面上并未呈现背景图片,给控件加一个属性 CssClass=""以后效果就出来了,如下 让我们来思考为什么在未定义CssClass=""属性时无法呈现自定义属性. Style类有一个IsEmpty属性用来判断已在的视图状态中是否定义了样式属性,默认情况下为true,当定义了样式属性后,则为false.CssClass属性为空时,默认情况下即认为定义了样式属性,只不过样式属性个数为0.若要在默认情况下呈现自定义样式属性则需重写IsEmpty属性.如下,只要判断自定义的样式属性视图状态是否为空即可.示例7          // 判断视图状态是否为空          internal   bool  IsSet( string  key)         {            return ViewState[key] != null;        }          /// <summary>        /// 是否定义样式元素        /// </summary>          public   override   bool  IsEmpty         {            get            {                return base.IsEmpty && !IsSet("imageUrl");            }        } (2)使用编程下面我们以编程方式,给控件添加自定义样式属性.发现BackColor属性能够呈现但ImageUrl 无法呈现,那说明我们刚才自定义的类就失去意义了,也说明我们还未重写某个方法.    LabelStyle a  =   new  LabelStyle();        a.ImageUrl  =   " images4.bmp " ;        a.BackColor  =  System.Drawing.Color.Red;        ImageLabel4_1.ApplyStyle(a); Style类有三个操作样式的方法,复制,合并和清除样式.WebControl类也一样.重写一下,我们的目的就达到了.看下面代码示例8 好了,再次编译测试一下,效果也出来了.这里再写一点.再呈现的时候可以重写另一个方法来代替AddAttributesToRender方法,如下 protected   override   void  FillStyleAttributes(CssStyleCollection attributes, IUrlResolutionService urlResolver) {    base.FillStyleAttributes(attributes, urlResolver);    attributes.Add(HtmlTextWriterStyle.BackgroundImage, ImageUrl);} 关于对样式的理解基本的东西就先写这么多吧.大家看完了再回去看看,注意步骤就可以了.重在理解.好久没写了发现自己写的又挺长的,写的好累呀...希望对大家有帮助吧.示例代码下载 参考文章: <<asp.net服务器控件开发技术与示例>> 还有国外的两本书,一本是微软的,一本是appess的. 还有刚wrox新出的一本.名字就不多说了,想学的人,肯定找的到.  

    最新回复(0)