熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

為ASP.NET控件添加設計時支持

2013-11-13 10:01:24  來源: .NET編程 
Microsoft ASPNET 為開發人員提供了一種適用於 Web 開發的功能最為強大的新工具服務器控件服務器控件使開發人員能夠在短時間內開發出響應速度快而且功能強大的 Web 應用程序所需的時間與在典型的 ASP 中創建類似應用程序的時間差不多

  ASPNET 服務器控件之所以能夠提供生產效率關鍵原因之一在於它為 Microsoft Visual Studio NET 開發環境中的服務器控件提供了豐富的設計時支持開發人員可以將服務器控件從 Visual Studio NET 工具箱拖放到頁面上通過 Properties(屬性)窗口訪問它們的屬性然後在 Visual Studio HTML 編輯器以及 ASPNET 頁面的內含代碼的類中利用 Microsoft IntelliSense? 語句完成功能這些設計時功能為 Web 開發帶來了快速應用程序開發 (RAD) 工具而這些工具已被 Microsoft Visual Basic? 開發人員使用了多年

  ASPNET 還使開發人員能夠通過創建自定義服務器控件以封裝大量可重復使用的用戶界面特定的代碼(例如登錄或注冊表單)來進一步提高生產效率盡管開發人員已經開始意識到開發自定義控件的重要性但許多人可能還沒有意識到還能在控件中利用 Visual Studio 設計時支持的強大功能使這些控件能夠像 ASPNET 中的內置控件那樣易於使用本文將介紹 Microsoft NET Framework 和 Visual Studio NET 提供的設計時支持的類型並向開發人員介紹如何構建利用這種支持的控件

  設計時支持的類型

  針對 Visual Studio NET 中的服務器控件有五種不同的設計時支持它們是

   內含代碼的類中的 IntelliSense

   設計視圖中的屬性浏覽器支持

   工具箱支持

   HTML 視圖中的屬性浏覽器支持

   HTML 編輯器中的 IntelliSense

  這些設計時支持類型是由幾個不同的機制提供的內含代碼的類中的 IntelliSense 由 IDE 啟用IDE 為您的控件讀取元數據以確定控件所提供的屬性和方法及其類型和參數要啟用內含代碼的類中的 IntelliSense只需對您的控件進行編寫和編譯然後將其程序集放到使用該控件的應用程序的 bin 子目錄中

  Visual Studio NET 編輯器設計視圖中的屬性浏覽器支持通過以下兩個途徑提供將該類型與某個屬性相關聯和/或將元數據特性與該屬性相關聯將元數據特性(下文簡稱為特性)添加到您的代碼中用於標識屬性的類別提供屬性說明以及在需要時指定首選編輯器有些類型的屬性(如 SystemDrawingColor)會自動映射到 Visual Studio NET 中的相應編輯器中

  Visual Studio NET 的 HTML 視圖中的 IntelliSense 和屬性浏覽器支持通過使用一種 XSD 架構進行提供該架構用於描述與控件相關聯的類型它使用稱為 Visual Studio 注釋的文本修飾指定控件的首選編輯器和其他首選項

  最後您可以通過結合特性和帶有特定屬性的自定義位圖來支持從 Visual Studio NET 工具箱拖放控件

  Blog 控件示例

  用於說明 Visual Studio NET 中的設計時功能的控件稱作Blog 控件如本文末尾的列表 所示該控件提供利用 XML 作為存儲介質的簡單 Web 日志功能Web 日志通常稱為 Blog它實際上是一個 Web 頁面供人們在上面張貼有關日常生活世態百象時事政治或人們所關心的其他問題的定期觀察報告或評論Blog 條目是通過 Web 浏覽器添加的

  Blog 控件非常簡單明了它利用控件組合向浏覽器提供輸出在組合控件中CreateChildControls 方法(由 ASPNET 運行時自動調用)會被重寫利用此方法我們可以創建構成自定義控件 UI 的控件並將它們添加到控件的控件集合中此外該控件還包含用於顯示和添加 Blog 以及當 XML Blog 存儲文件不存在時創建一個這樣的文件的邏輯該控件的幾個公共屬性需要開發人員在設計時進行設置其中包括在添加新 Blog 時該控件將重定向到的頁面的 URL與新 Blog 關聯的電子郵件地址控件模式(顯示或添加)以及各 Blog 條目之間的分隔線的顏色 所示為正在運行的 Blog 控件Add Blog(添加 Blog)超鏈接由 ASPNET 超鏈接控件提供獨立於 Blog 控件BlogClientaspx 的代碼如列表 所示BlogClientaspx 的 codebehind 類如列表 所示它提供單擊 Add Blog(添加 Blog)鏈接時更改 Blog 模式的邏輯

  為ASP.NET控件添加設計時支持

  圖 運行時的 Blog 控件

  圖所示為設計時基本 Blog 控件的外觀請注意雖然列出了屬性但並未分類

  為ASP.NET控件添加設計時支持

  圖 設計時的 Blog 控件

  添加設計時支持

  雖然在 Web 窗體頁上使用 Blog 控件非常簡單但並不是很直觀例如如果沒有相關文檔使用 Blog 控件的人就無法知道 Mode 屬性的有效值只能是 Display 或 Add如果未將 Add 模式的相關信息明確地告訴使用該控件的開發人員他們就很難自己發現並使用這種模式

  對於使用 Visual Studio NET(或支持 IntelliSense 的其他 IDE)的開發人員而言可以通過為控件添加設計時支持來解決這一問題這可以通過綜合利用本文前面所介紹的方法來實現在為自定義服務器控件提供設計時支持所面臨的挑戰中部分原因來自於在自定義控件中全面支持設計時功能所需的方法的多樣性最簡單的不需要任何附加編碼的是內含代碼的類中的 IntelliSense 語句完成方法如圖 所示此方法適用於 BlogClientaspxvb

  為ASP.NET控件添加設計時支持

  圖 內含代碼的類中的 IntelliSense

  遺憾的是語句完成功能的自動支持並沒有擴展到編輯 Web 窗體頁時的設計視圖或 HTML 視圖而且 Visual Studio 也沒有提供不需要額外的控件工作就能在屬性浏覽器中查看和編輯屬性的內置支持更復雜的是要在 Web 窗體編輯器的屬性浏覽器和設計視圖中支持 IntelliSense需要采用一種方法要在該編輯器的 HTML 視圖中支持 IntelliSense則需要采用另一種方法

  要在設計視圖中支持屬性浏覽所需的方法是通過特性告訴 Visual Studio NET 如何處理屬性要在 HTML 視圖中支持語句完成和屬性浏覽需要生成一個自定義 XSD 架構以描述控件中的類型我們將在下文討論這兩種方法

  設計視圖和元數據特性

  Visual Studio NET 為使用拖放技術的動態控件設計和修改提供了豐富的支持同時還提供了屬性浏覽器之類的工具以及相關的設計器(例如顏色選擇器)對這些工具的支持是通過一系列特性提供的您可以將這些特性添加到您的控件中這些特性用於告訴 Visual Studio IDE 是否在屬性浏覽器中顯示控件的屬性屬性所屬的類型以及應使用哪個設計器設置屬性的值

  對於將要提供設計時支持的控件版本我們將制作一份控件文件 Blogvb 的副本並將其命名為 Blog_DTvb然後在副本文件上進行修改這樣可以生成該控件的設計時版本並保留原始控件以便進行比較

  要支持在屬性浏覽器中編輯 AddRedirect 屬性應在屬性進程之前添加以下特性如以下代碼片段所示

  <Browsable(True) _
