Разрешение конфликтов состояния / пространства имен
У меня есть элемент управления списком. Когда пользователь щелкает по нему, он говорит пользовательскому элементу управления использовать определенный идентификатор для использования.
Пользовательский элемент управления рисует одну и ту же вещь каждый раз (динамически), просто загружает разное содержимое в зависимости от этого идентификатора (он загружается из базы данных в динамическую форму, такую как элемент управления).
Хорошо, теперь у меня проблемы с утечкой из состояния. Когда вы щелкнете по списку для загрузки, скажем, ID #1, все будет хорошо выглядеть. Затем вы нажимаете на ID #2, и все элементы управления textbox, созданные внутри пользовательского элемента управления, имеют то же самое, что было вставлено в ID #1. Поэтому, когда меняется индекс списка, мне нужно очистить состояние просмотра, но я не могу заставить это работать.
Все элементы управления также создаются в Page_Load.
Я попытался ViewState.Clear() в Page_Load, но это ничего не сделало.
У меня был пользовательский элемент управления, производный от INamingInterface, но я думаю, идентификаторы все еще совпадают для viewstate.
Я попытался изменить идентификатор пользовательского элемента управления на что-то уникальное (например, "CONROL_"+id.ToString()). Я также попытался сделать то же самое с панелью, содержащей пользовательский элемент управления.
Я не могу избавиться от этого состояния зрения!
РЕДАКТИРОВАТЬ ОК, вот код, который демонстрирует проблему
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (ddl.SelectedValue == "1")
{
Create("ID #1");
}
else if (ddl.SelectedValue == "2")
{
Create("ID #2");
}
}
void Create(string text)
{
TextBox t = new TextBox();
t.Text = text;
pnl.Controls.Add(t);
}
}
разметка:
<div>
<asp:Panel ID="pnl" runat="server">
<asp:DropDownList ID="ddl" runat="server" AutoPostBack="True">
<asp:ListItem Text="id 1" Value="1">
</asp:ListItem>
<asp:ListItem Text="id 2" Value="2"></asp:ListItem>
</asp:DropDownList>
</asp:Panel>
</div>
Если вы запустите этот код, вы заметите, что если вы измените то, что находится в текстовом поле, а затем измените раскрывающийся список, то то, что вы ввели ранее, будет сохранено вместо того, чтобы перезаписываться.
Моя основная цель в этом заключается в том, чтобы при смене идентификатора №2 он вставлял "текст №2" в текстовое поле, несмотря ни на что (желательно без полного отключения представления)
3 ответа
Если я установлю идентификатор элемента управления Text, тогда он не сохранит старое значение. Вы даете всем элементам управления уникальный идентификатор?
void Create(string text)
{
TextBox t = new TextBox();
t.ID = text;
t.Text = text;
pnl.Controls.Add(t);
}
Вы не можете сделать это таким образом.
Для корректной работы viewstate все элементы управления должны быть созданы до его загрузки и с одинаковыми идентификаторами. Таким образом, вы должны сохранить определения элементов управления в сеансе и затем воссоздать их с теми же идентификаторами в ASP.NET, чтобы загрузить их свойства из состояния представления. Page_load слишком поздно, сделайте это в PreLoad.
Но проще создать все элементы управления во время разработки с видимым значением false и чередовать их видимость, чтобы представление состояния работало правильно.
На самом деле это больше не актуально. Мы исправили это, просто отключив viewstate для наших динамически создаваемых элементов управления. Это не будет работать во всех случаях, но в нашем случае есть две кнопки, которые пользователь может нажимать (которые связаны с динамическими элементами управления), или поле со списком для переключения форм. Обе кнопки сохраняют состояние элементов управления в базе данных, поэтому viewstate на самом деле не нужен (я всегда запутываюсь, когда думаю о viewstate и о том, как он взаимодействует с элементами управления..)
Итак, основной совет: если у вас возникли проблемы с контролем состояния, убедитесь, что оно действительно вам нужно.