Loading UserControl Dynamically in UpdatePanel 【transfer]
来源:互联网 发布:淘宝网官网电脑版登录 编辑:程序博客网 时间:2024/06/05 01:11
http://geekswithblogs.net/rashid/archive/2007/08/11/Loading-UserControl-Dynamically-in-UpdatePanel.aspx
In this post, I will show you how to load different user control in UpdatePanel from different menu item click. I have found a lot of request in Asp.net Ajax Forum and some of them are having misconception about this. Once you complete reading this post you will be able to load controls dynamically and learn how to employ different helper controls like UpdateProgress, ModalPopupExtender while the UserControl is loading. First let us create plain page without the ajax support:
Markup:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="PlainSampleMenu.aspx.cs" Inherits="PlainSampleMenuPage" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" ><head runat="server"> <title>Plain Sample Menu</title></head><body> <form id="form1" runat="server"> <asp:Menu ID="Menu1" runat="server" OnMenuItemClick="Menu1_MenuItemClick"> <Items> <asp:MenuItem Text="File"> <asp:MenuItem Text="Load Control1"></asp:MenuItem> <asp:MenuItem Text="Load Control2"></asp:MenuItem> <asp:MenuItem Text="Load Control3"></asp:MenuItem> </asp:MenuItem> </Items> </asp:Menu> <br /> <br /> <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder> </form></body></html>
Code Behind:
using System;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;public partial class PlainSampleMenuPage : System.Web.UI.Page{ private const string BASE_PATH = "~/DynamicControlLoading/"; private string LastLoadedControl { get { return ViewState["LastLoaded"] as string; } set { ViewState["LastLoaded"] = value; } } private void LoadUserControl() { string controlPath = LastLoadedControl; if (!string.IsNullOrEmpty(controlPath)) { PlaceHolder1.Controls.Clear(); UserControl uc = (UserControl)LoadControl(controlPath); PlaceHolder1.Controls.Add(uc); } } protected void Page_Load(object sender, EventArgs e) { LoadUserControl(); } protected void Menu1_MenuItemClick(object sender, MenuEventArgs e) { MenuItem menu = e.Item; string controlPath = string.Empty; switch (menu.Text) { case "Load Control2": controlPath = BASE_PATH + "SampleControl2.ascx"; break; case "Load Control3": controlPath = BASE_PATH + "SampleControl3.ascx"; break; default: controlPath = BASE_PATH + "SampleControl1.ascx"; break; } LastLoadedControl = controlPath; LoadUserControl(); }}
As you can see we are loading the UserControls in the PlaceHolder Control on different menu item click. If you are wondering why I am also loading the controls in Page Load event based upon the ViewState, the reason is otherwise those dynamically loaded controls will not be visible in the consequent postbacks. There are few good articles written by Scott Mitchell on dynamically loading Controls which you will find in the following links:
- Dynamic Controls in ASP.NET
- Working with Dynamically Created Controls
- Dynamic Web Controls, Postbacks, and View State
Now let us ajaxify this page, lets wrap the PlaceHolder with an UpdatePanel control. The following shows the markup:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SampleMenu1.aspx.cs" Inherits="SampleMenuPage1" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" ><head runat="server"> <title>Sample Menu</title></head><body> <form id="form1" runat="server"> <asp:Menu ID="Menu1" runat="server" OnMenuItemClick="Menu1_MenuItemClick"> <Items> <asp:MenuItem Text="File"> <asp:MenuItem Text="Load Control1"></asp:MenuItem> <asp:MenuItem Text="Load Control2"></asp:MenuItem> <asp:MenuItem Text="Load Control3"></asp:MenuItem> </asp:MenuItem> </Items> </asp:Menu> <br /> <br /> <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Menu1" /> </Triggers> </asp:UpdatePanel> </form></body></html>
Since the Menu control resides outside the UpdatePanel we will also need a AsyncPostBackTrigger for the Menu Control. Now run this page, you will find the controls are loaded without a full postback.
Now let us further enhance this page with UpdateProgress and AjaxControlToolKit's ModalPopupExtender. First with the UpdateProgress Control.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SampleMenu1.aspx.cs" Inherits="SampleMenuPage1" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" ><head runat="server"> <title>Sample Menu - UpdateProgress</title></head><body> <form id="form1" runat="server"> <asp:Menu ID="Menu1" runat="server" OnMenuItemClick="Menu1_MenuItemClick"> <Items> <asp:MenuItem Text="File"> <asp:MenuItem Text="Load Control1"></asp:MenuItem> <asp:MenuItem Text="Load Control2"></asp:MenuItem> <asp:MenuItem Text="Load Control3"></asp:MenuItem> </asp:MenuItem> </Items> </asp:Menu> <br /> <br /> <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1"> <ProgressTemplate> Loading.... </ProgressTemplate> </asp:UpdateProgress> <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Menu1" /> </Triggers> </asp:UpdatePanel> </form></body></html>
As you can see we have added a UpdateProgress Control in the UpdatePanel ContentTemplate. But the UpdateProgress does not get visible when you click any of the menu item. This is the true nature of UpdatePanel, it does not shows the UpdateProgress if the control is out side the UpdatePanel which caused the postback. We have to manually show the UpdateProgress by the JavaScript code like the following:
<script type="text/javascript"> var prm = Sys.WebForms.PageRequestManager.getInstance(); prm.add_initializeRequest(initializeRequest); prm.add_endRequest(endRequest); var _postBackElement; function initializeRequest(sender, e) { if (prm.get_isInAsyncPostBack()) { e.set_cancel(true); } _postBackElement = e.get_postBackElement(); if (_postBackElement.id.indexOf('Menu1') > -1) { $get('UpdateProgress1').style.display = 'block'; } } function endRequest(sender, e) { if (_postBackElement.id.indexOf('Menu1') > -1) { $get('UpdateProgress1').style.display = 'none'; } }</script>
Now run the page, you will find the UpdateProgress Control is showing the loading message no matter which control caused the postback.
In this final section we will implement the AjaxControlToolKit's ModalPopupExtender to show the loading message, this will give you a similar look of CodePlex Site. The following shows the source:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SampleMenu2.aspx.cs" Inherits="SampleMenuPage2" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" ><head runat="server"> <title>Sample Menu - ModalPopupExtender</title> <style type="text/css"> .modalBackground { background-color:#dcdcdc; filter:alpha(opacity=60); opacity:0.60; } </style></head><body> <form id="form1" runat="server"> <asp:Menu ID="Menu1" runat="server" OnMenuItemClick="Menu1_MenuItemClick"> <Items> <asp:MenuItem Text="File"> <asp:MenuItem Text="Load Control1"></asp:MenuItem> <asp:MenuItem Text="Load Control2"></asp:MenuItem> <asp:MenuItem Text="Load Control3"></asp:MenuItem> </asp:MenuItem> </Items> </asp:Menu> <br /> <br /> <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Menu1" /> </Triggers> </asp:UpdatePanel> <asp:Panel ID="Panel1" runat="server" style="background-color:#ffffff;display:none;width:400px"> <div style="padding:8px"> <h2>Loading...</h2> </div> </asp:Panel> <ajaxToolKit:ModalPopupExtender ID="ModalPopupExtender1" runat="server" TargetControlID="Panel1" PopupControlID="Panel1" BackgroundCssClass="modalBackground" DropShadow="true" /> <script type="text/javascript"> var prm = Sys.WebForms.PageRequestManager.getInstance(); prm.add_initializeRequest(initializeRequest); prm.add_endRequest(endRequest); var _postBackElement; function initializeRequest(sender, e) { if (prm.get_isInAsyncPostBack()) { e.set_cancel(true); } _postBackElement = e.get_postBackElement(); if (_postBackElement.id.indexOf('Menu1') > -1) { $find('ModalPopupExtender1').show(); } } function endRequest(sender, e) { if (_postBackElement.id.indexOf('Menu1') > -1) { $find('ModalPopupExtender1').hide(); } } </script> </form></body></html>
As you can see we first created a custom style which will be shown as the background style when the modal popup is visible, next we have added a regular Asp.net Panel control which will be shown as the modal popup. We have initially set the Panel control display mode to none, so there will be no flicker when the modal popup is shown. At last, we have added a ModalPopupExtender and sets its required property. The previous rule also applies here, we have to manually show/hide the ModalPopup which we are doing in the above JavaScript code. You will also found few cool techniques of ModalPopupExtender in this link.
To run the sample first create a AjaxControlToolKit enable site website then create a folder DynamicControlLoading folder and copy the files in the following attachment.
Download: Complete Source
- Loading UserControl Dynamically in UpdatePanel 【transfer]
- Loading an ASP.NET Page Class dynamically in an HttpHandler
- ModuleManager and IModuleInfo - loading Flex Modules dynamically
- ModuleManager and IModuleInfo - loading Flex Modules dynamically
- Dynamically filled ListView in QML
- Dynamically loading an external JavaScript or CSS file
- An Application Program Dynamically Loading and Linking the Shared Library
- must re-compile ng element for loading html content dynamically
- Dynamically Loading Controllers and Views with AngularJS/$controllerProvider and RequireJS
- Creating and deleting threads dynamically in eCos
- create enum type dynamically(in runtime)
- Dynamically Change Record Group in Form
- set view margin in code dynamically
- Dynamically inflates UI in Android App
- usercontrol!
- dynamically changing delay in gr_delay (or history in any gr_block)
- Lazy Loading In AngularJS
- Lazy Loading In AngularJS
- 检测点16.2
- xml validation(五)
- 测试工程师的任务
- 数字信号处理中为什么要加窗
- doxygen相关问题
- Loading UserControl Dynamically in UpdatePanel 【transfer]
- 人的一生会遇到四个人!
- 标签的用法
- 关于CString总结(转) CString好用但太容易出错了
- The.Ten.Commandments.-摩西十戒
- 页面传值问题(转)
- VC自定义消息的发送与接收的方法实现
- Sun 存储模拟器的使用
- IO:cin.clear() 和 cin.sync() 的区别