0

我正在尝试将搜索功能添加到将向下滚动到正在搜索的项目的 ListBox。

我有一个绑定到 ObservableCollection 的 ListBox,我用一堆 RecipeNameDTO 对象填充了该列表框。我可以通过简单的搜索轻松地在 Items 集合中找到一个对象。

string searchItem = tbSearchString.Text;
var recipenameitem = lbRecipeNames.Items.Cast<DTO.RecipeNameDTO>().Where(u => u.RecipeName.ToLower().Contains(searchItem.ToLower())).FirstOrDefault();

我可以用这种方法重复地找到项目。

但是,如果我随后尝试使用 ContainerFromItem 查找对象的容器,则该方法将返回 null,除非在执行该方法时该对象在 ListBox 中可见:

ListBoxItem lbi = (ListBoxItem)lbRecipeNames.ItemContainerGenerator.ContainerFromItem(recipenameitem);

我确定(我认为)在执行 ContainerFromItem 之前实际对象存在于 ItemsCollection 中,因为我使用了我在本文开头记录的搜索的非空结果。此外,我可以向下滚动 ListBox 并找到我正在搜索的对象。

它必须与 ListBox 缓存 ItemsCollection 中的对象的方式有关,这会阻止 ContainerFromItem 返回容器。我的代码是否有修复(或对问题的理解)?

迈克尔

4

1 回答 1

0

我接受了 Andy 的建议并设置了我的 ListBox IsSynchronizedWithCurrent = True ,然后使用以下代码设置当前项目并将其滚动到视图中:

    string searchItem = tbSearchString.Text;

    CollectionViewSource cvs = (CollectionViewSource)this.FindResource("cvsRecipeName");
    ObservableCollection<DTO.RecipeNameDTO> itemsCollection = (ObservableCollection<DTO.RecipeNameDTO>)cvs.Source;

    List<DTO.RecipeNameDTO> recipenameitems = itemsCollection.Where(u => u.RecipeName.ToLower().Contains(searchItem.ToLower())).ToList();
    if (recipenameitems.Count > 0) { cvs.View.MoveCurrentTo(recipenameitems[0]);}

    lbRecipeNames.ScrollIntoView(lbRecipeNames.SelectedItem);

我确信我可以修改它以使其更灵活,但这是第一个修复。

于 2019-02-09T13:22:04.877 回答