扩展DropDownList控件

时间:2010-04-18 00:01:53

标签: asp.net custom-controls

我有一个相当大的应用程序,它有几百个带有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"));
    }
}

1 个答案:

答案 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,那么它基本上是无操作。