日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

开发高级 Web 部件

發布時間:2023/12/19 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 开发高级 Web 部件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?????? 通過用戶控件實現 Web 部件相當容易,但是也有一些弊端:

  • 受限的重用:如果不手動復制 .ascx 文件到其他 Web 應用程序的目錄下,就不能動態添加這些控件到其他 Web 應用程序的頁面中。
  • 受限的個性化:用戶控件的個性化僅限于常用的屬性,如標題、標題 URL 等。你不能獲取用戶控件的自定義屬性,該屬性保存在個性化存儲里,只有從 Web 部件派生而來的類才能有這類功能
  • 更好的呈現和行為控制:當使用自定義服務器控件時,你對呈現過程有更好的控制,而且可以更加動態的生成用戶界面。

?????? 因此,有時候需要將高級 Web 部件實現為從 System.Web.UI.WebControls.WebParts.WebPart 派生而來的服務器控件

?

?????? 創建一個 Web 部件的步驟如下:

  • 從 WebPart 派生
  • 添加自定義屬性,通過特性指定哪些屬性可以被用戶編輯,以及在個性化存儲里哪些需要按照每個用戶存儲,哪些又被所有用戶共享
  • 編寫初始化和加載代碼,覆蓋你需要的任何初始化過程。通常,會覆蓋 OnInit()和 CreateChildrenControls()
  • 加載階段完成后,控件將觸發它們的事件,你可以在自定義 Web 部件里為子控件添加事件處理程序
  • 在呈現階段開始前,要完成最后的任務,如設置控件的屬性和基于其所綁定到的數據源構建控件的結構。
  • 最后,必須編寫代碼來呈現 Web 部件。必須覆蓋 RenderContents()方法,它被基類在呈現邊框、標題欄和帶有動詞的標題菜單的操作之間調用。
  • 1. 開始之前,創建強類型的 DataSet

    ?????? 在開始深入到開發 Web 部件的細節之前,必須為方便的訪問存在數據庫中的數據添加幾個特別的組件,這些組件將用來完成本文的代碼示例。右擊項目添加一個 DataSet,命名為 CustomerSet,拖曳 Customer 和 CustomerNotes 表至 DataSet 的設計界面上。如下圖:

    ?????? 兩個強類型的 DataSet 擴展了 DataSet 類并提供了強類型的表適配器。右擊 CustomerNotes 表,添加一個查詢用于獲取某位客戶的注解,該查詢有一個參數 CustomerId。

    ?????? 總之,應該總是在開始創建實際的用戶界面組件之前創建業務層和數據訪問層,當然,業務層和數據訪問層是可以跨不同應用程序的,就像這個強類型的 DataSet 一樣。

    ?

    2. 自定義 WebPart 的骨架

    ?????? 創建一個繼承自 WebPart 的自定義類。引入命名空間 System.Web.UI.WebControls.WebParts 可以方便的訪問 Web Parts Framework。給 Web 部件添加一些屬性。對類里的每一個屬性過程,都可以指定這個屬性是對每個用戶個性化還是被所有用戶共享,以及這個屬性能否被用戶訪問

    namespace Apress.WebParts.Samples { public class CustomerNotesPart : WebPart { public CustomerNotesPart() { } ? [WebBrowsable(true)] [Personalizable(PersonalizationScope.User)] public string Customer { get; set; } } }

    ?????? WebBrowsable 特性指定了這個屬性對終端用戶可見。Personalizable 特性指定了該屬性的個性范圍是基于每個用戶的

    ?

    3. 初始化 Web 部件

    ?????? 你可以選擇性的創建子控件,就像創建一個組合 Web 部件時所做的那樣。如果不想在 RenderContents()方法內使用預置的控件,你可以自己呈現 Web 部件。但是,使用組合控件可以讓事情變得簡單很多,因為你不必擔心 HTML 細節。

    ?????? 要創建控件,必須覆蓋 CreateChildControls()方法,如下所示:

    private TextBox NewNoteText; private Button InsertNewNote; private GridView CustomerNotesGrid; ? protected override void CreateChildControls() { NewNoteText = new TextBox(); ? InsertNewNote = new Button(); InsertNewNote.Text = "Insert..."; InsertNewNote.Click += InsertNewNote_Click; ? CustomerNotesGrid = new GridView(); CustomerNotesGrid.HeaderStyle.BackColor = System.Drawing.Color.LightBlue; CustomerNotesGrid.RowStyle.BackColor = System.Drawing.Color.LightGreen; CustomerNotesGrid.AlternatingRowStyle.BackColor = System.Drawing.Color.LightGray; CustomerNotesGrid.AllowPaging = true; CustomerNotesGrid.PageSize = 5; CustomerNotesGrid.PageIndexChanging += CustomerNotesGrid_PageIndexChanging; ? Controls.Add(NewNoteText); Controls.Add(InsertNewNote); Controls.Add(CustomerNotesGrid); } ? void CustomerNotesGrid_PageIndexChanging(object sender, GridViewPageEventArgs e) { // Insert Page Change Logic // ... } ? void InsertNewNote_Click(object sender, EventArgs e) { // Insert new note here // ... }

    ?

    4. 加載數據和處理事件??????

    ?????? 這個 Web 部件的生命周期里的下一個階段是加載階段此時,可以連接到數據庫加載數據到控件里。要完成這些,必須覆蓋 OnInit()和 OnLoad()方法,或者捕獲 Web 部件的 Init 和 Load 事件。兩種做法效果相同。但是當覆蓋 OnLoad() 時,需要調用 Base.OnLoad()以便基類的加載功能也被執行。因此,有必要建立一次事件處理程序并捕獲自定義控件的事件,以便你不會忘記這點

    // Add some method into the control's constructor public CustomerNotesPart() { this.Init += new EventHandler(CustomerNotesPart_Init); this.Load += new EventHandler(CustomerNotesPart_Load); this.PreRender += new EventHandler(CustomerNotesPart_PreRender); }

    ?

    ?????? 現在,先編寫從數據庫中加載數據的功能,然后在事件里調用它。引入 CustomerSetTableAdapters 命名空間編碼會簡短一些,這個命名空間是用原來設計的強類型的 DataSet 創建的

    void BindGrid() { // 確定服務器控件是否包含子控件。如果不包含,則創建子控件。 ? CustomerNotesTableAdapter adapter = new CustomerNotesTableAdapter(); if (Customer.Equals(string.Empty)) { CustomerNotesGrid.DataSource = adapter.GetData(); } else { CustomerNotesGrid.DataSource = adapter.GetDataByCustomer(Customer); } } ? void CustomerNotesPart_Load(object sender, EventArgs e) { // Initialize web part properties this.Title = "Customer Notes"; this.TitleIconImageUrl = "NotesImage.jpg"; } ? void CustomerNotesPart_Init(object sender, EventArgs e) { // Don't try to load data in design mode if (!this.DesignMode) { BindGrid(); } }

    ????? 一定要記得調用 EnsureChildControls()方法,因為你并不確定 ASP.NET 什么時候實際調用 CreateChildControls()來創建子控件,ASP.NET 會在需要的時候創建這些控件。因此,你需要確保在這個方法里的控件可用。

    ?

    ?????? 現在,數據已經加載到網格了。在生命周期的下一階段,ASP.NET 運行庫處理事件。你的自定義 Web 部件必須捕獲之前添加的提交新注解到數據庫的 InertNewNote 按鈕的事件和改變頁面的 CustomerNotesGrid 的事件:

    void CustomerNotesGrid_PageIndexChanging(object sender, GridViewPageEventArgs e) { CustomerNotesGrid.PageIndex = e.NewPageIndex; } ? void InsertNewNote_Click(object sender, EventArgs e) { CustomerNotesTableAdapter adapter = new CustomerNotesTableAdapter(); ? // if NoteID is an identity column, you needn't insert it. adapter.Insert(Customer, DateTime.Now, NewNoteText.Text); ? // Refresh the grid with the new row as well BindGrid(); }

    ?

    ?????? 最后,必須在代碼的另一個地方也加載數據到 GridView。一旦有人修改了 Customer 屬性的值,Web 部件就要顯示與這個新選擇的客戶相關的信息:

    private string _Customer; [WebBrowsable(true)] [Personalizable(PersonalizationScope.User)] public string Customer { get { return _Customer; } set { _Customer = value; if (!this.DesignMode) { EnsureChildControls(); CustomerNotesGrid.PageIndex = 0; CustomerNotesGrid.SelectedIndex = -1; BindGrid(); } } }

    ?

    5. 最后的呈現

    ?????? 到此為止,已經初始化了 Web 部件,創建了控件,編寫了加載數據的代碼,并且捕獲了控件事件。那么,該呈現 Web 部件了。在呈現之前,你可以在控件上設置影響最后呈現的最后的屬性。比如,如果用戶還沒有初始化 Customer 屬性,你應該禁用 InsertNewNote 按鈕

    ?????? GridView 現在可以創建必需的 HTML 控件來顯示其所綁定的數據了(數據的加載之前的事件中已經完成了)。要完成這些,需要調用 DataBind()方法:

    void CustomerNotesPart_PreRender(object sender, EventArgs e) { if (Customer.Equals(string.Empty)) { InsertNewNote.Enabled = false; } else { InsertNewNote.Enabled = true; } ? CustomerNotesGrid.DataBind(); }

    ?

    ?????? 在 RenderContents()里,可以創建 HTML 代碼來設置 Web 部件的布局。如果不覆蓋這個方法,Web 部件將按照控件在 CreateChildControls()方法里被插入到 Web 部件的 Controls 集合中的順序來自動呈現。所以,你要覆蓋這個方法來創建一個更好的,美觀的,基于表的布局:

    protected override void RenderContents(System.Web.UI.HtmlTextWriter writer) { writer.Write("<table>"); ? writer.Write("<tr>"); writer.Write("<td>"); NewNoteText.RenderControl(writer); InsertNewNote.RenderControl(writer); writer.Write(""); writer.Write("</tr>"); writer.Write("<tr>"); writer.Write("<td>"); CustomerNotesGrid.RenderControl(writer); writer.Write(""); writer.Write("</tr>"); ? writer.Write(""); }

    ?

    6. 更多定制步驟

    ?????? 如前所述,使用 IWebPart 接口,實現的自定義 Web 部件可以覆蓋屬性,如標題和描述。此外,你還可以通過為其賦值(最好在 Load 里)來為 Web 部件的其他屬性指定默認值。甚至可以覆蓋來自 Web 部件的默認屬性和方法的實現

    public override bool AllowClose { get { return false; ; } set { // Don't want this to be set. } }

    ?

    ?????? 這樣,已經創建了一個 Web 部件,其中調用者不能通過外部的屬性設置來覆蓋其行為。你已經完成了對 Web 部件哪些能做、哪些不能做的定制。

    ?

    7. 使用 Web 部件

    ?????? 在 Web 部件頁面的頂部使用 <%@ Register%> 指令注冊 Web 部件:

    <%@ Register TagPrefix="apress" Namespace="Apress.WebParts.Samples" %>

    ?????? 接著,在 WebPartZone 控件里使用該 Web 部件:

    <asp:WebPartZone runat="server" ID="MainZone" > <zonetemplate> <uc1:Customers ID="MyCustomers" runat="server" OnLoad="MyCustomers_Load" /> <apress:CustomerNotesPart ID="MyCustomerNotes" runat="server" /> </zonetemplate> </asp:WebPartZone>

    ?????? 現在調試前一篇的示例,效果如下:

    總結

    以上是生活随笔為你收集整理的开发高级 Web 部件的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。