Category(行為) _
Description(成功提交新的 Blog 條目後 & _
應重定向到的 & _
頁面的 URL) _
Editor(SystemWebUIDesignUrlEditor _
GetType(UITypeEditor))> _
Public Property AddRedirect() As String
屬性進程代碼
End Property


  這些特性聲明允許在屬性浏覽器中顯示屬性為屬性設置所需的類別(當屬性按類別排序時)提供屬性說明並告訴 Visual Studio NET 使用 UrlEditor 類編輯屬性的值如圖 所示

  為ASP.NET控件添加設計時支持

  圖 設計視圖中的屬性支持

  此處所述的特性語法適用於 Visual Basic NET在 Visual Basic NET 中特性通過以下語法進行聲明

  <AttributeName(AttributeParams)>


  在 C# 中特性采用如下形式

[AttributeName(AttributeParams)]

  Visual Basic NET 要求特性聲明與其修改的成員位於同一行中因此通常最好在特性後面跟一個 Visual Basic 行接續字符以提高可讀性

<AttributeName(AttributeParams)> _
Public Membername()

  在 C# 和 Visual Basic 中您可以在一對 [ ] 或 <> 括號中聲明多個特性特性之間用逗號分隔而在 Visual Basic NET 中如果它們出現在不同的行中則必須使用 Visual Basic 行接續符銜接特性使其位於同一個語句中

  添加工具箱支持

  除了設置屬性級別的特性外還可設置某些類和程序集級別的特性例如您可以使用程序集級別的特性 TagPrefix 來指定標記前綴供程序集中包含的任何控件使用之後當您從 Visual Studio 工具箱中向某個 Web 窗體頁上添加該控件的實例時Visual Studio NET 將自動插入這個標記前綴以下代碼片段顯示了 TagPrefix 特性的語法該特性應放置在定義該控件的類模塊內但應在類和命名空間聲明之外(請注意在 Visual Basic NET 項目中命名空間是在項目級別定義的因此您不用擔心如何將程序集特性放置到命名空間聲明之外)在以下特性中TagPrefix 特性的第一個參數是控件的命名空間第二個參數是您希望為標記前綴使用的文本

  <Assembly: TagPrefix(BlogControl BlogControl)>


  要將控件集成到 Visual Studio NET 環境中應將 ToolBoxData 特性(該特性用於告訴 Visual Studio NET 從工具箱中為控件插入的首選標記名)添加到實現該控件的類中

  <ToolboxData(<{}:Blog_DT runat=server></{}:Blog_DT>)> _
