无限制地显示和隐藏Web表单的各个部分,以避免ViewState加载问题

时间:2012-01-07 15:45:28

标签: asp.net viewstate failed-to-load-viewstate

问题

我有一个网络表单,我想隐藏并显示一些面板。当我说“Panel”时,我不是指Panel控件,而只是html中的一个窗格(通常由DIV表示)。

我希望按照我的意愿显示和隐藏这些面板......没有限制意味着不一定只有一个窗格必须是可见的,也可以是2,3或4个。

通常我是通过以下方式实现的:

<div id="mypane1" runat="server">
  ...
</div>
<div id="mypane2" runat="server">
  ...
</div>
<div id="mypane3" runat="server">
  ...
</div>

和此:

this.mypane1.Visible = true;
this.mypane2.Visible = false;
this.mypane3.Visible = true;

不幸的是,这些面板包含控件,其中一些不会从头开始显示(第一个Web表单加载,所以当没有PostBack发生时)。这会导致ViewState加载出现问题。

关于ViewState加载

当然,很多人会明白我的ViewState这些问题。好吧,简而言之,问题是:ViewState加载错误并不容易管理,但最后我能理解以下内容。

让我们说:

<!-- In .aspx -->
<div id="mypane1" runat="server">
  ...
  <asp:Literal ID="..." runat="server" ...></asp:Literal>
  <asp:TextBox ID="..." runat="server" ...></asp:TextBox>
  ...
</div>
<div id="mypane2" runat="server">
  ...
  <asp:LinkButton ID="lb1" OnClick="lb1_Click" runat="server" ...></asp:LinkButton>
  <asp:LinkButton ID="lb2" OnClick="lb2_Click" runat="server" ...></asp:LinkButton>
  <asp:LinkButton ID="lb3" OnClick="lb3_Click" runat="server" ...></asp:LinkButton>
  ...
</div>
<div id="mypane3" runat="server">
  ...
  <asp:TextBox ID="..." runat="server" ...></asp:TextBox>
  <asp:LinkButton ID="lb4" OnClick="lb4_Click" runat="server" ...></asp:LinkButton>
  <asp:TextBox ID="..." runat="server" ...></asp:TextBox>
  ...
</div>

// In .aspx.cs
protected void Page_Load(...) {
  if (!this.IsPostBack) {
    this.mypane1.Visible = true;
    this.mypane2.Visible = false;
    this.mypane3.Visible = true;
  }
}

/// ... In the page many happens and the panes are shown and hidden ... ///

// Event Handlers
protected void lb1_Click(object sender, EventArgs e) {
  ...
}
protected void lb2_Click(object sender, EventArgs e) {
  ...
}
protected void lb3_Click(object sender, EventArgs e) {
  ...
}
protected void lb4_Click(object sender, EventArgs e) {
  ...
}

问题是如下。

  • 在开始时,不显示pane2。

  • 在显示某些操作后,会显示pane2并显示其控件。

  • 用户点击lb1 - &gt; ViewState error

请注意,与pane2控件关联的每个事件都会发生相同的情况。是否按下lb4,没问题。

问题在于,开始层次结构由窗格1和3中的控件表示。当控件引发事件时,如果发现初始层次结构ViewState不一致(因为我在{{1}上操作)通常HtmlControls更聪明,并且可以在控件添加到其中时管理更好的ViewState。)

可行的solutoions

请注意,我只需执行以下操作即可隐藏和显示面板:

ServerControls

这不是我想要做的事情,原因有两个:

  • 我希望窗格不会被渲染为Html。

  • 我想使用服务器控件。

请求

我需要使用网页控件来管理我的面板管理,我无法使用this.mypane2.Attributes.Add("display", "none"); 因为控件层次结构未正确加载。

我尝试了HtmlControl和View控件,但它们只允许我使用一个活动视图。我该怎么办?

注意:请不要过分关注MultiView问题,这只是一个很好的设计让你知道会发生什么,我唯一的兴趣是找到一种方法来隐藏和显示使用服务器控件的窗格

三江源

3 个答案:

答案 0 :(得分:1)

我假设将面板的visiblity设置为false会导致不将孩子添加到ViewState或以某种方式干扰它。这是对的吗?

考虑到这一点,如果您希望在.Net渲染引擎中使用控件但是对最终用户隐藏,您可以尝试使用css显示和隐藏它们,即

显示

pnlDemo.Attributes.Add("style", "display:block");

<强>隐藏

pnlDemo.Attributes.Add("style", "display:none");

我遇到了一种情况,我需要ASP.Net控件来实现ViewState,但没有显示。在适当的时候,我会使用JQuery显示它们,这种方法适用于该场景,因此它可能适用于您的。

答案 1 :(得分:1)

您是否尝试过使用ViewStateModeByIdAttribute

  

ViewStateModeByIdAttribute类用于指定需要按ID加载视图状态的控件。默认的视图状态加载行为是ASP.NET通过页面控制树中的索引加载控件的视图状态信息。按ID加载视图状态信息会产生性能成本,因为在加载视图状态信息之前必须专门搜索页面控制树。

答案 2 :(得分:0)

您是否尝试过使用page.RegisterStartupScript。 脚本将在页面加载结束时加载,因此控件将具有其viewstate。 编写能够隐藏面板ID的JavaScript代码。将CSS更改为隐藏的可见性而不显示无。

要在其上显示面板的另一个asp按钮。  您可以在按钮的ClientClick事件上编写JavaScript代码,以更改面板的CSS以更改其可见性。