这是设置。我有一个启用了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);
}
答案 0 :(得分:1)
好的,我可以重现这个问题,但我不能100%确定为什么不保留ViewState。
我认为会发生类似这样的事情:
ASP.NET从发布的请求中检索CheckBoxes中的checked-state,但前提是它在服务器端是可见的(否则它甚至不会呈现为html)。如果它不可见,它将从ViewState获取检查状态。
我认为UserControl的PreRender在这种情况下为时已晚。 ASP.NET不知道它必须在ViewState中保存此值,因为之后更改了条件(Visible-State)。因此,没有发布值且没有ViewState值,ASP.NET必须使用默认状态(未选中)。
如果将此代码从PreRender移至Page_Load,则可以正常工作。
但我强烈建议将它移到页面本身,因为它真的属于那里。用户控件不应该坚持在其页面中存在特定控件,因为它也应该在其他页面中工作。