动态加载用户控件事件订阅

本文关键字:事件 控件 加载 用户 动态 | 更新日期: 2023-09-27 18:01:42

我很难订阅动态加载的用户控件中的事件。可能最简单的方法就是查看我遇到问题的代码。如有任何帮助,不胜感激。

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

 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行。

再次感谢您的协助。

动态加载用户控件事件订阅

解决方案#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;
    }
}

然后在用户控件中动态创建和订阅updatepparent事件:

// 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方法:

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);

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