Как я могу повторно инстанцировать динамических пользовательских элементов управления ASP.NET, не используя базу данных?

Я использую diff-buffer-with-file и выбираю файл, что буфер прибыл из (который является значением по умолчанию так или иначе для команды... просто хит входит).

можно также использовать режим изменений выделения, хотя это не отследит изменения, пока Вы не включите его, таким образом, не настолько полезный, если Вы хотите видеть то, что изменилось, когда Вы закрываете файл, который не был в этом режиме:-)

5
задан Shog9 24 August 2009 в 18:39
поделиться

2 ответа

Вы можете сохранить минимум того, что вам нужно знать для воссоздания элементов управления в коллекции, хранящейся в сеансе. Сеанс доступен на этапах инициализации страницы.

Вот вам пример. Он состоит из:

Default.aspx, cs
- панель для хранения пользовательских элементов управления
- «Добавить кнопку управления», которая будет добавлять пользовательский элемент управления при каждом нажатии

TimeTeller.ascx, cs
- имеет метод SetTime, который устанавливает метку элемента управления на указанное время.

Default.aspx

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

<!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></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Panel ID="pnlDynamicControls" runat="server">
        </asp:Panel>
        <br />
        <asp:Button ID="btnAddControl" runat="server" Text="Add User Control" 
            onclick="btnAddControl_Click" />
    </div>
    </form>
</body>
</html>

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<string, string> 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<string, string>();
            Session["myControlList"] = myControlList;
         }
         else 
         {
            myControlList = (Dictionary<string, string>)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" %>
<asp:Label ID="lblTime" runat="server"/>

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();
      }
   }
}  

Как видите, мне все еще нужно управлять внутренним состоянием просмотра моего пользовательского элемента управления, но пакет состояний просмотра сохраняется на странице и передается обратно элементу управления при обратной передаче. Думаю, важно отметить, что мое решение очень близко к решению Дэвида. Единственное существенное отличие в моем примере заключается в том, что для хранения управляющей информации используется сеанс вместо состояния просмотра. Это позволяет событиям происходить на этапе инициализации. Важно отметить, что это решение требует больше ресурсов сервера, поэтому оно может не подходить в некоторых ситуациях в зависимости от вашей стратегии масштабирования.

3
ответ дан 14 December 2019 в 08:56
поделиться

Я делал это раньше. Мне не приходилось делать это со времен .NET 1.1, но принципал удаляет то же самое.

Я сделал это на Page_Load, а не Init, мне пришлось перезагрузить элементы управления, которые вы создали в последнем цикле страниц.

Сначала вам необходимо отслеживать элементы управления, созданные вами для каждого цикла страницы. Это включает тип, имя и т. Д. .

Затем при каждой загрузке страницы вам необходимо перестраивать их.

Вы делаете это, воссоздавая элемент управления, присваивая ему тот же самый идентификатор, добавляя его в место sampe на странице и, наконец, в ViewState [ "LoadedControl"] к типу элемента управления.

Вот код, который я использовал, я сделал это только с пользовательскими элементами управления, которые я создал. Я не пробовал это с элементом управления ASP.NET, но думаю, что это будет работать так же.

В этом случае у меня есть ArrayList из триплетов (имейте в виду, что это .NET 1.1), и первым элементом был идентификатор PageView. Возможно, вам это не понадобится для вашего приложения.

protected void Page_Load(object sender, System.EventArgs e)
{
    //**********************************************************
    //*  dynCtlArray will hold a triplet with the PageViewID,  *
    //*  ControlID, and the Control Name                       *
    //**********************************************************

    ArrayList dynCtlArray = (ArrayList)this.ViewState["dynCtlArray"];
    if (dynCtlArray != null)
    {

        foreach (object obj in dynCtlArray)
        {
            Triplet ctrlInfo = (Triplet)obj;

            DynamicLoadControl(ctrlInfo);
        }
    }
}

private void DynamicLoadControl(Triplet ctrlInfo)
{
    // ERROR HANDLING REMOVED FOR ANSWER BECAUSE IT IS NOT IMPORTANT YOU SHOULD HANDLE ERRORS IN THIS METHOD

    Control ctrl = this.LoadControl(Request.ApplicationPath
        + "/UC/" + (string)ctrlInfo.Third);

    ctrl.ID = (string)ctrlInfo.Second;

    // Create New PageView Item
    Telerik.WebControls.PageView pvItem = this.RadMultiPage1.PageViews[(int)ctrlInfo.First];
    pvItem.Controls.Add(ctrl);

    /******************************************************
     *  The ControlName must be preserved to track the    *
     *  currently loaded control                          *
     * ****************************************************/
    ViewState["LoadedControl"] = (string)ctrlInfo.Third;
}
private void RegisterDynControl(Triplet trip)
{
    ArrayList dynCtlArray = (ArrayList)this.ViewState["dynCtlArray"];

    if (dynCtlArray == null)
    {
        dynCtlArray = new ArrayList();
        this.ViewState.Add("dynCtlArray", dynCtlArray);
    }

    dynCtlArray.Add(trip);

}

В некоторых методах на вашей странице

// Create new Control
Control ctrl = Page.LoadControl("../UC/MyUserControl.ascx");

// . . . snip .. . 

// Create Triplet
Triplet ctrlInfo = new Triplet(0, ctrl.ID, "MyUserControl.ascx");
// RegisterDynControl to ViewState
RegisterDynControl(ctrlInfo);

// . . . snip .. . 

Чтобы получить доступ к элементам управления для сохранения информации, вам нужно будет выполнить this.Page.FindControl ('');

3
ответ дан 14 December 2019 в 08:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: