我很难在动态加载的用户控件中订阅事件。看看我遇到问题的代码可能最简单。非常感谢任何帮助。
在父页面上,我使用此方法动态加载用户控件。
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 :(得分:1)
如果要获得通用解决方案,可以使用属性和事件创建抽象用户控件类。然后MyUserControl1可以从这个抽象用户控件继承。在您的加载方法中,您可以转换为抽象用户控件并以更简单的方式使用它。所以你可以创建一些其他用户控件。
答案 1 :(得分: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方法:
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
但似乎您可能正在考虑加载许多不同类型的用户控件,因此第一个解决方案应该可以正常工作。
关于您对Reflection的关注,请尝试以下方法:
Type type = MyControl.GetType();
EventInfo eventInfo = type.GetEvent("UpdateParent");
EventHandler handler = new EventHandler(HandledEvent);
eventInfo.AddEventHandler(MyControl, handler);