开发者

Can ASP.NET dropdownlist control persist list item classes on postback?

I have a dropdownlist control on a page with AutoPostBack set to True. On the initial load of the page I am setting a CSS class on certain ListItems in the DropDownList. The resulting HTML looks like this:

<select id="mySelect">
    <option value="1">First</option>
    <option value="2" selected="selected">Second</option>
    <option value="3" class="favorite">Third</option>
    <option value="4">Fourth</option>
    <option value="5" class="favorite">Fifth</option>
</select>

After postback the ListItems lose their CSS classes. It now looks like this.

<select id="mySelect">
    <option value="1">First</option>
    <option value="2">Second</option>
    <option value="3">Third</option>
    <option value="4">Fourth</option>
    <option value="5" selected="selected">Fifth</option>
</select>

Is there any way that the dropdownlist will remember the CSS classes on individual ListItems after a postback or will I need to somehow set the classes myself after postback?

Here is the code that adds the CSS 开发者_StackOverflow中文版to the dropdownlist. It is run on PageLoad but not run on PostBack.

foreach(MyItem _myItem in MyItemList)
{
   ListItem _listItem = new ListItem();
   _listItem.Value = _myItem.ID.ToString();
   _listItem.Text = _myItem.Title;
   if(_myItem.IsFavorite)
   {
      _list.Attributes["class"] = "favorite";
   }
   ddlMyDropDown.Items.Add(_listItem);
}

Corey


EDIT:

This works for me. Try something like this

    protected void Page_Load(object sender, EventArgs e)
    {
        if(!IsPostBack)
        {
            LoadData();
        } 

        LoadStyle();
    }

    private void LoadData()
    {
        DropDownList1.Items.AddRange(Enumerable.Range(0, 10).Select(x => new ListItem(x.ToString())).ToArray());
    }

    private void LoadStyle()
    {
        foreach (ListItem item in DropDownList1.Items)
        {
            if (int.Parse(item.Value) % 2 == 0)
            {
                item.Attributes.Add("class", "test");
            }
        }
    }


So your problem here is one of state management, and for the most part its your responsibility to manage the state of the items on your page. Consider that this one page may be rendered 100 times in a minute (to 100 different browsers) and each one could have a different state. The server can't keep track of all these different instances and states, you have to do that.

There are two ways to deal with this, the simplest is similar to what @StackOverflowException stated, just make sure that you determine and set your state every time your page is created. This is easier, but definitely not scalable, especially if that involves a lot of database work and other stuff.

The better solution is to create some properties of your own that store things in the pages ViewState. There are a lot of ways to do this, but here's just a quick sample:

protected override OnPageLoad(EventArgs e)
{
    myListBox.Items.AddRange(myListItems);
}

protected IEnumberable<ListItems> myListItems 
{
    get 
    { 
        IEnumberable<ListItems> items = (IEnumerable<ListItems>)ViewState["myListItems"]; 

        // Build the list if we can't get it out of the viewstate
        if(items = null) 
        {
            items = BuildListItems();
            ViewState["myListItems"] = items;
        }

        return _items;          
    }

    set { ViewState["myListItems"] = value; }
}

This would take a bit longer on the initial page view, but during postbacks would (theoretically) be faster because it can get the list out of the page's view state without reconstructing it (basically deserializing it).

The drawback to this method is that your view state, which is output to the browser, can get very large if you put too much data in it.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