How can I re-instantiate dynamic ASP.NET user controls without using a database?

前端 未结 3 2042
孤城傲影
孤城傲影 2020-12-18 07:55

I\'m currently working with a part of my application that uses Dynamic Web User Controls and I\'m having a bit of trouble figuring out the best way to re-instantiate the con

3条回答
  •  萌比男神i
    2020-12-18 08:51

    You could store the bare minimum of what you need to know to recreate the controls in a collection held in session. Session is available during the init phases of the page.

    Here is an example for you. It consists of:

    Default.aspx, cs
    - panel to store user controls
    - "Add Control Button" which will add a user control each time it is clicked

    TimeTeller.ascx, cs
    - has a method called SetTime which sets a label on the control to a specified time.

    Default.aspx

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DynamicControlTest._Default" %>
    
    
    
    
    
        
    
    
        

    Default.aspx.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace DynamicControlTest
    {
       public partial class _Default : System.Web.UI.Page
       {
          Dictionary myControlList; // ID, Control ascx path
    
          protected void Page_Load(object sender, EventArgs e)
          {
    
          }
    
          protected override void OnInit(EventArgs e)
          {
             base.OnInit(e);
    
             if (!IsPostBack)
             {
                myControlList = new Dictionary();
                Session["myControlList"] = myControlList;
             }
             else 
             {
                myControlList = (Dictionary)Session["myControlList"];
    
                foreach (var registeredControlID in myControlList.Keys) 
                {
                   UserControl controlToAdd = new UserControl();
                   controlToAdd = (UserControl)controlToAdd.LoadControl(myControlList[registeredControlID]);
                   controlToAdd.ID = registeredControlID;
    
                   pnlDynamicControls.Controls.Add(controlToAdd);
                }
             }
          }
    
          protected void btnAddControl_Click(object sender, EventArgs e)
          {
             UserControl controlToAdd = new UserControl();
             controlToAdd = (UserControl)controlToAdd.LoadControl("TimeTeller.ascx");
    
             // Set a value to prove viewstate is working
             ((TimeTeller)controlToAdd).SetTime(DateTime.Now);
             controlToAdd.ID = Guid.NewGuid().ToString(); // does not have to be a guid, just something unique to avoid name collision.
    
             pnlDynamicControls.Controls.Add(controlToAdd);
    
             myControlList.Add(controlToAdd.ID, controlToAdd.AppRelativeVirtualPath);
          }
       }
    }
    

    TimeTeller.ascx

    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TimeTeller.ascx.cs" Inherits="DynamicControlTest.TimeTeller" %>
    
    

    TimeTeller.ascx.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace DynamicControlTest
    {
       public partial class TimeTeller : System.Web.UI.UserControl
       {
          protected void Page_Load(object sender, EventArgs e)
          {
    
          }
    
          public void SetTime(DateTime time) 
          {
             lblTime.Text = time.ToString();
          }
    
          protected override void LoadViewState(object savedState)
          {
             base.LoadViewState(savedState);
             lblTime.Text = (string)ViewState["lblTime"];
          }
    
          protected override object SaveViewState()
          {
             ViewState["lblTime"] = lblTime.Text;
             return base.SaveViewState();
          }
       }
    }  
    

    As you can see, I still have to manage the internal viewstate of my user control, but the viewstate bag is being saved to the page and handed back to the control on postback. I think it is important to note that my solution is very close to David's. The only major difference in my example is that it's using session instead of viewstate to store the control info. This allows things to happen during the initialization phase. It is important to note that this solution takes up more server resources, therefore it may not be appropriate in some situations depending on your scaling strategy.

提交回复
热议问题