在portal項目第一迭代中,我主要負責控制項陳列庫這一塊的工作。所謂知識需要分享,閱讀豐富人生。我希望和大家分享一下控制項經驗並相互探討以求共同進步,一起成長。
以下是所需控制項和其功能描述:
名稱 |
說明 |
備忘 |
ScollGridView |
帶滾動的GridVIew,與asp.net GridView有別,Asp.net GridView在資料過多時採用的是分頁,而ScollGridView在資料過多時採用垂直捲軸解決 |
運用於各種統計頁面 |
PlanItem |
具體表現為圖片的寬度為進度的百分比。 |
運用於進度的表示 |
StatusItem |
利用不同的圖片與文字表現不同的狀態 |
|
BiasItem |
將偏差的正負值轉換為落後與超前及相應的色彩 |
用於表示偏差方向 |
今天先講一下PlanItem控制項吧
首先,我們先回憶一下VS2010中內建的.NET控制項都有些什麼特徵,如屬性、事件等等,並且都可以自己設定相關屬性和編寫事件實現的相關代碼...是吧,而現在我們要寫控制項也要讓它擁有這些特徵,暴露出其相關的屬性和事件,我們會用到物件導向編程裡的繼承,繼承屬性、事件、方法...在我看來,好的控制項應該滿足活字印刷中的一些特徵,如靈活性、可擴充性、可複用性...另外最重要的一點,也是我們不得不考慮的問題——相容性。
關於相容性問題可以參考:Portal項目的Hackhttp://blog.csdn.net/zouyujie1127/article/details/6903278
1、開啟VS2010,建立一個空白的解決方案。
2、在空白解決方案中建立類庫,類庫名為PlanItem,選擇PlanItem並按右鍵“引用”,選擇“添加引用”,添加System.Web和System.Web.Extension的引用
在PlanItem類庫中建立一個類MyPlanItem.cs用於描述PlanItem控制項
3、介紹一下控制項開發中常用的屬性的設計時特性
[Category("顯示")]:設定該控制項在屬性面板中顯示的組名。
[Description("進度文本,保留兩位小數")]:設定屬性說明,在選中該控制項後,可以在屬性面板的底部看到屬性的說明。
[DefaultValue("0.00")]:設定屬性的預設值。
4、首先,我應該知道控制項其實也是一個類,而控制項的最終基類就是Control類,在.NET控制項開發中,我們常用到三個類,它們分別是Control、WebControl、CompositeControl(複合控制項)這裡我們讓其繼承Control,WebControl是Control的一個子類,所以其具有比Control更多的屬性,如Style樣式等等...
在接下來的.NET控制項開發中,我們會使用一個Render()的重寫方法,從而將控制項輸出到頁面中去,要知道,.NET控制項的最終顯示形式就是以HTML標記顯示的。
所以,我們可以在要開發什麼控制項之前,先用Dreamver8將其畫出來,然後在對其進行編碼實現。
最後,將PlanItem.cs編譯成dll類庫,然後在工具箱面板對其進行添加後,就可以像使用.NET控制項一樣將其拖放到將要放置的位置進行使用了。
編譯命令,大家還記得吧。(csc /target:library PlanItem.cs)
protected override void Render(HtmlTextWriter writer) 160. { 161. string div1 = "<div style='position:static;float:left;width:" + this.DivWidth + "px;height:" + this.DivHeight + "px;z-index:1;background-image: url(" + this.BgImageDown + ");_background-image: none;'/>"; 162. writer.Write(div1); 163. string div2 = "<div style='position:static;width:" + this.ImgWidth + "%;height:" + this.DivHeight + "px;z-index:2;float:left;background-image: url(" + this.BgImageUp + ");_background-image: none; '/>"; 164. writer.Write(div2); 165. string div3 = "<div style='position:static;margin-left:auto;margin-right:auto;width:" + DivWidth + "px;height:" + DivHeight + "px;line-height:" + DivHeight + "px;z-index:3; text-align:center; vertical-align:middle;color:" + TextColor + ";font-size:12px;'>"; 166. writer.Write(div3); 167. writer.Write(this.Text + "%"); 168. writer.Write("</div>"); 169. }
細心的朋友可能會發現,在Render(HtmlTextWriter writer)方法中,出現了 _background-image: none;這是為瞭解決IE6中的侵吞現象而設的。如(左邊為正常顯示,右邊為IE6中侵吞現象的結果):
IE6的侵吞現象:兩個設定了背景的div疊加在一起,哪怕上面那個div的寬度小於下面的那個div的寬度,上面的div也會將下面的div完全覆蓋。由於我這裡使用到了三個div,無法解決其侵吞現象,如果是兩個div的話可以在代碼加上 override:hiddren 即可,這裡我讓其在IE6中不顯示進度背景只顯示進度文字了(為了過測試部那一關)。這裡我簡單提一下,解決IE6中侵吞現象最直接的辦法是將IE升級到7.0,微軟於兩年前已經宣布IE6正式淘汰,呼籲全世界的朋友使用更高版本的IE瀏覽器。
不知道大家發現了沒有,我這個控制項使用的是三個div疊加,從而實現項目進度的顯示,下面兩個div都設定了背景圖片,最下面的div表示總寬度,中間的那個div的背景圖片的寬度表示的是項目的進度,而最上面的div用文字顯示項目進度(置中顯示),這裡我使用到了position:static;而不是讓父div相對定位,子div絕對位置。這是有原因的,因為考慮到這個控制項會嵌套使用在collGridView控制項中,如果不設定為position:static;一旦出現滾動,則在Google瀏覽器中div會飄起來,出現如下現象:
這個控制項的實現比較簡單,痛點事瀏覽器的相容性問題。臨淵羨魚,不如退而結網,動手試一下吧!
MyPlanItem.cs源碼:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Web;using System.Web.UI;using System.ComponentModel;namespace PlanItem{ public class MyPlanItem : Control { private string text; [Category("顯示")] [Description("進度文本,保留兩位小數")] [DefaultValue("0.00")] public string Text { get { if (text== null||text=="") { return "0.00"; } else { decimal num = Convert.ToDecimal(text); int index = num.ToString().IndexOf('.'); if (index < 1) { return Math.Round(num, 2).ToString() + ".00"; } else { int sum = (num.ToString().Length - index - 1); if (sum == 1) { return Math.Round(num, 2).ToString() + "0"; } else { return Math.Round(num, 2).ToString(); } } } } set { text= value; } } [Category("顯示")] [Description("進度圖片寬度")] [DefaultValue(0)] public UInt64 ImgWidth { get { return (Text =="0.00") ? 0 : Convert.ToUInt64(Convert.ToDouble(text)); } } [Category("顯示")] [Description("背景圖片路徑")] public string BgImageDown { get { string s = (string)ViewState["ImageDownUrl"]; return s; } set { ViewState["ImageDownUrl"] = value; } } [Category("顯示")] [Description("進度圖片路徑")] public string BgImageUp { get { string s = (string)ViewState["ImageUpUrl"]; return s; } set { ViewState["ImageUpUrl"] = value; } } private int divWidth; [Category("顯示")] [Description("寬度")] [DefaultValue(100)] public int DivWidth { get { return divWidth; } set { divWidth = value; } } private int divHeight; [Category("顯示")] [Description("高度")] [DefaultValue(30)] public int DivHeight { get { return divHeight; } set { divHeight = value; } } private string textColor; [Category("顯示")] [Description("文本顏色")] [DefaultValue("black")] public string TextColor { get { return textColor; } set { textColor = value; } } private string bgColor; [Category("顯示")] [Description("進度背景顏色")] [DefaultValue("blue")] public string BgColor { get { return bgColor; } set { bgColor = value; } } //將控制項呈現到瀏覽器中顯示 protected override void Render(HtmlTextWriter writer) { string div1 = "<div style='position:static;float:left;width:" + this.DivWidth + "px;height:" + this.DivHeight + "px;z-index:1;background-image: url(" + this.BgImageDown + ");_background-image: none;'/>"; writer.Write(div1); string div2 = "<div style='position:static;width:" + this.ImgWidth + "%;height:" + this.DivHeight + "px;z-index:2;float:left;background-image: url(" + this.BgImageUp + ");_background-image: none; '/>"; writer.Write(div2); string div3 = "<div style='position:static;margin-left:auto;margin-right:auto;width:" + DivWidth + "px;height:" + DivHeight + "px;line-height:" + DivHeight + "px;z-index:3; text-align:center; vertical-align:middle;color:" + TextColor + ";font-size:12px;'>"; writer.Write(div3); writer.Write(this.Text + "%"); writer.Write("</div>"); } }}