Public Class Blog_DT
Inherits Panel
Implements INamingContainer
控件實現
End Class


  將控件從工具箱中插入到頁面上時由 TagPrefix 特性指定的標記前綴將插入 {} 占位符而其他文本將按原樣插入

  您還可以為控件提供自己的自定義圖標以顯示在工具箱中為此需要創建一個 x 像素大小的位圖(左下方的像素采用透明色)其名稱與包含該控件的類相同(即 classnamebmp)使用 Add Existing Item(添加現有項)命令將該位圖添加到項目中然後使用屬性浏覽器將其 Build Action(創建操作)設置為 Embedded Resource(內置資源)如圖 所示

  為ASP.NET控件添加設計時支持

  圖 設置 Build Action(創建操作)

  編譯完成後該控件將支持從工具箱中將控件添加到某個頁面中時為 Blog 控件自動插入 @Register 指令標記前綴和標記名並在工具箱中顯示自定義圖標如圖 所示要將控件添加到 Visual Studio NET 工具箱中應完成以下簡單步驟

  在設計視圖中選擇 Visual Studio NET 工具箱的 Web forms(Web 窗體)選項卡
在該選項卡上的任意位置單擊鼠標右鍵然後選擇 Add/Remove Items(添加項目/刪除項目)(Visual Studio NET 中為 Customize Toolbox [自定義工具箱])

  選擇 NET Framework Components(NET Framework 組件)選項卡然後單擊 Browse(浏覽)
浏覽到編譯後的控件程序集所在的位置選中它並單擊 Open(打開)

  單擊 OK(確定)

  為ASP.NET控件添加設計時支持

  圖 工具箱中的自定義控件

  將控件添加到工具箱中後可以通過雙擊該控件或將其從工具箱中拖放到 Web 窗體頁上將其添加到 Web 窗體頁中無論何種情況Visual Studio NET 都會自動插入正確的 @Register 指令(包括基於程序集級別的特性設置 TagPrefix)還將使用 ToolBoxData 屬性中指定的標記名為該控件生成一組標記

  添加設計器

  正如前文所述Blog 控件在 Web 窗體編輯器的設計視圖中沒有任何可視界面這使得選擇頁面上的控件很困難更難以理解控件在運行時的外觀為了解決這個問題我們可以添加設計器支持使設計時的 HTML 在外觀上接近於運行時的 Blog 控件請注意您還可以生成可以完整再現控件運行時輸出的設計器但此操作相當復雜而且超出了本文的討論范圍

  所有服務器控件設計器都是從類 SystemWebUIDesignControlDesigner 派生而來該類提供了大量方法您可以重寫這些方法為您的控件提供設計時渲染以下代碼簡單重寫了 GetDesignTimeHtml 方法返回設計時顯示的簡單 HTML請注意該示例顯示了 Blog 控件的整個設計器類您可以簡單地將其添加到現有的 Blog_DTvb 類文件中

  Public Class BlogDesigner
Inherits ControlDesigner

Public Overrides Function GetDesignTimeHtml() As String
Return <h>Blog</h><hr/><hr/>
End Function

