I've got a view model that exposes a CollectionViewSource built around my observable collection. I also have a command for deleting items:
public ObservableCollection<FooViewModel> Foos { get; set; }
public ICollectionView FooCollectionView { get; set; }
public ICommand DeleteFooCommand { get; set; }
private FooViewModel _SelectedFoo;
public FooViewModel SelectedFoo
{
get { return _SelectedFoo; }
set
{
if (value != _SelectedFoo)
{
_SelectedFoo = value;
OnPropertyChanged();
}
}
}
public MyViewModel()
{
Foos = new ObservableCollection<FooViewModel>();
FooCollectionView = CollectionViewSource.GetDefaultView(Patches);
FooCollectionView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
DeleteFooCommand = new RelayCommand(DeleteFoo);
}
private void DeleteFoo(object parameter)
{
var collection = parameter as IEnumerable;
if (collection == null) return;
var itemsToDelete = collection.OfType<FooViewModel>().ToList();
if (!itemsToDelete.Any()) return;
SelectedFoo = null;
// TODO: Figure out what the next SelectedFoo should be after deleting)
foreach (var item in itemsToDelete)
Foos.Remove(item);
}
In the spirit of MVVM, I don't want to know whether or not my CollectionViewSource was bound to a ListBox, ListView, etc. I simply expect one or more FooViewModels in my command parameter (via [control].SelectedItems). However, I want to set the new SelectedFoo to what I think would be the next logical item that should be selected. I know there is IndexOf() of my source collection, but that index won't match the index after the sort of my CollectionViewSource. Is there a way to get the index of the item on the view and not the source? I can do what I want if I pass the bound ListBox as my command parameter, but I'd rather not know about the bound control.