ASP.NET:UserControl中隐藏的页面中的CheckBox在再次可见时不会保持检查状态

时间:2011-07-05 21:02:44

标签: asp.net user-controls viewstate

这是设置。我有一个启用了viewstate的ASP.NET4页面,带有2个单选按钮的RadioButtonList,一个CheckBox和一个包含的UserControl。如果选择了一个单选按钮,我想隐藏CheckBox,如果选择了另一个单选按钮,则显示它。我希望CheckBox在隐藏和重新显示时保持它的状态;如果在隐藏之前检查过,当它再次显示时,我仍然希望它被检查。

根据选择的单选按钮,显示/隐藏CheckBox的代码存在于UserControl的OnPreRender事件中。所以它使用Parent.FindControl()来获取控件,然后根据RadioButtonList的状态隐藏/显示CheckBox。

问题是,当在UserControl的OnPreRender()中执行此逻辑时,复选框在隐藏后不会保持其状态,然后重新显示。也就是说,如果选中该复选框,则单击单选按钮将其隐藏,当我单击其他单选按钮时,我希望在现在显示复选框时仍然选中该复选框。我有一种感觉,我不理解一些视图状态机制,但当我尝试添加一个TextBox并隐藏/显示它时,它确实按照预期维护了它的文本值。

我可以将逻辑移动到UserControl的Page_Load,并且复选框状态按预期运行。但是我试图让它在OnPreRender()中运行,或者至少寻找一个解释为什么我看到这种行为。

在default.aspx中:

 <asp:RadioButtonList runat="server" ID="uxRadio" AutoPostBack="true">
        <asp:ListItem Text="choice 1" Value="1"></asp:ListItem>
        <asp:ListItem Text="choice 2" Value="2"></asp:ListItem>
        <asp:ListItem Text="choice 3" Value="3"></asp:ListItem>
    </asp:RadioButtonList>
    <asp:CheckBox runat="server" ID="uxCheck" AutoPostBack="true" />
    <uc1:Control ID="uxControl" runat="server"></uc1:Control>

UserControl.ascx.cs:

protected override void OnPreRender(EventArgs e)
{
   RadioButtonList rb = (RadioButtonList)Parent.FindControl("uxRadio");
   CheckBox cb = (CheckBox)Parent.FindControl("uxCheck");

   if (rb.SelectedValue == "2")
   {
       cb.Visible = false;
   }
   else
   {
       cb.Visible = true;
   }
   base.OnPreRender(e);
 }

1 个答案:

答案 0 :(得分:1)

好的,我可以重现这个问题,但我不能100%确定为什么不保留ViewState。

我认为会发生类似这样的事情:

ASP.NET从发布的请求中检索CheckBoxes中的checked-state,但前提是它在服务器端是可见的(否则它甚至不会呈现为html)。如果它不可见,它将从ViewState获取检查状态。

我认为UserControl的PreRender在这种情况下为时已晚。 ASP.NET不知道它必须在ViewState中保存此值,因为之后更改了条件(Visible-State)。因此,没有发布值且没有ViewState值,ASP.NET必须使用默认状态(未选中)。

如果将此代码从PreRender移至Page_Load,则可以正常工作。

但我强烈建议将它移到页面本身,因为它真的属于那里。用户控件不应该坚持在其页面中存在特定控件,因为它也应该在其他页面中工作。

相关问题