End Class


  要將該設計器綁定到 Blog_DT 類中我們使用了 Designer 特性如以下片段所示請注意此段代碼還添加了一個描述控件功能的 Description 特性

  <Description(簡單 Blog 控件支持顯示 & _
Web 日志/來自 XML 文件的新條目) _
Designer(BlogControlBlogDesigner) _
ToolboxData(<{}:Blog_DT runat=server></{}:Blog_DT>)> _
Public Class Blog_DT
Inherits Panel
Implements INamingContainer


  如您所見BlogDesigner 類非常簡單但它為控件在 Web 窗體頁上的設計時外觀添加了大量內容如圖 所示

  為ASP.NET控件添加設計時支持

  圖 添加設計時渲染

  列表 顯示了 Blog 控件的代碼它已經使用特性進行了更新以啟用設計視圖和屬性浏覽器中的控件設計時支持請注意該示例添加了多條 using 指令以導入支持我們使用的特性和設計器類所需要的命名空間這個新列表還添加了一個用於 Mode 屬性值的枚舉

  HTML視圖支持自定義架構和 Visual Studio 注釋

  盡管前文所述的特性幫助我們為 Blog 控件提供了設計時支持但這裡遺漏了一個重要的問題在 Web 窗體編輯器的 HTML 視圖中添加標記和特性的 IntelliSense 支持對於那些認為在 HTML 環境中工作比在所見即所得風格的環境中工作更舒適的開發人員來說這是一個極大的疏忽

  因為 Web 窗體編輯器的 HTML 視圖使用 XSD 架構決定在 Web 窗體頁上提供哪些元素和特性所以為了糾正這一問題我們需要提供一個描述 Blog 控件及其所支持的特性的 XSD 架構也可以在該架構中添加注釋告訴 Visual Studio NET 各種元素的有關信息以及我們所希望的元素行為

  列表 包含 Blog 控件特定的 XSD 架構的部分內容實際的架構文件(可從本文的示例代碼中獲得)還包含面板控件(Blog_DT 控件就是由它派生的)的類型定義以及其他必需的特性和類型定義這些定義是從為內置 ASPNET 服務器控件創建的 aspxsd 架構文件中復制的

  請注意任何時候都不應直接修改 aspxsd 架構文件而只應將必需的類型和特性定義復制到您的自定義架構文件中盡管這看起來是多余的但如果直接編輯 aspxsd以後安裝 NET Framework 或服務包時該文件將被覆蓋您的自定義輸入項將因此而丟失

  在列表 請注意根架構元素上的 targetNamespace 和 xmlns 特性這兩個特性用於為控件的架構定義 XML 命名空間targetNamespace 和 xmlns 特性的值還將用於 Web 窗體頁中的特性綁定該架構<xsd:element> 標記定義根 Blog_DT 元素<xsd:complexType> 標記定義 Blog_DT 元素的特性包括 <xsd:attributeGroup> 標記引用的 Web 控件特性最後<xsd:simpleType> 標記定義 BlogMode 類型的枚舉該類型被用作 Blog_DT 元素的一個特性

  請注意列表 使用 vs:builder 注釋來告訴 Visual Studio NET 對 AddRedirect 特性使用 URL 生成器而對 SeparatorColor 特性使用顏色生成器vs:builder 注釋是可用於修改架構的注釋之一 列出了最常用的注釋

  表 常用的 Visual Studio NET 注釋

   注釋 用途 有效值 vs:absolutepositioning 在根 <schema> 元素上使用用於確定 Visual Studio 是否可以插入用於定位的樣式特性 true 或 false vs:blockformatted 表明是否可以在自動格式化期間為元素添加前導空格 true 或 false vs:builder 指定用於編輯相關屬性值的生成器 顏色樣式或 URL vs:deprecated 允許將某個相關屬性標記為已否決以防止其在屬性浏覽器和語句完成中出現 true 或 false vs:empty 在元素級別使用用於指示 Visual Studio NET 應對相關標記(無結束標記)使用一個標記語法 true 或 false vs:friendlyname 在根級別使用用於為架構提供顯示名   vs:iscasesensitive 在根級別使用說明 Visual Studio NET 是否以區分大小寫的方式處理相關標記 true 或 false vs:ishtmlschema 在根級別使用說明架構是否是一個 HTML 文檔架構 true 或 false vs:nonbrowseable 在特性級別使用說明該特性不應出現在語句完成中 true 或 false vs:readonly 在特性級別使用說明不能在屬性窗口中修改該特性 true 或 false vs:requireattributequotes 在根級別使用說明特性值必須用引號括起 true 或 false

  創建自己的 XSD 架構後可以將其與 aspxsd 文件保存到同一位置(在 Visual Studio NET 默認為 C:\Program Files\Microsoft Visual Studio NET \Common\Packages\schemas\xml\)

  要允許 Visual Studio NET 讀取您的自定義架構需要將一個 xmlns 特性添加到要使用該架構的頁面的 <body> 標記中如以下代碼片段所示

  <body xmlns:BlogControl=urn:/schemas


  請注意此段代碼使用具有 xmlns 特性的 BlogControl 前綴來說明該架構適用於帶有 BlogControl 標記前綴的控件這個可以再次調用的前綴是使用 TagPrefix 特性進行設置的(有關該特性的說明請參見上文中的元數據特性一節)xmlns 特性的值應與架構根元素中定義的 targetNamespace 特性的值相同

  通過 xmlns 特性綁定架構之後即可鍵入一個開放的字符並使 Blog 控件顯示為語句完成的一個選項如圖 所示此時還應獲取已定義屬性的語句完成包括 Mode 屬性的有效值以及由 XSD 文件中的注釋指定的生成器

  為ASP.NET控件添加設計時支持

  圖 HTML 視圖中的語句完成

  小結

  本文介紹了 Visual Studio NET 中適用於 ASPNET 服務器控件的設計時支持還說明了開發人員如何在自己的自定義控件中利用這一支持功能雖然在控件中添加設計時支持相對簡明但要充分利用這些功能卻需要掌握多種不同的技巧特別欠缺的知識領域就是如何將自定義 XSD 架構綁定到頁面上在撰寫本文時還不具備將頁面與控件 XSD 架構連接起來所需的 xmlns 特性的內置支持所以還需要手動添加這個特性希望以後的 Visual Studio NET 版本能夠自動完成這一過程

  本文中的示例代碼包含一個適用於 Blog 控件基礎版和設計時支持版的 Visual Studio NET 項目還包含一個說明如何使用每個控件的客戶端項目要運行 BlogControlClient 項目您需要在 IIS 中創建一個虛擬目錄 BlogControlClient然後將其映射到硬盤驅動器上用於保存 BlogControlClient 項目文件夾的位置

  真誠地感謝 Microsoft Visual Studio NET 團隊的 Rob Caron他在我編寫自定義 XSD 架構的創建和綁定過程中給予了極大的幫助

  代碼列表

  列表 Blogvb

  supports Color structure
