2011-07-11 21 views
1

動的に読み込まれたユーザーコントロールのイベントを購読するのが非常に苦労しています。おそらく、私が問題を抱えているコードを見るのが最も簡単です。どんな助けでも大歓迎です。動的に読み込まれたユーザーコントロールイベント

親ページでは、このメソッドを使用してユーザーコントロールを動的に読み込みます。

private void LoadMyUserControl(string controlName) 
{ 
     parent.Controls.Clear(); 

     // Load the user Control 
     UserControl MyControl = (UserControl)LoadControl(ControlName); 

     string userControlID = controlName.Split('.')[0]; 
     MyControl.ID = userControlID.Replace("/","").Replace("~", ""); 
     Type ucType = MyControl.GetType(); 

     // Set misc parameters 
     PropertyInfo myProp = ucType.GetProperty("MyProp"); 
     myProp.SetValue(MyControl, "MyVal", null); 

     //Dynamically subscribe to user control event 
     Type objectType = MyControl.GetType(); 
     EventInfo objectEventInfo = objectType.GetEvent("updateParent"); 
     Type objectEventHandlerType = objectEventInfo.EventHandlerType;    
     MethodInfo mi = this.GetType().GetMethod("HandledEvent"); 
     Delegate del = Delegate.CreateDelegate(objectEventHandlerType, this, mi); 
     objectEventInfo.AddEventHandler(this, del); 

    } 

    public void HandledEvent (Object sender, EventArgs e) 
    { 

    } 

私のユーザーコントロールは、この

public partial class MyUserControl1 : System.Web.UI.UserControl 
    { 
     public int MyProp { get; set; } 
     public event EventHandler updateParent; 
    } 

のような単純な公開イベントがあり、私は取得していますエラーが述べObjectEventInfo.AddEventHandlerライン上にある「オブジェクトがターゲットタイプと一致していません。」

お返事ありがとうございます。

+0

は、私はあなたがユーザーコントロール対MyUserControl1にユーザーコントロールをキャストしたいと思います。 –

+2

なぜイベントリフレクションを持つ共通インターフェースIControlを作成し、インターフェースタイプにキャストし、そのように参照できるのでしょうか?このように、複数のUCが署名を満たしていますが、強くタイプされたものを参照することができます... –

+0

私はこれを感謝しますが、私は本当に限られた反射スキルを磨くことを試みています。反射によってこれを行うことはできませんか? – Uproden

答えて

1

解決策1:共通のインターフェイスを作成します。

// IParentControlUpdater.cs 
namespace AspNetUserControlDynamicEvent { 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 

    interface IParentControlUpdater { 
     event EventHandler<EventArgs> UpdateParent; 
    } 
} 

// DynamicUserControl.ascx.cs 
namespace AspNetUserControlDynamicEvent { 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Web; 
    using System.Web.UI; 
    using System.Web.UI.WebControls; 

    public partial class DynamicUserControl : System.Web.UI.UserControl, IParentControlUpdater { 
     protected void Page_Load(object sender, EventArgs e) { } 

     #region IParentControlUpdater Members 

     public event EventHandler<EventArgs> UpdateParent; 

     #endregion 
    } 
} 

// Default.aspx.cs 
namespace AspNetUserControlDynamicEvent { 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Web; 
    using System.Web.UI; 
    using System.Web.UI.WebControls; 

    public partial class _Default : System.Web.UI.Page { 
     protected void Page_Load(object sender, EventArgs e) { } 

     private void LoadMyUserControl(string controlName) { 
      UserControl control = (UserControl)LoadControl(controlName); 

      // Do some stuff 

      ((IParentControlUpdater)control).UpdateParent += new EventHandler<EventArgs>(control_UpdateParent); 
     } 

     private void control_UpdateParent(object sender, EventArgs e) { 
      throw new NotImplementedException(); 
     } 
    } 
} 

溶液#2:基本クラスを作成します。 ベースユーザコントロールクラス(例:DynamicUserControlBase)を作成します。

// DynamicUserControlBase.ascx.cs 
namespace AspNetUserControlDynamicEvent { 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Web; 
    using System.Web.UI; 
    using System.Web.UI.WebControls; 

    public partial class DynamicUserControlBase : System.Web.UI.UserControl { 
     protected void Page_Load(object sender, EventArgs e) { } 

     // Base event 
     public event System.EventHandler<System.EventArgs> UpdateParent; 
    } 
} 

その後、あなたのユーザーコントロールの中であなたが動的にupdateParentイベントを作成し、サブスクライブしたい:

// DynamicUserControl.ascx.cs 
namespace AspNetUserControlDynamicEvent { 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Web; 
    using System.Web.UI; 
    using System.Web.UI.WebControls; 

    public partial class DynamicUserControl : DynamicUserControlBase { 
     protected void Page_Load(object sender, EventArgs e) { } 
    } 
} 

注それはDynamicUserControlBaseから継承方法。さて、あなたのLoadMyUserControl方法のために:あなたがコントロールのみの1種類で作業している場合

private void LoadMyUserControl(string controlName) { 
    DynamicUserControlBase control = (DynamicUserControlBase)LoadControl(controlName); 

    // Do some stuff  

    control.UpdateParent += new EventHandler<EventArgs>(HandledEvent); 
} 

private void HandledEvent(object sender, EventArgs e) { 
    throw new NotImplementedException(); 
} 

しかし、あなたは同じように簡単にLoadControlにボクシングを変更することができます:

WebUserControl1 control = (WebUserControl1)LoadControl(controlName); // example 

しかし、それはあるかのように思えますおそらく多くの異なるタイプのユーザーコントロールをロードすることを検討しているので、最初のソリューションは正常に動作するはずです。

リフレクション経由であなたの懸念については、これを試してみてください。

Type type = MyControl.GetType(); 
EventInfo eventInfo = type.GetEvent("UpdateParent"); 
EventHandler handler = new EventHandler(HandledEvent); 
eventInfo.AddEventHandler(MyControl, handler); 
+0

これはすべて意味があり、助けてくれてありがとうございましたが、好奇心のためにリフレクションを使ってこれを行うことはできませんか?私は本当にここで間違っていることを知ろうとしています。 – Uproden

+0

パフォーマンスが悪いので反射が混乱しているので、私は大雑把な選択肢があるときはそれをお勧めしませんが、学習のために私はコンピュータ(家)の近くにいるときにさらに調べます –

+0

費用がかかります*混乱していません –

1

一般的なソリューションを取得する場合は、プロパティとイベントを使用して抽象的なユーザーコントロールクラスを作成できます。 MyUserControl1は、この抽象的なユーザーコントロールから継承できます。ロードメソッドでは、抽象的なユーザーコントロールにキャストし、簡単な方法で使用することができます。他のユーザーコントロールを作成することもできます。

+0

コードを組み込んだのとまったく同じ方法に答える途中でした。彼のための適切な解決策に見えます。 –

+0

これは非常に一般的だと思います。私は私のコントロールを同じ方法で使用しています。しかし、あなたの努力のためにお金を支払う必要があります;) – ibram

関連する問題