ASP.NET动态修改控制树

我试图删除并动态添加控件到我的控制树。 例如:

在特定情况下,我打电话给:

private void resetPanel() { Panel.Controls.Clear(); Panel.Controls.Add(Image); Panel.Controls.Add(HiddenField); } 

我的主要目标是如何让所添加的控件在回发中持续存在?

当我使用文本框和标题调用另一个类似的函数时,它会完美地存在。 但是,对于图像,它会丢失其URL和属性。

我知道要保持动态控件,你必须在Init上添加它,你必须负责控制树,因此需要在每次回发时将动态控件添加到树中。

那么为什么它适用于文本框和标签在post后面保持不变但是你不能对图像和隐藏字段进行控制添加?

谢谢,Brian

– 更新和解决方案 –

我在我的代码中发现了一个错误,并且HiddenField值在后备文件中保持不变。 我选择的解决方案是使用ViewState保存值,然后在每个post上恢复我的动态控件。

– 编辑 –

感谢您的回复,因为我的问题可能有更好的解决方案,这里有一些代码可以显示我如何调用该方法以及为什么需要。

  public void resetTitlePanel() { // Restylize the panel to initial state TitlePanel.Controls.Clear(); TitlePanel.BorderColor = System.Drawing.Color.Maroon; TitlePanel.BorderStyle = BorderStyle.Dashed; TitlePanel.Enabled = true; // Set the new control properties to initial state Label TitleLabel = new Label(); TitleLabel.ID = "TitleLabel"; TextBox TitleTxtBox = new TextBox(); TitleTxtBox.ID = "TitleTxtBox"; // Add the new controls to the container TitlePanel.Controls.Add(TitleLabel); TitlePanel.Controls.Add(TitleTxtBox); // Set the reference of this to the new dynamic control this.TitleLabel = TitleLabel; this.TitleTxtBox = TitleTxtBox; } public void resetImagePanel() { // Restylize the panel to initial state ImagePanel.Controls.Clear(); ImagePanel.BorderColor = System.Drawing.Color.Blue; ImagePanel.BorderStyle = BorderStyle.Dashed; ImagePanel.HorizontalAlign = HorizontalAlign.NotSet; // Set the new control properties to initial state Image AddImage = new Image(); AddImage.ImageUrl = "~/Resources/Icons/picture_add.png"; AddImage.ID = "AddImage"; HiddenField HiddenImage = new HiddenField(); HiddenImage.ID = "HiddenImage"; // Add the new controls to the container ImagePanel.Controls.Add(AddImage); ImagePanel.Controls.Add(HiddenImage); // Set the reference of this to the new dynamic control this.AddImage = AddImage; this.HiddenImage = HiddenImage; } 

通话方式:

 private void copyFromSlide(TemplateControl destination, Template source) { // Reset the template destination.resetTitlePanel(); destination.resetImagePanel(); destination.Title = source.Title; // Find the path from the database and assign it to the control destination.ImagePath = modData.getImagePath((int)source.ImageID); } 

所以…我明白代码很复杂,可能比它应该更多。 此外,我只是一个初学者,所以质量可能更差,我为此道歉。

主要说明是:

  • 有2个用户控件相互交互。
  • 这完全正常!IsPostback。
  • ViewStateEnable在默认情况下为true,即使我明确指定它,我得到相同的结果。
  • 这完全适用于由标签和文本框组成的标题面板,两者都保留其值。
  • 我知道我将静态和动态控件混合在一起。 我习惯了C,所以我不确定是否可以将对象指针移动到新的动态对象。

问题是,在分配图像路径时,该值不会保留在回发上。

我需要删除并重新添加控件,因为在特定条件下,我将删除控件并添加标签,如上所述,没有问题。 我之所以认为我不需要再次初始化控件,是因为我正在添加到一个有根的面板,如下所示:

http://weblogs.asp.net/infinitiesloop/archive/2006/08/30/TRULY-Understanding-Dynamic-Controls-_2800_Part-3_2900_.aspx

我希望这会增加一些清晰度。

再次感谢,

布赖恩

触发InitComplete事件之前,ViewState不会跟踪更改。 如果您在此之前进行更改并将它们存储在ViewState中(例如在Init中),则这些更改将不会生成新的视图状态键。 Init应该用于从viewstate重建您的控件。 Init事件之后的事件是您应该在视图状态中为这些控件设置新值,以便它们将被保留。

回答您的第二个问题:Image和HiddenField控件不响应任何事件(例如,单击事件),因此不需要重建。 这就是为什么你看到TextBox和Label控件与Image和HiddenField控件之间的不同行为。

可以更容易地存储确定何时在页面视图状态中添加和删除这些控件的数据,并且只是在每个页面加载时重新创建控件。

您是否在这些控件上启用了ViewState?

您可以在此处查看本文档“备注”部分中的一些内容

您需要做的是在OnLoad()发生之前(通常在OnInit()上)始终将所有控件添加到页面(或用户控件)中。

这是因为ASP.NET在OnLoad()上从ViewState或Request.Form加载控件值。

事实上,在回发之间没有任何“控件”被持久化,它只是在ViewState或Request.Form中回发之间保留的控件值。 (如果它们是以标记或动态方式添加的),如上所述,唯一重要的是控件在OnLoad()之前添加到页面中。

我应该添加即使你在OnLoad后添加你的元素你仍然可以读取控件的值(在回发中),如下所示:

 Request.Form[txtName.UniqueID] 

有关ASP.NET中控件生命周期的更多信息,请参阅此处;

http://msdn.microsoft.com/en-us/library/ms178472.aspx