2014-11-03 90 views
0

我想在用户选择的DropDownList选择的基础上,在运行时动态添加usercontrols到我的页面中的PlaceHolder。事情是这样的:动态用户控件和视图状态 - 我在想什么

protected void Page_Init(object sender, EventArgs e) 
{ 
    //get user's content selection 
    int contentMode; 

    if (!IsPostBack) 
     contentMode = 1; 
    else 
     contentMode = Int32.Parse(Request.Form[ddlMode.UniqueID]); 

    //load a user control 
    ContentControl ucContent = null; 

    switch (contentMode) 
    { 
     case 1: 
      ucContent = LoadControl("~/Controls/SomeContent1.ascx") as ContentControl; 
      break; 
     case 2: 
      ucContent = LoadControl("~/Controls/SomeContent2.ascx") as ContentControl; 
      break; 
    } 

    ucContent.ID = "ucContent"; 

    phContentArea.Controls.Add(ucContent); 
} 

...这几乎工作,但有两个回传后,我得到这样的:

无法加载视图状态。要将视图状态加载到其中的控制树必须与前一个请求期间用于保存视图状态的控制树相匹配。例如,当动态添加控件时,在回发期间添加的控件必须与初始请求期间添加的控件的类型和位置相匹配。

......我读过的内容是由于第二次回复中的控件与之前的回发不同。我试图通过给予控件相同的ID和类型来防止这种情况,但没有骰子。这两个控件:

public partial class SomeContent1 : Foo.Bases.ContentControl 
{ 
    //code 
} 

public partial class SomeContent2 : Foo.Bases.ContentControl 
{ 
    //code 
} 

是否有一部分难题我错过了使这项工作?我读过类似的问题,但是这些建议并不富有成效。

感谢

回答

0

在init事件中,你必须确保控件树调回以前的控件树相匹配;所以如果你删除控件,你需要在init运行后删除它,这是viewstate加载的时候。

此外,初始加载可能需要在PreInit中完成,您可以尝试查看这是否也有帮助。

+0

我没有明确地删除任何控件,但是在上面的Page_Init中,我根据所选列表值加载了不同的控件。在上面的代码中,只有选定项目的UC被加载,其他则不是。这肯定会导致不匹配的视图状态控制树。但我不知道如何解决 - 以上述为模型,我应该做些什么来防止这种情况发生? – mdelvecchio 2014-11-03 23:01:15

+0

是的,这是导致问题的原因。您必须重新加载之前的状态,然后删除旧的控件并添加一个新的控件。从动态角度来看,您可以存储另一个包含当前状态的ViewState变量,在init上加载该变量,然后删除旧的并添加新的以达到正确的状态。或者像你刚刚提到的那样加载所有内容 – 2014-11-03 23:23:51

0

不同的技术,它的工作原理,但是是一个比我的问题不同,是在运行时添加的所有内容的控制,但将非选定的为False的可见性:

switch (contentMode) 
{ 
    case 1: 
     ucContent = LoadControl("~/Controls/SomeContent1.ascx") as ContentControl; 
     phContentArea.Controls.Add(ucContent); 

     ucContent = LoadControl("~/Controls/SomeContent2.ascx") as ContentControl; 
     ucContent.Visible = false; 
     ucContent.EnableViewState = false; 
     phContentArea.Controls.Add(ucContent);  
     break; 

    case 2: 
     ucContent = LoadControl("~/Controls/SomeContent1.ascx") as ContentControl; 
     ucContent.Visible = false; 
     ucContent.EnableViewState = false; 
     phContentArea.Controls.Add(ucContent); 

     ucContent = LoadControl("~/Controls/SomeContent2.ascx") as ContentControl; 
     phContentArea.Controls.Add(ucContent); 
     break; 
} 

...但这并不像加载所需的控件一样好。

+0

我建议,因为动态控制管理是Web表单中的一种痛苦;但是,由于页面上的控件数量多,您将拥有更大的视图状态有效内容。 – 2014-11-03 23:21:03

+0

Visible = False也不会呈现任何标记,因此页面大小相同,但ViewState将保留。 – 2014-11-03 23:24:33

+0

如果不需要,您可以始终在usercontrol实例或其包含的任何子控件上禁用ViewState。 – sh1rts 2014-11-03 23:28:55

相关问题