【问题标题】:How do I wire an ascx event from a dynamically loaded ascx page into the aspx page...?如何将 ascx 事件从动态加载的 ascx 页面连接到 aspx 页面...?
【发布时间】:2013-09-08 14:49:10
【问题描述】:

这段代码在我的 ASPX 页面中。下面显示的 sn-p 用于根据用户在 ASPX 页面上所做的某些选择来动态加载用户控件。

    protected void loadUserControl(string tmUCName)
    {
        phDetail.Controls.Clear();
        ViewState["vsControl"] = null;
        UserControl tmUControl = LoadControl(tmUCName) as UserControl;
        tmUControl.ID = "ucidControl";
        phDetail.Controls.Add(tmUControl);
        ViewState["vsControl"] = tmUCName;
    }

ASCX 有效,ASCX 页面上的 SELECT 事件也有效。我的问题是从 ASCX 页面上的选择事件中获取值到 ASPX 页面。由于用户控件 (ASCX) 是动态加载的(基于 ASPX 页面上的某些选择),我发现很难将事件从 ASCX 连接到 ASPX 页面。在明确的负载情况下,我没有任何问题......一切都很漂亮......

对于它的价值,如果页面被显式加载,例如:

PlaceHolder1.Controls.Clear();
WebUserControlTest02 = LoadControl(@"~\WebUserControl2.ascx") as WebUserControl2;
WebUserControlTest02.gvASCX02SelectedIndexChanged += new EventHandler (WebUserControlTest02_gvASCX02SelectedIndexChanged);
PlaceHolder1.Controls.Add(WebUserControlTest02);

在 ASPX 和 ASCX 页面之间连接事件没有任何问题。

【问题讨论】:

    标签: c# asp.net user-controls


    【解决方案1】:

    编辑:问题和答案分为两部分。第一部分是如何"bubble" 发生在UserControl 内部的控件上的事件。这是通过处理内部控件的事件然后在UserControl 本身上触发类似事件来完成的。在这种情况下,UserControl's 事件与内部控件的事件共享相同的名称和签名。这不是必需的,但在这种情况下这样做是有意义的。

    第二部分是如何动态加载UserControls,但仍让包含网页连接到每个UserControl 类上定义的冒泡事件。问题是 ASP.NET UserControl 类本身没有定义事件,而动态加载的 UserControls 的唯一共同点是它们都是 UserControl 类型。 这个问题也可以通过让所有UserControls 实现一个定义事件的通用接口来解决。通过将UserControl 变量转换为接口类型,您可以访问接口定义的事件。并且到时候可以挂接网页来处理事件。

    这两个部分一起允许源自ListBox 控件的事件由包含ListBoxUserControl 重复,并允许动态加载UserControl 的网页侦听并响应相同的事件。


    首先定义一个你想要处理的事件的接口:

    public interface IMyUserControl
    {
        event EventHandler SelectedIndexChanged;
    
    }
    

    接下来,让您的每个 UserControl 实现此事件并连接列表框的 SelectedIndexChanged 事件:

    public partial class WebUserControl1 : System.Web.UI.UserControl, IMyUserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            ListBox1.SelectedIndexChanged += (o, args) =>
            {
                var selectedIndexChanged = SelectedIndexChanged;
                if (selectedIndexChanged != null)
                    selectedIndexChanged(o, args);
            };
        }
    
        public event EventHandler SelectedIndexChanged;
    }
    

    现在在您的通用代码中,将 UserControl 转换为接口类型和 viola,您可以访问事件:

    protected void loadUserControl(string tmUCName)
    {
        phDetail.Controls.Clear();
        ViewState["vsControl"] = null;
        UserControl tmUControl = LoadControl(tmUCName) as UserControl;
        tmUControl.ID = "ucidControl";
        phDetail.Controls.Add(tmUControl);
        ViewState["vsControl"] = tmUCName;
        ((IMyUserControl)tmUControl).SelectedIndexChanged += OnUserControlSelectedIndexChanged
    }
    
    private void OnUserControlSelectedIndexChanged(object sender, EventArgs args)
    {
        // ...
    }
    

    【讨论】:

    • 感谢基思,感谢您的反馈。我想我已经掌握了窍门,但我有点困惑。在您描述的界面示例中-“SelectedIndexChanged”是控制事件还是事件处理程序名称?我尝试给事件起一个合理的名称,但它拒绝在 ASCX 中公开。请求详细说明界面,以及它与 ASCX 的关系。
    • 基思,我还没有达到标记你的回复的水平,所以现在我的评论是...... :)
    • SelectedIndexChanged 是控制事件。 UserControl 正在处理由 ListBox(位于 UserControl 内部)引发的 SelectedIndexChanged 事件并将其“冒泡”到网页。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多