2010-02-12 2 views
6

У меня проблема с ViewState. У меня есть страница aspx с деревом слева и UpdatePanel с панелью ASP.NET внутри справа. Именно в этой внутренней панели я загружаю и выгружаю динамически пользовательские элементы управления. Я использую эту панель обновления для загрузки динамических элементов управления.переменная Viewstate, потерянная при пользовательском управлении, динамически загружается

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

При первом загрузке пользовательского элемента управления я вызываю его конструктор с параметрами. Когда я перезагружаю этот пользовательский элемент управления при каждой обратной передаче, я использую его обычный конструктор.

Моя проблема в том, что значения, которые я сохранил на ViewState, стали нулевыми при последующей обратной передаче.

Update:

Это часть моего пользовательского элемента управления:

public class MyUserControl : System.Web.UI.UserControl 
{ 
private int PKId 
{ 
    get { return ViewState["pkId"] as int; } 
    set { ViewState["pkId"] = value; } 
} 

public MyUserControl(int pkId) 
{ 
    this.PKId = pkId; 
} 

... 
} 

Я следую за эту статью, чтобы загрузить элементы управления динамически: http://msdn.microsoft.com/en-us/magazine/cc748662.aspx#id0070065.

Второе обновление:
Я также установить один и тот же идентификатор элемента управления, когда я загрузить пользовательский элемент управления в первый раз, и на каждом reaload.

Возможно, я могу использовать другой метод для хранения этих значений, таких как ввод скрытых полей или кеша. Я выбрал ViewState, потому что я не хочу перегружать сервер с помощью значений Session для каждого пользователя.

Третье обновление:

I load the controls with this code: 

System.Web.UI.UserControl baseControl = LoadControl(ucUrl) as System.Web.UI.UserControl; 
if (baseControl != null) 
{ 
    baseControl.ID = "DestinationUserControl"; 
    PanelDestination.Controls.Add(baseControl); 
} 

И reaload с этим кодом:

DynamicControls.CreateDestination ud = this.LoadControl(TrackedUserControl) as DynamicControls.CreateDestination; 
if (ud != null) 
{ 
    ud.ID = "DestinationUserControl"; 
    PanelDestination.Controls.Add(ud); 
} 

Что происходит?

+0

Пожалуйста, предоставьте часть кода, который делает это, чтобы мы могли лучше понять, что происходит. –

+0

Я обновил вопрос. – VansFannel

+0

Почему вы вводите его как UserControl в начальной загрузке и как CreateDestination при повторной загрузке? –

ответ

3

Попробуйте сохранить элемент управления в локальной переменной после его загрузки/сборки до его добавления в иерархию управления. Это позволяет отображать данные ViewState из и в элемент управления. См. «Правило 2» здесь http://chiragrdarji.wordpress.com/2009/05/20/maintain-viewstate-for-dynamic-controls-across-the-postback/.

+0

Я установил одинаковый идентификатор в обоих случаях, и он не работает. – VansFannel

+1

А, ок. Мой ответ обновлен. Это должно сделать это. –

+0

Возможно, я не понимаю ваш ответ, но я делаю так, как правило 2. Я обновил свой вопрос более подробно. – VansFannel

0

Динамическое добавление элементов управления в UpdatePanel - такая плохая идея. Это порождает столько проблем.

Если возможно, переместите создание динамического управления из UpdatePanel, и я верю, что ваша проблема будет решена.

+0

Мне очень жаль. Я ошибаюсь. Это UpdatePanel с панелью ASP.NET внутри. Именно в этой внутренней панели я загружаю и выгружаю динамически пользовательские элементы управления. – VansFannel

3

Когда вы загружаете пользовательский элемент управления? Это должно произойти в событии Init, если вы хотите сохранить/восстановить ViewState.

+0

Пользовательский элемент управления имеет текстовое поле. Если у них есть текст, он правильно восстанавливается при обратных передачах. Я перезагружаю пользовательский элемент управления на событии Page_Load. Я следую этой статье, чтобы динамически загружать элементы управления: http://msdn.microsoft.com/en-us/magazine/cc748662.aspx#id0070065 – VansFannel

+2

Если в этой статье говорится о загрузке динамических элементов управления в Page_Load, это просто неправильно. Это будет работать в некоторых случаях, но, конечно, не все, как вы обнаружили. Восстановление ViewState происходит до Page_Load, и поэтому ваша переменная имеет значение null. Нет простого способа объяснить это. – Bryan

0

Как указано Bryan, вы должны загрузить свои динамические элементы управления в Page_Init, а не в Page_Load.

Поскольку this description of the Page Life Cycle объясняет, что к моменту возникновения события Page_Load состояние представления из обратной передачи уже обработано (в PreLoad). Если элементы управления еще не перезагружены, состояние представления некуда.

PreLoad:

Используйте это событие, если вам необходимо выполнить обработку на странице или управления до события Load.

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

+0

Возможно, я могу использовать другой метод для хранения этих значений, таких как ввод скрытых полей или кеша. Я выбрал ViewState, потому что я не хочу перегружать сервер. – VansFannel

+0

Элементы управления могут быть динамически добавлены в postback в событии Load, и в это время их жизненный цикл «догонит» к текущему событию. См. «Уловные события для добавленных элементов управления» здесь http://msdn.microsoft.com/en-us/library/ms178472.aspx и пошаговое руководство № 6 здесь http://www.codeproject.com/KB/aspnet/ aspnetviewstatepagecycle.aspx # Пошаговое руководство (которое отлично иллюстрирует разницу в поведении до и после добавления элемента управления в иерархию). –

+0

@gWiz, хотя прохождение игры №6 интересно, в зависимости от событий «догоняющего» в лучшем случае проблематично. Даже сам поход говорит: «Рекомендуется добавлять динамические элементы управления во время событий« PreInit »или« Init ». Вот что я предлагаю @VansFannel. –

Смежные вопросы