Imports SystemDrawing
支持 StreamWriter 類型
Imports SystemIO
Imports SystemWebUI
支持使用 HTML 控件
Imports SystemWebUIHtmlControls
支持使用 Web 控件
Imports SystemWebUIWebControls

Public Class Blog
Inherits Panel
Implements INamingContainer

Protected BlogDS As DataSet
Protected TitleTB As TextBox
Protected BlogText As TextBox

Private _addRedirect As String
Private _email As String
Private _mode As String
Private _separatorColor As Color = ColorBlack

Public Property AddRedirect() As String
Get
Return Me_addRedirect
End Get
Set(ByVal Value As String)
Me_addRedirect = Value
End Set
End Property

Public Property Email() As String
Get
Return Me_email
End Get
Set(ByVal Value As String)
Me_email = Value
End Set
End Property

Public Property Mode() As String
Get
Return Me_mode
End Get
Set(ByVal Value As String)
Me_mode = Value
End Set
End Property

Public Property SeparatorColor() As Color
Get
Return Me_separatorColor
End Get
Set(ByVal Value As Color)
Me_separatorColor = Value
End Set
End Property

  Protected Overrides Sub OnInit(ByVal e As EventArgs)
LoadData()
MyBaseOnInit(e)
End Sub

Protected Overrides Sub CreateChildControls()
If Not Me_mode = Add Then
DisplayBlogs()
Else
NewBlog()
End If
End Sub

Protected Sub LoadData()
BlogDS = New DataSet()

Try
BlogDSReadXml(PageServerMapPath(Blogxml))
Catch fnfEx As FileNotFoundException
CreateBlankFile()
LoadData()
End Try
End Sub

Protected Sub DisplayBlogs()
Dim BlogDate As DateTime
Dim CurrentDate As DateTime = New DateTime()
Dim BlogRows As DataRowCollection = _
BlogDSTables()Rows
Dim BlogDR As DataRow
For Each BlogDR In BlogRows
Dim BDate As String = BlogDR(date)ToString()
BlogDate = New DateTime _
(ConvertToInt(BDateSubstring( )) _
ConvertToInt(BDateSubstring( )) _
ConvertToInt(BDateSubstring( )))

If Not CurrentDate = BlogDate Then
Dim TempDate As Label = New Label()
TempDateText = BlogDateToLongDateString()
TempDateFontSize = FontUnitLarge
TempDateFontBold = True
MeControlsAdd(TempDate)
MeControlsAdd _
(New LiteralControl(<br/><br/>))
CurrentDate = BlogDate
End If

Dim Anchor As HtmlAnchor = New HtmlAnchor()
AnchorName = # & BlogDR(anchorID)ToString()
MeControlsAdd(Anchor)

Dim Title As Label = New Label()
TitleText = BlogDR(title)ToString()
TitleFontSize = FontUnitLarger
TitleFontBold = True
MeControlsAdd(Title)

MeControlsAdd(New LiteralControl(<p>))
Dim BlogText As LiteralControl = _
New LiteralControl(<div> & _
BlogDR(text)ToString() & </div>)
MeControlsAdd(BlogText)
MeControlsAdd(New LiteralControl(</p>))

Dim Email As HyperLink = New HyperLink()
EmailNavigateUrl = mailto: & _
BlogDR(email)ToString()
EmailText = Email me
MeControlsAdd(Email)

MeControlsAdd(New LiteralControl( | ))
Dim AnchorLink As HyperLink = New HyperLink()
AnchorLinkNavigateUrl = _
PageRequestUrlToString() & # & _
BlogDR(anchorID)ToString()
AnchorLinkText = Link
MeControlsAdd(AnchorLink)

MeControlsAdd(New _
LiteralControl(<hr color= & _
ColorTranslatorToHtml(_separatorColor) & _
width=%/><br/>))
Next
End Sub

Protected Sub NewBlog()
Dim Title As Label = New Label()
TitleText = Create New Blog
TitleFontSize = FontUnitLarger
TitleFontBold = True
MeControlsAdd(Title)

MeControlsAdd(New LiteralControl(<br/><br/>))

Dim TitleLabel As Label = New Label()
TitleLabelText = Title:
TitleLabelFontBold = True
MeControlsAdd(TitleLabel)
TitleTB = New TextBox()
MeControlsAdd(TitleTB)

MeControlsAdd(New LiteralControl(<br/>))

Dim BlogTextLabel As Label = New Label()
BlogTextLabelText = Text:
BlogTextLabelFontBold = True
MeControlsAdd(BlogTextLabel)
BlogText = New TextBox()
BlogTextTextMode = TextBoxModeMultiLine
BlogTextRows =
BlogTextColumns =
MeControlsAdd(BlogText)

