Asp.net 在页面加载之外加载控件是否?

Asp.net 在页面加载之外加载控件是否?,asp.net,dynamic,controls,render,lifecycle,Asp.net,Dynamic,Controls,Render,Lifecycle,我提前为发表如此冗长的问题表示歉意。信不信由你,你在这里看到的实际上是手头问题/代码的一个相当浓缩的版本。虽然我希望有人能给我指点更好或不同的方法,但我也非常想弄清楚这一点,这样我就可以在晚上睡觉了:) 我遇到了在不同的aspx页面之间传递确认消息的要求。我选择不使用查询字符串变量,因为查询字符串值“是”粘性的(即它们在所有后续回发中都会持续存在),我不想在这一点上添加一堆条件逻辑 无论如何,我提出了一个非常简单的类,它使用会话将通知与特定URL关联。然后,我钩住母版页page\u Load事件

我提前为发表如此冗长的问题表示歉意。信不信由你,你在这里看到的实际上是手头问题/代码的一个相当浓缩的版本。虽然我希望有人能给我指点更好或不同的方法,但我也非常想弄清楚这一点,这样我就可以在晚上睡觉了:)

我遇到了在不同的aspx页面之间传递确认消息的要求。我选择不使用查询字符串变量,因为查询字符串值“是”粘性的(即它们在所有后续回发中都会持续存在),我不想在这一点上添加一堆条件逻辑

无论如何,我提出了一个非常简单的类,它使用会话将通知与特定URL关联。然后,我钩住母版页page\u Load事件来查询此类,以查找应为当前URL显示的任何通知。如果找到,它将动态加载NotificationMessage用户控件并显示消息内容

当尝试在不同的aspx页面之间传递通知时,一切正常。可以预见的是,当内容页试图向其自身添加通知时(即“您输入的数据无效,请重试”),事情就不起作用了。原因很清楚:当内容页为自己添加通知时,母版页的页面加载事件已经触发,因此在页面生命周期中做任何事情都为时已晚。相关代码粘贴在下面

    public class MyMasterPage:MasterPage{

    protected void Page_Load(object sender, EventArgs e)
    {
        LoadNotifications(this.Request.Url.ToString());
    }


    private void LoadNotifications(string url)
    {
        //look for a notification
        Notification? notification = NotificationManager.Instance.RetrieveNotification(url);

        //there are no notifications, nothing to see here 
        if (!notification.HasValue)
        {
            return;
        }

        //there is a Notification for this url, so load it into a user control
        NotificationMessage notificationMessageControl = (NotificationMessage)LoadControl("~/App_UserControls/NotificationMessage.ascx");
        notificationMessageControl.ID = "notificationMessage";
        notificationMessageControl.Notification = notification;
        notificationMessageControl.Visible = true;

        //find the placeholder on the master page
        PlaceHolder placeHolder = (PlaceHolder)PageUtils.FindControlRecursive(this, "NotificationPlaceholder");

        if (placeHolder == null)
        {
            throw new ApplicationException("NotificationPlaceholder control not found.");
        }

        //insert into control
        placeHolder.Controls.Add(notificationMessageControl);
        placeHolder.Visible = true;

        //remove the notification so it doesn't show up next time
        NotificationManager.Instance.RemoveNotification(url);


    }

}
考虑到上面提到的发布生命周期,我修改了NotificationManager类,这样每当为当前页面添加通知时,它都会引发一个事件。母版页截取该事件,如果page\u Load已经触发,它将重新启动LoadNotifications方法

 //bind the event on the page constructor
    public MyMasterPage()
    {
        NotificationManager.Instance.NotificationAdded += this.NotificationAdded;

    }

    private void NotificationAdded(string forUrl)
    {
        if (_pageLoaded){
           LoadNotifications(forUrl);
        }
    }
不幸的是,这不起作用。我已经多次阅读了这段代码,尽管母版页加载NotificationMessage UserControl并将其添加到适当的占位符中,但最终的aspx HTML从不包含该UserControl的标记。我已经在UserControl的页面加载中放置了断点,并验证了它们确实在执行过程中被命中

如果我从内容页内部动态加载UserControl并完全绕过母版页,则它会顺利呈现:

public partial class MyContentPage:Page
{

    public void DoSomethingCool(object sender, EventArgs e)
    {
        if (MyServiceLayer.Save(foo)==false){
            Notification notification = new Notification(NotificationType.Error, "We’re sorry, your document was not saved.");
            NotificationMessage notificationMessage = (NotificationMessage)LoadControl("~/App_UserControls/NotificationMessage.ascx");
            notificationMessage.Notification = notification;
            notificationMessage.Visible = true;
            PlaceHolder holder = (PlaceHolder)PageUtils.FindControlRecursive(this, "NotificationPlaceholder");
            holder.Controls.Add(notificationMessage);
        }
    }
}
作为记录,我去掉了UserControl的动态加载,而是在母版页标记中选择了静态声明,并对控件的Visible属性进行了基于代码的切换;还是没有骰子


如果有人能解释一下这个难题,我将不胜感激。

我以前尝试过这类事情,但从未完全适应过。我所做的是将我的ASCX放在每一页(或母版页)上,让ASCX控制它的状态,而不是让ASPX控制我的ASCX


不过,我不确定这是否会对你的情况有所帮助。

我以前尝试过这种方法,但从未完全适应过。我所做的是将我的ASCX放在每一页(或母版页)上,让ASCX控制它的状态,而不是让ASPX控制我的ASCX


不过,我不确定这是否会对您的情况有所帮助。

您似乎希望在控制事件触发后显示您的信息。您可以考虑让这些消息聚合,直到所有控件事件都被触发,然后在 OnPrimeNe/Cuff>中从您的<代码> NoTrimeCudioMeals<代码>中取出所有消息,而不是<代码> pGeaLoad 。这样,您就可以消除可能使事情复杂化的事件(如
NotificationAdded
)等

不过,问题并不是100%。了解母版页实际上是页面上的控件有时会有所帮助,而不是像您所想的那样。它将受到页面上任何控件的限制


嗯,安德森看来你想在你的控制事件发生后显示你的信息。您可以考虑让这些消息聚合,直到所有控件事件都被触发,然后在 OnPrimeNe/Cuff>中从您的<代码> NoTrimeCudioMeals<代码>中取出所有消息,而不是<代码> pGeaLoad 。这样,您就可以消除可能使事情复杂化的事件(如
NotificationAdded
)等

不过,问题并不是100%。了解母版页实际上是页面上的控件有时会有所帮助,而不是像您所想的那样。它将受到页面上任何控件的限制


嗯,安德森听起来很有趣。你能举例说明吗?听起来很有趣。你能举例说明一下吗?