Search code examples
c#asp.netlistviewlistviewitemselecteditemtemplate

Programmatically Select Item in Asp.Net ListView


After doing a quick search I can't find the answer to this seemingly simple thing to do.

How do I Manually Select An Item in an Asp.Net ListView?

I have a SelectedItemTemplate, but I don't want to use an asp:button or asp:LinkButton to select an item. I want it to be done from a URL. Like a QueryString, for example.

The way I imagine would be on ItemDataBound, check a condition and then set it to selected if true, but how do I do this?

For example:

protected void lv_ItemDataBound(object sender, ListViewItemEventArgs e) {

  using (ListViewDataItem dataItem = (ListViewDataItem)e.Item) {

     if (dataItem != null) {
        if( /* item select condition */ ) {   

            // What do I do here to Set this Item to be Selected?
            // edit: Here's the solution I'm using :
            ((ListView)sender).SelectedIndex = dataItem.DisplayIndex;

            // Note, I get here and it gets set
            // but the SelectedItemTemplate isn't applied!!!

        }
     }
  }
}

I'm sure it's one or two lines of code.

EDIT: I've updated the code to reflect the solution, and it seems that I can select the ListView's SelectedItemIndex, however, it's not actually rendering the SelectedItemTemplate. I don't know if I should be doing this in the ItemDataBound event as suggested below.


Solution

  • I looked at some of what's going on in ListView under the hood and think this is probably the best approach.

    void listView_ItemCreated(object sender, ListViewItemEventArgs e)
    {
        // exit if we have already selected an item; This is mainly helpful for
        // postbacks, and will also serve to stop processing once we've found our
        // key; Optionally we could remove the ItemCreated event from the ListView 
        // here instead of just returning.
        if ( listView.SelectedIndex > -1 ) return; 
    
        ListViewDataItem item = e.Item as ListViewDataItem;
        // check to see if the item is the one we want to select (arbitrary) just return true if you want it selected
        if (DoSelectDataItem(item)==true)
        {
            // setting the SelectedIndex is all we really need to do unless 
            // we want to change the template the item will use to render;
            listView.SelectedIndex = item.DisplayIndex;
            if ( listView.SelectedItemTemplate != null )
            {
                // Unfortunately ListView has already a selected a template to use;
                // so clear that out
                e.Item.Controls.Clear();
                // intantiate the SelectedItemTemplate in our item;
                // ListView will DataBind it for us later after ItemCreated has finished!
                listView.SelectedItemTemplate.InstantiateIn(e.Item);
            }
        }
    }
    
    bool DoSelectDataItem(ListViewDataItem item)
    {
        return item.DisplayIndex == 0; // selects the first item in the list (this is just an example after all; keeping it simple :D )
    }
    

    NOTES

    • ListView selects the template an item will use after it's DataBinding event fires. So if the SelectedIndex is set before then, no more work is necessary
    • Setting the SelectedIndex anywhere after DataBinding works, you just don't get the SelectedItemTemplate. For that you have either rebind the data; or reinstantiate the SelectedItemTemplate on the ListViewItem. be sure to clear the ListViewItem.Controls collection first!

    UPDATE I have removed most of my original solution, since this should work better and for more cases.