asp.net控件開發基礎(6)

作者: Clingingboy  來源: 博客園  發布時間: 2010-10-02 19:34  閱讀: 1244 次  推薦: 1   原文鏈接   [收藏]  

  位于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; }
        }
  好了,講清楚上面這一點.我們再來測試一下.看下面示例(還是采用我們第一講的例子),下面只給出定義樣式屬性的代碼,其他的類似。

 

 
#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

使用此控件

 

<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

 
#region 方法


/// <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
好了,再次編譯測試一下,效果也出來了。這里再寫一點.再呈現的時候可以重寫另一個方法來代替AddAttributesToRender方法,如下:
 
protected override void FillStyleAttributes(CssStyleCollection attributes, IUrlResolutionService urlResolver)
{

base.FillStyleAttributes(attributes, urlResolver);
attributes.Add(HtmlTextWriterStyle.BackgroundImage, ImageUrl);
}
  關于對樣式的理解基本的東西就先寫這么多吧.大家看完了再回去看看,注意步驟就可以了.重在理解。好久沒寫了發現自己寫的又挺長的,寫的好累呀...希望對大家有幫助吧。

 

上一篇:asp.net控件開發基礎(5)

下一篇:asp.net控件開發基礎(7)
1
0
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()