Search code examples
c#.netobservablecollectionselectedindex

ObservableCollection filter Selected Item


I have a problem that I don't know how to solve.

I have a observable collection that I filter the items as I type in a textbox the problem is that when I select the filtered item I get the wrong selected index.

For example I have one item after filtering the real selected index is 2 but because it sets the collection as I type it set the index to one if the only filtered item left is one.

So how do I get the right item selected. Like in the mail application to make my question maybe easier to understand

Here is the selection changed event:

private void searchToDoItemsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (searchToDoItemsListBox.SelectedIndex == -1)
        return;
    NavigationService.Navigate(new Uri("/DetailsPage.xaml?selectedItemSearch=" + searchToDoItemsListBox.SelectedIndex, UriKind.Relative));
    searchToDoItemsListBox.SelectedIndex = -1;
}

And here is for the details page:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    if (NavigationContext.QueryString.TryGetValue("selectedItemSearch", out selectedIndexSearch))
    {
        int indexSearch = int.Parse(selectedIndexSearch);
        DataContext = App.ViewModel.AllToDoItems[indexSearch];
    }

}

Solution

  • Bind to the SelectedItem

    <ListBox SelectedItem="{Binding Selected, Mode=TwoWay}" ItemsSource="Binding={Items}">
    </ListBox>
    

    and you have to fields:

    public ObservableCollection<ItemType> Items {get;set;} //setted while filtering, does it?
    

    and

    private ItemType _selected;
    public ItemType Selected
    {
      get 
      {
        return _selected;
      }
      set 
      { 
         _selected = value;
         //here you can save the item. 
         //For example save the item id, and navigate to DetailsPage
      }
    }
    

    And then, you can get the item from list:

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            if (NavigationContext.QueryString.TryGetValue("selectedItemSearch", out selectedIndexSearch))
            {
                int id = int.Parse(selectedIndexSearch);
                DataContext = GetById(id)
            }
        }
    
      public ItemType GetByIf(id) 
      {
        for(int i = 0; i < App.ViewModel.AllToDoItems.Count; i++)
        {
            if(App.ViewModel.AllToDoItems[i].Id == id) return App.ViewModel.AllToDoItems[i];
        }
        return null;
      }