C# 动态加载的用户控件事件订阅

C# 动态加载的用户控件事件订阅,c#,asp.net,user-controls,C#,Asp.net,User Controls,我很难订阅动态加载的用户控件中的事件。可能最简单的方法就是查看我遇到问题的代码。非常感谢您的帮助 在父页面上,我使用此方法动态加载用户控件 private void LoadMyUserControl(string controlName) { parent.Controls.Clear(); // Load the user Control UserControl MyControl = (UserControl)LoadControl(Control

我很难订阅动态加载的用户控件中的事件。可能最简单的方法就是查看我遇到问题的代码。非常感谢您的帮助

在父页面上,我使用此方法动态加载用户控件

 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行中声明“对象与目标类型不匹配”


再次感谢您的帮助。

如果您想获得通用解决方案,可以使用属性和事件创建一个抽象用户控件类。然后MyUserControl1可以从这个抽象用户控件继承。在load方法中,您可以强制转换为抽象用户控件,并以更简单的方式使用它。因此,您可以创建一些其他用户控件。

解决方案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)
  {

  }
// 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();
        }
    }
}
请注意它是如何从DynamicCuserControlBase继承的。现在,对于LoadMyUserControl方法:

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();
}
但似乎您可能正在考虑加载许多不同类型的用户控件,因此第一个解决方案应该可以正常工作

至于您通过反思的担忧,请尝试以下方法:

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

我想您会希望将UserControl强制转换为MyUserControl1而不是UserControl。当您可以创建一个具有事件引用的公共接口IControl,强制转换为接口类型并以这种方式引用它时,为什么要使用反射?通过这种方式,多个UC符合签名,但您可以将其称为强类型…我对此表示感谢,但我确实在努力磨练我有限的反思技能。这是不可能做到这一点,通过反射?是在回答同一方法与代码包含在中间。对他来说似乎是合适的解决办法。我认为这是很常见的。我用同样的方法使用我的控件。但是你需要为你的努力付出代价;)这一切都是有道理的,谢谢您的帮助,但出于好奇,使用反射是否不可能做到这一点?我真的很想知道我在这里做错了什么。反思对于表现来说是杂乱无章的,所以我一般来说。当有明显的替代方案时,不要推荐它,但为了学习,当我靠近一台电脑(家)时,我会进一步研究它,更新底部的答案。
WebUserControl1 control = (WebUserControl1)LoadControl(controlName); // example
Type type = MyControl.GetType();
EventInfo eventInfo = type.GetEvent("UpdateParent");
EventHandler handler = new EventHandler(HandledEvent);
eventInfo.AddEventHandler(MyControl, handler);