MeControlsAdd(New LiteralControl(<br/>))

Dim Submit As Button = New Button()
SubmitText = Submit
AddHandler SubmitClick AddressOf MeSubmit_Click
MeControlsAdd(Submit)
End Sub

Protected Sub Submit_Click(ByVal Sender As Object _
ByVal e As EventArgs)
EnsureChildControls()
AddBlog()
End Sub

Protected Sub AddBlog()
Dim NewBlogDR As DataRow
NewBlogDR = BlogDSTables()NewRow()
NewBlogDR(date) = FormatDate(DateTimeToday)
NewBlogDR(title) = TitleTBText
NewBlogDR(text) = BlogTextText
NewBlogDR(anchorID) = GuidNewGuid()ToString()
NewBlogDR(email) = _email
BlogDSTables()RowsInsertAt(NewBlogDR )
BlogDSWriteXml(PageServerMapPath(Blogxml))
PageResponseRedirect(_addRedirect)
End Sub

Protected Function FormatDate(ByVal dt As DateTime) _
As String
Dim retString As String
retString = StringFormat({:D} dtMonth)
retString &= StringFormat({:D} dtDay)
retString &= StringFormat({:D} dtYear)
Return retString
End Function

Public Sub CreateBlankFile()
Dim NewXml As StreamWriter = _
FileCreateText(PageServerMapPath(Blogxml))

NewXmlWriteLine(<blogs>)
NewXmlWriteLine _
( <! blog field describes a single blog )
NewXmlWriteLine( <blog>)
NewXmlWriteLine( <! date field contains & _
the creation date of the blog )
NewXmlWriteLine( <date> & _
FormatDate(DateTimeToday) & </date>)
NewXmlWriteLine _
( <title>Temporary Blog</title>)
NewXmlWriteLine( <! text field & _
should contain the blog text including any & _
desired HTML tags )
NewXmlWriteLine( <text>This entry & _
indicates that the file blogxml was not & _
foundA default version of this file has & _
been created for youYou can modify the & _
fields in this file as desiredIf you set & _
the Blog control to add mode (add the & _
attribute mode=add to the controls & _
declaration) the control will & _
automatically populate the XML file when & _
you submit the form</text>)
NewXmlWriteLine( <! anchorID field & _
will be autopopulated by the control )
NewXmlWriteLine( <anchorID></anchorID>)
NewXmlWriteLine( <! email field should & _
contain the email address for feedback )
NewXmlWriteLine( <email>change this to a & _
valid email address</email>)
NewXmlWriteLine( </blog>)
NewXmlWriteLine(</blogs>)
NewXmlClose()
End Sub

End Class

  列表 BlogClientaspx

  <%@ Register TagPrefix=cc Namespace=BlogControl
Assembly=BlogControl %>
<%@ Page Language=vb AutoEventWireup=false
Codebehind=BlogClientaspxvb
Inherits=BlogControlClientWebForm%>
<!DOCTYPE HTML PUBLIC //WC//DTD HTML
Transitional//EN
<html>
<head>
<title>Blog Client</title>
</head>
<body>
<form id=Form method=post runat=server
<p><asp:hyperlink id=Link navigateurl=BlogClientaspx?mode=add runat=server>Add Blog</asp:hyperlink></p>
<cc:blog
id=Blog
Email=
AddRedirect=BlogClientaspx
SeparatorColor=LawnGreen
runat=server></cc:blog>
<p><asp:hyperlink id=Link
navigateurl=BlogClientaspx?mode=add
runat=server>Add Blog</asp:hyperlink></p>
</form>
</body>
</html>

  列表 BlogClientaspxvb

  Imports BlogControl

Public Class WebForm
Inherits SystemWebUIPage
Protected WithEvents Link As _
SystemWebUIWebControlsHyperLink
Protected WithEvents Link As _
SystemWebUIWebControlsHyperLink
Protected WithEvents Blog As BlogControlBlog

Private Sub Page_Load(ByVal sender As SystemObject _
ByVal e As SystemEventArgs) Handles MyBaseLoad
If RequestQueryString(mode) = add Then
BlogMode = Add
LinkVisible = False
LinkVisible = False
Else
BlogMode = Display
LinkVisible = True
LinkVisible = True
End If
End Sub

End Class

  列表 Blog_DTvb

  支持設計時特性
Imports SystemComponentModel
支持顏色結構
Imports SystemDrawing
支持 UITypeEditor 類型
Imports SystemDrawingDesign
支持 StreamWriter 類型
Imports SystemIO
Imports SystemWebUI
支持 ControlDesigner 類型
請注意必須添加程序集
SystemDesign 的引用才能導入此命名空間
Imports SystemWebUIDesign
支持使用 HTML 控件
Imports SystemWebUIHtmlControls
支持使用 Web 控件
Imports SystemWebUIWebControls

<Assembly: TagPrefix(BlogControl BlogControl)>

Public Enum BlogMode
Add
Display
End Enum

<Description(Simple Blog controlSupports display & _
of Web log / news items from an XML file) _
Designer(BlogControlBlogDesigner) _
ToolboxData(<{}:Blog_DT runat=server></{}:Blog_DT>)> _
Public Class Blog_DT
Inherits Panel
Implements INamingContainer

Protected BlogDS As DataSet
Protected TitleTB As TextBox
Protected BlogText As TextBox

Private _addRedirect As String
Private _email As String
Private _mode As BlogMode
Private _separatorColor As Color = ColorBlack

<Browsable(True) _
Category(Behavior) _
Description(URL to which the page should redirect after successful submission of a new Blog entry) _
Editor(SystemWebUIDesignUrlEditor _
GetType(UITypeEditor))> _
Public Property AddRedirect() As String
Get
Return Me_addRedirect
End Get
Set(ByVal Value As String)
Me_addRedirect = Value
End Set
End Property

<Browsable(True) _
Category(Behavior) _
Description(Email address the control will use for listing in new Blog entries)> _
Public Property Email() As String
Get
Return Me_email
End Get
Set(ByVal Value As String)
Me_email = Value
End Set
End Property

<Browsable(True) _
Category(Behavior) _
Description(Controls whether existing Blogs are displayed or fields for creating a new Blog entry)> _
Public Property Mode() As BlogMode
Get
Return Me_mode
End Get
Set(ByVal Value As BlogMode)
Me_mode = Value
End Set
End Property

<Browsable(True) _
Category(Appearance) _
Description(Controls the color of the line that separates Blog entries when in display mode)> _
Public Property SeparatorColor() As Color
Get
Return Me_separatorColor
End Get
Set(ByVal Value As Color)
Me_separatorColor = Value
End Set
End Property

Protected Overrides Sub OnInit(ByVal e As EventArgs)
LoadData()
MyBaseOnInit(e)
End Sub

Protected Overrides Sub CreateChildControls()
If Not Me_mode = BlogModeAdd Then
DisplayBlogs()
Else
NewBlog()
End If
End Sub

Protected Sub LoadData()
BlogDS = New DataSet()

Try
BlogDSReadXml(PageServerMapPath(Blogxml))
Catch fnfEx As FileNotFoundException
CreateBlankFile()
LoadData()
End Try
End Sub

Protected Sub DisplayBlogs()
Dim BlogDate As DateTime
Dim CurrentDate As DateTime = New DateTime()

Dim BlogRows As DataRowCollection = _
BlogDSTables()Rows
Dim BlogDR As DataRow
For Each BlogDR In BlogRows
Dim BDate As String = BlogDR(date)ToString()
BlogDate = New DateTime _
(ConvertToInt(BDateSubstring( )) _
ConvertToInt(BDateSubstring( )) _
ConvertToInt(BDateSubstring( )))

If Not CurrentDate = BlogDate Then
Dim TempDate As Label = New Label()
TempDateText = BlogDateToLongDateString()
TempDateFontSize = FontUnitLarge
TempDateFontBold = True
MeControlsAdd(TempDate)
MeControlsAdd _
(New LiteralControl(<br/><br/>))
CurrentDate = BlogDate
End If

  Dim Anchor As HtmlAnchor = New HtmlAnchor()
AnchorName = # + BlogDR(anchorID)ToString()
MeControlsAdd(Anchor)

Dim Title As Label = New Label()
TitleText = BlogDR(title)ToString()
TitleFontSize = FontUnitLarger
TitleFontBold = True
MeControlsAdd(Title)

MeControlsAdd(New LiteralControl(<p>))
Dim BlogText As LiteralControl = _
New LiteralControl(<div> & _
BlogDR(text)ToString() & </div>)
MeControlsAdd(BlogText)
MeControlsAdd(New LiteralControl(</p>))

Dim Email As HyperLink = New HyperLink()
EmailNavigateUrl = mailto: & _
BlogDR(email)ToString()
EmailText = Email me
MeControlsAdd(Email)

MeControlsAdd(New LiteralControl( | ))
Dim AnchorLink As HyperLink = New HyperLink()
AnchorLinkNavigateUrl = _
PageRequestUrlToString() & # & _
BlogDR(anchorID)ToString()
AnchorLinkText = Link
MeControlsAdd(AnchorLink)

MeControlsAdd _
(New LiteralControl(<hr color= & _
ColorTranslatorToHtml(_separatorColor) & _
width=%/><br/>))
Next
End Sub

Protected Sub NewBlog()
Dim Title As Label = New Label()
TitleText = Create New Blog
TitleFontSize = FontUnitLarger
TitleFontBold = True
MeControlsAdd(Title)

MeControlsAdd(New LiteralControl(<br/><br/>))

Dim TitleLabel As Label = New Label()
TitleLabelText = Title:
TitleLabelFontBold = True
MeControlsAdd(TitleLabel)
TitleTB = New TextBox()
MeControlsAdd(TitleTB)

MeControlsAdd(New LiteralControl(<br/>))

