Search code examples
c#wpfmvvmlistcollectionview

Navigate to a specific item inside ListCollectionView


I'm trying to navigate to a specific item inside a ListCollectionView based on the value of the Date property of SelectedDay.

VM

private Day _selectedDay;
public Day SelectedDay    // the Name property
{
     get { return _selectedDay; }
     set { _selectedDay = value; RaisePropertyChanged(); }
}

public ObservableCollection<ShootingDay> AllShootingDayInfo {get; set;}

private ListCollectionView _shootingDayInfoList;
public ListCollectionView ShootingDayInfoList
{
    get
    {
        if (_shootingDayInfoList == null)
        {
            _shootingDayInfoList = new ListCollectionView(AllShootingDayInfo);}
            return _shootingDayInfoList;
    }
    set
    {
        _shootingDayInfoList = value; RaisePropertyChanged();
    }
}

The <Day> object has a property of Date and I want that to match with the Date Property in the <ShootingDay> Object so I can navigate to the item in the ShootingDayInfoList where SelectedDay.Date matches Date of Item inside ShootingDayInfoList.

I've tried this but this isn't working since Selected Item is not part of the same object.

ShootingDayInfoList.MoveCurrentTo(SelectedDay.Date);

How can I make this work? I'm very new to all this.


Solution

  • You need Filter predicate to get the needed item, then remove that Filter to bring back all the items back.

    Code

    ViewModel vm = new ViewModel();
    System.Diagnostics.Debug.WriteLine(vm.ShootingDayInfoList.Count.ToString());
    vm.SelectedDay.Date = DateTime.Parse("12/25/2015");
    
    vm.ShootingDayInfoList.Filter = (o) =>
    {
        if (((ShootingDay)o).Date.Equals(vm.SelectedDay.Date))
            return true;
    
        return false;
    };
    
    ShootingDay foundItem = (ShootingDay)vm.ShootingDayInfoList.GetItemAt(0);
    vm.ShootingDayInfoList.Filter = (o) => { return true; };
    
    vm.ShootingDayInfoList.MoveCurrentTo(foundItem); 
    

    I have checked the code by using MoveCurrentToNext() method, it is working properly. This approach won't affect your existing code.

    2nd approach, use AllShootingDayInfo directly or use SourceCollection property to get underlying Collection :

        ViewModel vm = new ViewModel();
        System.Diagnostics.Debug.WriteLine(vm.ShootingDayInfoList.Count.ToString());
        vm.SelectedDay.Date = DateTime.Parse("12/23/2015");
    
        IEnumerable<ShootingDay> underlyingCollection = ((IEnumerable<ShootingDay>)vm.ShootingDayInfoList.SourceCollection);
    
        ShootingDay d1 = underlyingCollection.FirstOrDefault(dt => dt.Date.Equals(vm.SelectedDay.Date)); 
    
        vm.ShootingDayInfoList.MoveCurrentTo(d1);