天天看點

動态加載使用者控件(整理)

微軟示例:

就像您可以通過程式設計方式在 Web 窗體頁上建立任意 ASP.NET 伺服器控件的執行個體,您也可以通過使用包含頁的 LoadControl 方法來做到這一點。但您首先必須使用@ Control 指令的className 屬性将強類型與使用者控件相關聯。之是以需要這樣是因為LoadControl 方法傳回 Control 類的類型,并且您需要将該使用者控件轉換為合适的強類型,以便設定該控件的各個屬性。

以下代碼使用 className 屬性将 MyUserControl.ascx 檔案中儲存的使用者控件轉換為強類型。

<%@ Control className="MyUserControl" %>      

以程式設計方式建立使用者控件的執行個體

  1. 使用@ Reference 指令在要包含使用者控件的 Web 窗體頁的頂部注冊該使用者控件。當以程式設計方式建立使用者控件時,隻有您建立了對該控件的引用後,使用者控件的強類型才可用于該 Web 窗體頁。例如,以下代碼建立對 MyUserControl.ascx 檔案中所建立使用者控件的引用。

    <%@ Reference Control="MyUserControl.ascx" %>

    注意 當以聲明方式在 Web 窗體頁中建立使用者控件的執行個體時,請使用@ Register 指令。

  2. 在代碼隐藏類檔案中,或是在包含 .aspx 檔案的代碼聲明塊中,建立使用者控件的執行個體。根據需要配置設定屬性值,并使用 Add 方法将該控件添加到包含頁的 ControlCollection 對象上。這使該控件可用于該頁的繼承的 Control.Controls 屬性。在以下示例中,建立 MyUserControl.ascx 的執行個體并将其 BackColor 屬性設定為 beige。

    [C#]Control c1 = LoadControl("MyUserControl.ascx");

    ((MyUserControl)c1).BackColor = "beige";

    Page.Controls.Add(c1);

    [Visual Basic]Dim c1 As UserControl = LoadControl("MyUserControl.ascx")

    CType(c1, MyUserControl).BackColor = "beige"

    Page.Controls.Add(c1)

    注意 當您使用 Add 方法将控件添加到 ControlCollection 對象時,這些控件将按處理順序放置在集合中。如果您希望将控件添加到集合中的特定位置,請使用 AddAt 方法并指定您要存儲該控件的索引位置。

位址:

ms-help://MS.VSCC/MS.MSDNVS.2052/cpguide/html/cpconinstantiatingusercontrolsprogrammatically.htm

鴻雪示例:

注: 本方法是我同僚李強原創

步驟一: 把ascx控件拖入設計視窗,然後轉入html模式,保留定義

如果你需要多個ascx的話,請全部拖入。

但是把相應的内容删除。(因為我們需要動态加載)

在需要填入控件的地方,放個容器,比如td,并設定在伺服器端運作

    <TD  id="tdpan" runat=server></TD>

2:動态調用

UserControl myusercontrol = (UserControl) LoadControl ("../includes/pageNavigater.ascx") ;

            Type myusertype = myusercontrol.GetType();

//下面是給ascx指派

            PropertyInfo  myuserinfo1 = myusertype.GetProperty("RelatedDatagrid");//) .GetProperty("RelatedDatagrid");

            myuserinfo1.SetValue(myusercontrol,gridhwcy  ,null);

            PropertyInfo  mypassinfo = myusertype.GetProperty("torefresh");

            mypassinfo.SetValue(myusercontrol,true,null );

            PropertyInfo  myuserdatasource = myusertype.GetProperty("RelatedDataSource");

            myuserdatasource.SetValue(myusercontrol,dv,null);

            tdpan.Controls.Clear();

            tdpan.Controls.Add(myusercontrol);

如果還有什麼不明白,請和  [email protected] 聯系          

​​http://www.dev-club.com/club/bbs/showAnnounce.asp?id=1506069​​     

ASP.net中動态加載使用者控件

  UserControl control = (_pager.LoadControl(String.Format("~/WebUC/{0}.ascx", _ctrlId))) as UserControl;

  control.ID = "uc_" + _ctrlId;

  _panelControl.Controls.Add(control);

ASP.net中動态加載使用者控件時一些問題的總結

經常見到有人說在ASP.net中不要使用動态控件,我想主要的原因在于使用動态控件會帶來一些問題,在做項目的過程中,我将由動态加載控件引發的總是作了一個小小的總結。

1、在使用LoadControl加載控件後,使用者控件中的某些控件不再響應事件。

這個問題主要是由于将控件加載放在if (!Page.IsPostBack)之内引起的,放在外面即可。在思歸的blog上對此問題進行了詳細的說明。

2、使用者控件中某些控件的響應出現問題,如某個按鈕第一次選擇時不觸發CLICK事件,第二次可以了。

這是由于沒有給控件設定ID引起的,控件ID的作用在下面詳細講述。 如 

  Control userControl=(Control)Page.LoadControl(“Test.ascx”);

  userControl.ID=“Test”;

  AddControl(userControl);

3、如果使用者控件中包括DataGrid控件,那麼加載控件後可能出現不響應DataGrid事件的問題。

這好像是一個bug,必須要将加載的控件進行強制轉換,如:

  Test userControl=(Test)Page.LoadControl(“Test.ascx”); 

注意:上面使用的是Test類型,而不是Control!

我在以前的Blog中曾提到過這個問題,這種方式将使系統的擴充性降低。 我有一個解決方案可以和大家讨論(運用政策模式):

  public class BaseControl : System.Web.UI.UserControl

  {

    public virtual BaseControl ProcessThisControl();

  }

所有的使用者控件從BaseControl 繼承,如果有Datagrid控件,由overide ProcessThisControl方法,如:

  return this as Test;

按如下方式加載控件:

  BaseControl userControl=(BaseControl )Page.LoadControl(“Test.ascx”);

userControl.ProcessThisControl();

4、在使用者控件中如何使用JavaScript

大家都知道,使用用戶端的腳本将大大提高頁面的響應速度,同時可以避免頻繁地重新整理頁面。是以使用javascript來實作頁面中部分控制是一個比較好的方式,但是在使用者控件中如果通路某一個子控件呢?

使用方式如下:

  document.all.<%= TestControl.ClientID%><%= lstUser.ClientID%>.disabled=true;     //将TestControl設定為不可用

如果在C#腳本中應該這樣寫:

  Page.RegisterStartupScript("OnInitControl","<SCRIPT LANGUAGE='JavaScript'>document.all.Test_TestControl.disabled=true;</SCRIPT>");   //Test為使用者控件,TestControl為使用者控件中的子控件。

現在說一下控件ID,在通路aspx檔案時,IIS會将aspx的腳本進行編譯。編譯的時候将使用者控件中的内容寫在同一個頁面中,為了防止頁面中的控件與使用者控件中的控件名稱相同,在編譯的時候對使用者控件中的控件名稱修改為 :   使用者控件名:子控件 ,控件ID則修改為 使用者控件ID_子控件ID。在動态加載控件時,如果不對控件的ID進行指派,則控件ID為上一次加載的控件ID,是以在加載使用者控件後應該立即對其設定ID。

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace CatChen.Cocollab.Web.UI.Controls
{
    public class ViewPanel : System.Web.UI.Control, System.Web.UI.INamingContainer
    {
        private string _virtualPath;
        private Control _view;

        public string VirtualPath
        {
            get { return this._virtualPath; }
            set
            {
                string oldValue = this._virtualPath;
                this._virtualPath = value;
                if (this.Page != null && value != oldValue)
                {
                    this.ChildControlsCreated = false;
                    this.EnsureChildControls();
                }
            }
        }
        public Control View
        {
            get { return this._view; }
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (!string.IsNullOrEmpty(this.VirtualPath))
            {
                this.EnsureChildControls();
            }
        }

        protected override void LoadViewState(object savedState)
        {
            Pair pair = savedState as Pair;
            if (pair != null)
            {
                base.LoadViewState(pair.First);
                this.VirtualPath = pair.Second as string;
            }
        }

        protected override void CreateChildControls()
        {
            this.Controls.Clear();

            if (string.IsNullOrEmpty(this.VirtualPath))
            {
                return;
            }

            if (this.Page == null)
            {
                throw new Exception("ViewPanel.Page is null.");
            }

            this._view = this.Page.LoadControl(this.VirtualPath);
            if (this._view == null)
            {
                throw new Exception("ViewVirtualPath cannot be loaded.");
            }

            this._view.ID = "ucView";
            this.ClearChildState();
            this.Controls.Add(this._view);
        }

        protected override object SaveViewState()
        {
            return new Pair(base.SaveViewState(), this.VirtualPath);
        }
    }
}