1

I want to have the view model of my main window inform a user control that the sorting of an ObservableCollection (a property of the view model) has changed via an event.

Using a shared/static method is not my solution as the main window view model should not be aware of the user control (which itself is bound to the same view model).

A list box control is using the ObservableCollection as a source for its Items and this scenario is simply to force ScrollIntoView on the list box.

I'm aware of the concept of RoutedEvents and tunneling which I think might be my solution but I'm not entirely sure if that's the only option. Routing in this way is a completely new concept for me.

I've looked at this example but I would need custom events presumably as opposed to existing routing events.

Thanks.

Community
  • 1
  • 1
miriyo
  • 103
  • 1
  • 11

1 Answers1

0

CollectionChanged event is fired by ICollectionView, when Items are added/removed or List is refreshed. You can make use of this event to raise your own custom event. Below code snippet demonstrates its use when Students collection of a ViewModel vm is sorted.

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            ICollectionView view = (ICollectionView)CollectionViewSource.GetDefaultView(vm.Students);
            view.CollectionChanged += view_CollectionChanged;
            view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending)); 
        }

        void view_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("view_CollectionChanged changed !");
        }

More can be said if you tell how you use the ViewModel's collection property in your UserControl.

Normally MainWindow and UserControls should communicate via ICommand.

Custom Command Tutorial

AnjumSKhan
  • 9,647
  • 1
  • 26
  • 38
  • Thank you for your comment. In this case the ObservableCollection isn't changing. I'm just using a menu on my MainWindow to sort the said ObservableCollection by using: ListCollectionView.SortDescriptions.Add() It's after this that I want to force my user control to use ScrollIntoView. – miriyo Jan 26 '16 at 12:49
  • first of all, you should not sort the collection in MainWindow, instead UserControl itself should respond to Menu. above code can be used as is with `ListBox.ItemsSource` too : `ICollectionView view = (ICollectionView)CollectionViewSource.GetDefaultView(myListBox.ItemsSource);` – AnjumSKhan Jan 26 '16 at 14:01
  • Aside from where the collection should be sorted, I still can't see how my UserControl is aware of an event having happened in the MainWindow. – miriyo Jan 26 '16 at 15:00
  • You have to use an ICommand. There can be many separate UserControls for various MainWindow:MenuItems. They will communicate using Commands. ICommand is must for MVVM. – AnjumSKhan Jan 26 '16 at 15:03
  • Yes I'm familiar with ICommand and am using them already in many places but my UserControl has to react to an Event which is something different. – miriyo Jan 26 '16 at 15:40
  • You can raise the event from the `CollectionChanged` event from `MainWindow`. Use original collection in your GetDefaultView() in MainWindow. Then fire the custom event. – AnjumSKhan Jan 26 '16 at 15:51