asp.net控件开发基础(6)
位于WebControls命名空间的style类为顶级样式类.大部分标准控件都拥有其样式属性。
1.下面为设置样式方法
(1)你可以直接设置控件样式
(2)通过获取web控件的样式集合来设置
(3)通过设置样式类,利用WebControl类的ApplyStyle方法来复制非空样式,并改写现有样式
Button1.ApplyStyle(myStyle);
(4)一直定义样式表属性,不使用控件属性,与定义HTML样式相同.
下面引出话题,为什么要使用样式?大家知道定义样式可以使用统一风格,定义好的样式,可以重复使用.再回来看上面设置样式方法.
2.了解WebControl.BackColor和Style.BackColor
(1)和(2)是差不多的.但(3)则不同,(3)的定义方法有通用性,你可以定义一种样式,然后利用控件的ApplyStyle方法来引用样式.给样式编程提供了方便。WebControl类定义了通用的样式.(1)和(2)使用的样式属性为
3.自定义样式属性
刚开始就讲了style类为通用的顶级样式类,但需求是会发生变化的. 好了,下面真正开始编码了。下面以改写label控件为例子
(1)改写样式属性,让其默认背景为红色,相信大家一定看的懂
示例一
{
[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方法以前为大家讲过,这里不多讲了.
示例二
{
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 方法,其返回为一个样式集合.其默认情况下实现如下:
{
return new Style(ViewState);
}
{
return new TableStyle(ViewState);
}
示例三
{
public class ImageLabel3 : Label
{
protected override Style CreateControlStyle()
{
return new TableStyle(ViewState);
}
}
}
示例四
{
//默认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类中属性,所以需要强行转换.如下对比。默认情况下
{
get
{
return ((Style)ControlStyle).BackColor;
}
set
{
((Style)ControlStyle).BackColor = value;
}
}
{
get { return ((TableStyle)ControlStyle).BackImageUrl; }
set { ((TableStyle)ControlStyle).BackImageUrl = value; }
}
#region 控件样式
protected override Style CreateControlStyle()
{
return new TableStyle(ViewState);
}
[BrowsableAttribute(true)]
[DescriptionAttribute("网格线")]
[CategoryAttribute("Appearance")]
public virtual GridLines GridLines
{
get { return ((TableStyle)ControlStyle).GridLines; }
set { ((TableStyle)ControlStyle).GridLines = value; }
}
[BrowsableAttribute(true)]
[DescriptionAttribute("单元格间距")]
[CategoryAttribute("Appearance")]
public virtual int CellSpacing
{
get { return ((TableStyle)ControlStyle).CellSpacing; }
set { ((TableStyle)ControlStyle).CellSpacing = value; }
}
[BrowsableAttribute(true)]
[DescriptionAttribute("单元格边距")]
[CategoryAttribute("Appearance")]
public virtual int CellPadding
{
get { return ((TableStyle)ControlStyle).CellPadding; }
set { ((TableStyle)ControlStyle).CellPadding = value; }
}
[BrowsableAttribute(true)]
[DescriptionAttribute("表水平对齐")]
[CategoryAttribute("Appearance")]
public virtual HorizontalAlign HorizontalAlign
{
get { return ((TableStyle)ControlStyle).HorizontalAlign; }
set { ((TableStyle)ControlStyle).HorizontalAlign = value; }
}
[BrowsableAttribute(true)]
[DescriptionAttribute("表背景图片")]
[CategoryAttribute("Appearance")]
public virtual string BackImageUrl
{
get { return ((TableStyle)ControlStyle).BackImageUrl; }
set { ((TableStyle)ControlStyle).BackImageUrl = value; }
}
#endregion
使用此控件
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 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
{
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");
}
}
下面我们以编程方式,给控件添加自定义样式属性。发现BackColor属性能够呈现但ImageUrl 无法呈现,那说明我们刚才自定义的类就失去意义了,也说明我们还未重写某个方法.
a.ImageUrl = "images4.bmp";
a.BackColor = System.Drawing.Color.Red;
ImageLabel4_1.ApplyStyle(a);
示例8
/// <summary>
/// 复制样式
/// </summary>
/// <param name=""></param>
public override void CopyFrom(Style s)
{
if (s == null)
return;
base.CopyFrom(s);
LabelStyle ls = s as LabelStyle;
if (ls == null || ls.IsEmpty)
return;
if (ls.IsSet("imageUrl"))
this.ImageUrl = ls.ImageUrl;
}
/// <summary>
/// 整合样式
/// </summary>
/// <param name="s"></param>
public override void MergeWith(Style s)
{
if (s == null)
return;
if (IsEmpty)
{
CopyFrom(s);
return;
}
LabelStyle ls = s as LabelStyle;
if (ls == null || ls.IsEmpty)
return;
if (ls.IsSet("imageUrl") && !IsSet("imageUrl"))
this.ImageUrl = ls.ImageUrl;
}
/// <summary>
/// 清除样式
/// </summary>
public override void Reset()
{
base.Reset();
if (IsEmpty)
return;
if (IsSet("imageUrl"))
ViewState.Remove("imageUrl");
}
#endregion
{
base.FillStyleAttributes(attributes, urlResolver);
attributes.Add(HtmlTextWriterStyle.BackgroundImage, ImageUrl);
}
下一篇:asp.net控件开发基础(7)