开发者

ASP.NET: CheckBox in Page hidden by UserControl does not stay checked when made visible again

Here's the setup. I have an ASP.NET4 Page with viewstate enabled, with a RadioButtonList with 2 radio buttons, a CheckBox, and an included UserControl. I want to hide the CheckBox if one radio button is selected, and show it if the other is selected. I want the CheckBox to maintain it's state when it is hidden and re-shown; if it was checked before hiding, when it is shown again I still want it to be checked.

The twist is that the code to show/hide the CheckBox, based on what radio button is chosen, lives in the OnPreRender event of the UserControl. So it does Parent.FindControl()s to get the controls, then hides/shows the CheckBox based on the state of the RadioButtonList.

The issue is, when doing this logic in OnPreRender() of the UserControl, the checkbox does not maintain its state after it is hidden, then reshown. That is, if the checkbox is checked, then I click the radio button to hide it, when I click the other radio button I want the checkbox to still be checked when it is now shown. I have a feeling I'm not understanding some of the view state mechanisms, but when I tried adding a TextBox and hiding/showing it, it did maintain it's text value as expected.

I can move the logic to Page_Load of the UserControl and the checkbox state behaves as expected. But I'm trying to get it to work in OnPreRender(), or at least looking for an explanation as to why I'm seeing this behavior.

In 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:

开发者_如何学JAVAprotected 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);
 }


Ok, i could reproduce this issue but i'm not 100% sure why the ViewState is not retained.

I assume that something like this happens:

ASP.NET retrieves the checked-state from CheckBoxes from the posted request but only if it's Visible on serverside(otherwise it wouldn't even be rendered as html). If it's invisible it gets the checked-state from ViewState.

I think that the UserControl's PreRender is too late in this case. ASP.NET does not know that it has to save this value in ViewState because the condition(Visible-State) is changed afterwards. Hence there is no posted value and no ViewState value and ASP.NET must use the default-state(unchecked).

If you move this code from PreRender to Page_Load it works.

But i would strongly recommend to move it to the Page itself because it really belongs there. A usercontrol should not insist on the existence of specific controls in it's page because it should also work in other pages.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