我有一个相当大的应用程序,它有几百个带有Yes / No ListItem的DDL。为了节省一些时间,我创建了一个扩展标准DDL的自定义控件。
这一切似乎都运行正常,但是在代码中分配SelectedValue属性时遇到了一些问题,其中所选值似乎对控件没有影响。我想知道我是否应该在Init或PagePreLoad期间添加我的项目?我应该在添加列表项之前或之后调用base.OnInit吗?这主要是有效但不是100%。 (V3.5)
public class YesNoDropDownList : DropDownList
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!Page.IsPostBack)
{
base.Items.Add(new ListItem("Yes", "YES"));
base.Items.Add(new ListItem("No", "NO"));
}
}
}
我认为问题在于,如果我在Init中加载ListItems,那就是在viewstate建立之前,ListItems在回发时丢失了。如果我在OnLoad中加载它们,那就是在应用SelectedValue之后,如果我设置了SelectedValue,则选择将丢失。我的解决方案是在OnInit覆盖中连接Page InitComplete事件。这有效,但我不确定这是最好的解决方案。
因此,无论是下面详述的Page_InitComplete还是OnInit,我都必须每次加载项目。想法?
protected override void OnInit(EventArgs e)
{
this.Page.InitComplete += new EventHandler(Page_InitComplete);
base.OnInit(e);
}
private void Page_InitComplete(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
base.Items.Add(new ListItem("Yes", "YES"));
base.Items.Add(new ListItem("No", "NO"));
}
}
答案 0 :(得分:0)
我建议在OnInit中添加项目而不是在PreLoad上添加项目,这样你的控件就可以通过状态和适当的设置来启动它的生命。相关的文档(强调我的)
在初始化所有控件并应用任何皮肤设置后触发。单个控件的Init事件发生在页面的Init事件之前 使用此事件来读取或初始化控件属性。
ViewState跟踪也会启用between Init and PreLoad,因此如果控件之前创建了所有选项,那就更好了。
SelectedValue的代码是(谢谢反射器):
set
{
if (this.Items.Count != 0)
{
if ((value == null) || (base.DesignMode && (value.Length == 0)))
{
this.ClearSelection();
return;
}
ListItem item = this.Items.FindByValue(value);
if ((((this.Page != null) && this.Page.IsPostBack) && this._stateLoaded) && (item == null))
{
throw new ArgumentOutOfRangeException("value", SR.GetString("ListControl_SelectionOutOfRange", new object[] { this.ID, "SelectedValue" }));
}
if (item != null)
{
this.ClearSelection();
item.Selected = true;
}
}
this.cachedSelectedValue = value;
}
如果您尝试在填充项目列表之前设置SelectedValue,那么它基本上是无操作。