Dim BlogTextLabel As Label = New Label()
BlogTextLabelText = Text:
BlogTextLabelFontBold = True
MeControlsAdd(BlogTextLabel)
BlogText = New TextBox()
BlogTextTextMode = TextBoxModeMultiLine
BlogTextRows =
BlogTextColumns =
MeControlsAdd(BlogText)

MeControlsAdd(New LiteralControl(<br/>))

Dim Submit As Button = New Button()
SubmitText = Submit
AddHandler SubmitClick AddressOf MeSubmit_Click
MeControlsAdd(Submit)
End Sub

Protected Sub Submit_Click(ByVal Sender As Object _
ByVal e As EventArgs)
EnsureChildControls()
AddBlog()
End Sub

Protected Sub AddBlog()
Dim NewBlogDR As DataRow
NewBlogDR = BlogDSTables()NewRow()
NewBlogDR(date) = FormatDate(DateTimeToday)
NewBlogDR(title) = TitleTBText
NewBlogDR(text) = BlogTextText
NewBlogDR(anchorID) = GuidNewGuid()ToString()
NewBlogDR(email) = _email
BlogDSTables()RowsInsertAt(NewBlogDR )
BlogDSWriteXml(PageServerMapPath(Blogxml))
PageResponseRedirect(_addRedirect)
End Sub

Protected Function FormatDate(ByVal dt As DateTime) As String
Dim retString As String
retString = StringFormat({:D} dtMonth)
retString &= StringFormat({:D} dtDay)
retString &= StringFormat({:D} dtYear)
Return retString
End Function

Public Sub CreateBlankFile()
Dim NewXml As StreamWriter = _
FileCreateText(PageServerMapPath(Blogxml))

NewXmlWriteLine(<blogs>)
NewXmlWriteLine _
( <! blog field describes a single blog )
NewXmlWriteLine( <blog>)
NewXmlWriteLine( <! date field contains & _
the creation date of the blog )
NewXmlWriteLine( <date> & _
FormatDate(DateTimeToday) & </date>)
NewXmlWriteLine _
( <title>Temporary Blog</title>)
NewXmlWriteLine( <! text field & _
should contain the blog text including any & _
desired HTML tags )
NewXmlWriteLine( <text>This entry & _
indicates that the file blogxml was not & _
foundA default version of this file has & _
been created for youYou can modify the & _
fields in this file as desiredIf you set & _
the Blog control to add mode (add the & _
attribute mode=add to the controls & _
declaration) the control will & _
automatically populate the XML file when & _
you submit the form</text>)
NewXmlWriteLine( <! anchorID field & _
will be autopopulated by the control )
NewXmlWriteLine( <anchorID></anchorID>)
NewXmlWriteLine( <! email field should & _
contain the email address for feedback )
NewXmlWriteLine( <email>change this to a & _
valid email address</email>)
NewXmlWriteLine( </blog>)
NewXmlWriteLine(</blogs>)
NewXmlClose()
End Sub

End Class

Public Class BlogDesigner
Inherits ControlDesigner

Public Overrides Function GetDesignTimeHtml() As String
Return <h>Blog</h><hr/><hr/>
End Function

End Class

  列表 Blogxsd

  <?xml version= encoding=utf ?>
<xsd:schema
targetNamespace=urn:/schemas
elementFormDefault=qualified
xmlns=urn:/schemas
xmlns:xsd=
xmlns:vs=StudioIntellisense
vs:friendlyname=Blog Control Schema
vs:ishtmlschema=false
vs:iscasesensitive=false
vs:requireattributequotes=true
<xsd:annotation>
<xsd:documentation>
Blog Control schema
</xsd:documentation>
</xsd:annotation>

<xsd:element name=Blog_DT type=BlogDef />

<! <aspnetian:Blog>
<xsd:complexType name=BlogDef
<! <aspnetian:Blog>specific attributes
<xsd:attribute name=AddRedirect type=xsd:string
vs:builder=url/>
<xsd:attribute name=Email type=xsd:string/>
<xsd:attribute name=Mode type=BlogMode/>
<xsd:attribute name=SeparatorColor
type=xsd:string
vs:builder=color/>
<! <asp:Panel>specific attributes
<xsd:attribute name=BackImageUrl
type=xsd:anyURI />
<xsd:attribute name=HorizontalAlign
type=HorizontalAlign />
<xsd:attribute name=Wrap type=xsd:boolean />
<xsd:attribute name=Enabled type=xsd:boolean />
<xsd:attribute name=BorderWidth type=ui />
<xsd:attribute name=BorderColor type=xsd:string
vs:builder=color />
<xsd:attribute name=BorderStyle
type=BorderStyle />
<xsd:attributeGroup ref=WebControlAttributes />
</xsd:complexType>

<! DataTypes
<xsd:simpleType name=BlogMode
<xsd:restriction base=xsd:string
<xsd:enumeration value=Add />
<xsd:enumeration value=Display />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>


From:http://tw.wingwit.com/Article/program/net/201311/12307.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.