必须在每次回发时重建控制树,包括部分回发 - 或者让它通过 ControlState/ViewState 重建。在这种情况下,在随后的回发中,Items 集合不会被重建(或被清除)并且在 Render 阶段是空的。
对于这样的情况,我会这样处理:
- 在 RadioButtonList 上启用 ViewState并确保在 Load 1之前添加它,或者;
- 将适当集合的 ViewState 存储在容器控件上,然后 DataBind 消费控件 - 请参阅GenericDataSourceControl以了解设置它的干净方法。我更喜欢这种方法,因为它一致、可预测且易于控制。
1这应该有效,但可能无效。我通常对哪些控件真正支持 ViewState 以及在何种程度上使用总是让我觉得......不一致感到困惑。在任何情况下,如果 ViewState 被禁用,它将不起作用- 请记住,禁用页面(或父控件)的 ViewState 会一直禁用 ViewState。此外,必须在适当的时间将控件加载到控件树中,并使用相同的控件路径/ID(通常是 Init 或 Load),以便它与请求 ViewState 一起正确运行。
#2的粗略想法:
将视图状态保存在包含的用户控件中(必须为此控件启用 ViewState):
// ListItem is appropriately serializable and works well for
// automatic binding to various list controls.
List<ListItem> Names {
// May return null
get { return (List<ListItem>)ViewState["names"]; }
set { ViewState["names"] = value; }
}
在 GenericDataSourceControl 中(将 GDS 放入标记中,以便它有一个不错的 ID)选择事件:
void SelectEvent(sender e, GenericSelectArgs args) {
args.SetData(Names);
}
动态添加 RadioButtonList(例如,在 中Control.OnLoad
):
// Unless this NEEDS to be dynamic, move it into the declarative markup.
// The dynamic control must be added to the *same location* it was before the
// postback or there will be ugly invalid control tree creation exceptions.
var radioList = new RadioButtonList();
someControl.Controls.Add(radioList);
// To minimize problem with Control Tree creation this should be unique and
// consistent for dynamic controls.
radioList.ID = "radioList";
// Binding to the DS "declarative" usually works better I've found
radioList.DataSourceID = "idOfTheGDS";
// You -may- need to DataBind, depending upon a few factors - I will usually call
// DataBind in PreRender, but generally in the Load is OK/preferred.
// If it already binds, don't call it manually.
radioList.DataBind();
如果 DataBinding 工作正常,那么应该可以禁用RadioButtonList 的 ViewState .. 但有时在应该使用 ControlState 时使用 ViewState,因此请确保它按需要运行。