Программно выбрать элемент в Asp.Net ListView - PullRequest
6 голосов
/ 20 февраля 2009

После быстрого поиска я не могу найти ответ на эту, казалось бы, простую вещь.

Как вручную выбрать элемент в Asp.Net ListView?

У меня есть SelectedItemTemplate, но я не хочу использовать asp: button или asp: LinkButton для выбора элемента. Я хочу, чтобы это было сделано с URL. Например, как QueryString.

То, как я представляю, будет на ItemDataBound, проверить условие и затем установить его в значение selected, если оно истинно, но как мне это сделать?

Например:

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!!!

        }
     }
  }
}

Я уверен, что это одна или две строки кода.

РЕДАКТИРОВАТЬ: Я обновил код, чтобы отразить решение, и кажется, что я могу выбрать SelectedItemIndex ListView, однако на самом деле это не визуализация SelectedItemTemplate. Я не знаю, следует ли мне делать это в событии ItemDataBound , как предлагается ниже .

Ответы [ 4 ]

13 голосов
/ 20 февраля 2009

Я посмотрел на то, что происходит в ListView, и думаю, что это, вероятно, лучший подход.

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 )
}

ПРИМЕЧАНИЯ

  • ListView выбирает шаблон, который элемент будет использовать после срабатывания события DataBinding. Поэтому, если SelectedIndex установлен до этого, больше не нужно работать
  • Установка SelectedIndex в любом месте после того, как DataBinding работает, вы просто не получаете SelectedItemTemplate. Для этого вам нужно либо перепроверить данные; или повторно создайте шаблон SelectedItemTemplate в ListViewItem. Обязательно сначала очистите коллекцию ListViewItem.Controls!

ОБНОВЛЕНИЕ Я удалил большую часть своего исходного решения, так как это должно работать лучше и для большего количества случаев.

5 голосов
/ 20 февраля 2009

Вы можете установить ListViews SelectedIndex

list.SelectedIndex = dataItem.DisplayIndex; // don't know which index you need
list.SelectedIndex = dataItem.DataItemIndex; 

Обновление

Если вы загружаете данные при загрузке страницы, вам может потребоваться просмотреть данные, чтобы найти индекс, а затем установить значение SelectedIndex перед вызовом метода DataBind ().

public void Page_Load(object sender, EventArgs e)
{
  var myData = MyDataSource.GetPeople();
  list.DataSource = myData;
  list.SelectedIndex = myData.FirstIndexOf(p => p.Name.Equals("Bob", StringComparison.InvariantCultureIgnoreCase));
  list.DataBind();
}


public static class EnumerableExtensions
{
    public static int FirstIndexOf<T>(this IEnumerable<T> source, Predicate<T> predicate)
    {
        int count = 0;
        foreach(var item in source)
        {
            if (predicate(item))
                return count;
            count++;
        }
        return -1;
    }
}
3 голосов
/ 20 февраля 2009
list.SelectedIndex = list.Items.IndexOf(item);
2 голосов
/ 20 февраля 2009

Расширяя ответы @Jeremy и @ bendewey, вам не нужно делать это в ItemDataBound. Вам нужно только, чтобы привязка ListView уже имела место перед установкой SelectedValue. Вы должны быть в состоянии сделать это во время PreRender. См. Эту страницу жизненного цикла документы для получения дополнительной информации о том, когда имеет место привязка.

...