6

快速搜索后,我找不到这个看似简单的事情的答案。

如何在 Asp.Net ListView 中手动选择项目?

我有一个 SelectedItemTemplate,但我不想使用 asp:button 或 asp:LinkBut​​ton 来选择一个项目。我希望从 URL 完成。例如,像 QueryString 一样。

我想象的方式是在 ItemDataBound 上,检查一个条件,然后将其设置为选中(如果为真),但我该怎么做呢?

例如:

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

        }
     }
  }
}

我确定这是一两行代码。

编辑:我更新了代码以反映解决方案,似乎我可以选择 ListView 的 SelectedItemIndex,但是,它实际上并没有呈现 SelectedItemTemplate。我不知道我是否应该按照下面的建议在 ItemDataBound 事件中执行此操作。

4

4 回答 4

13

我查看了引擎盖下 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,则无需进行更多工作
  • 在 DataBinding 工作后的任何位置设置 SelectedIndex,您只是没有获得 SelectedItemTemplate。为此,您要么重新绑定数据;要么 或在 ListViewItem 上重新实例化 SelectedItemTemplate。请务必先清除 ListViewItem.Controls 集合!

更新我已经删除了大部分原始解决方案,因为这应该会更好并且适用于更多情况。

于 2009-02-20T20:26:27.567 回答
5

您可以设置 ListViews SelectedIndex

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

更新

如果您在页面加载时加载数据,您可能必须遍历数据以查找索引,然后在调用 DataBind() 方法之前设置 SelectedIndex 值。

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;
    }
}
于 2009-02-20T18:59:55.107 回答
3
list.SelectedIndex = list.Items.IndexOf(item);
于 2009-02-20T18:59:29.473 回答
2

扩展@Jeremy 和@bendewey 的答案,您不需要在ItemDataBound 中执行此操作。您只需要在设置 SelectedValue 之前已经发生 ListView 绑定。您应该能够在 PreRender 期间执行此操作。有关何时发生绑定的更多信息,请参阅此页面生命周期文档

于 2009-02-20T19:05:56.993 回答