1

I am trying to implement a filtering and paging on a ListView. I managed to do the filtering but I observed that the UI doesn't get updated when I am adding/removing items from the collection.

Here is my setup: XAML:

   <ListView
           ItemsSource="{Binding SourceCollection, UpdateSourceTrigger=Explicit}"
           ScrollViewer.HorizontalScrollBarVisibility="Hidden"
           ScrollViewer.VerticalScrollBarVisibility="Auto"/>

VM Side:

  private CollectionViewSource _usersCollection;

CTOR

  _usersCollection = new CollectionViewSource {Source = UsersCollection};
  _usersCollection.Filter += usersCollection_Filter;

Props:

  public ICollectionView SourceCollection => _usersCollection.View;
  public List<User> UsersCollection => LiteDbHelper.GetAllUsers();

Then when I am adding a new item I tried to Refresh() the collection (both SourceCollection and _usersCollection) with no luck, also tried to RaisePropertyChanged on UsersCollection, again with no luck. The UI stays the same as the first time created.

P.S. I am adding records to a file-DB (LiteDB) and then I need to retrieve them from the DB and update the UI. This worked till I started to use the ICollectionView.

Any hints?

Update: I managed to fix this issue with the following code:

Changed the property that was feeding the CollectionViewSource:

 private ObservableCollection<User> _usersCollectionDB = new ObservableCollection<User>();
    public ObservableCollection<User> UsersCollection
    {
        get
        {
            if (_usersCollectionDB.Count == 0)
            {
                var allUsers = LiteDbHelper.GetAllUsers();
                _usersCollectionDB.AddRange(allUsers);
                return _usersCollectionDB;
            }

            return _usersCollectionDB;

        }
        set => _usersCollectionDB = value;
    }

and on the add method I just used these lines and it worked:

        var allUsers = LiteDbHelper.GetAllUsers();
        _usersCollectionDB.Clear();
        _usersCollectionDB.AddRange(allUsers);

        _usersCollection.View.Refresh();
Rock3rRullz
  • 357
  • 1
  • 4
  • 21
  • How do you retrieve the records and update the source collection? – mm8 Oct 04 '18 at 14:58
  • With this: LiteDbHelper.GetAllUsers, and in the begining I only raised the property to get the new values, but now with the ICollectionView it doesn't work anymore – Rock3rRullz Oct 04 '18 at 15:30
  • You need to reset the Source property. Please post your code. – mm8 Oct 04 '18 at 15:31
  • I cleaned my vm in order to contain only the stuff for this issue: https://pastebin.com/vpi7VqVS AddUserMethod - is called when I add a new user to database – Rock3rRullz Oct 04 '18 at 16:45
  • You haven't posted any AddUserMethod. Please post the relevant parts of your code here instead of referring to some external link. – mm8 Oct 05 '18 at 09:42
  • The relevant part from that method I posted it on the last code block on edit. – Rock3rRullz Oct 05 '18 at 15:42

1 Answers1

1

Your source collection is a simple list:

List<User> UsersCollection => LiteDbHelper.GetAllUsers();
_usersCollection = new CollectionViewSource { Source = UsersCollection };

This is the reason you won't get any UI updates. The UsersCollection property will be queried by the CollectionViewSource one time, so the CollectionViewSource's instance will work only with that single list of items that were retrieved on initialization.

If you check out the documentation, you will see the following:

If the source collection implements the INotifyCollectionChanged interface, the changes raised by the CollectionChanged event are propagated to the views.

The source collection needs to implement INotifyCollectionChanged. That's e.g. an ObservableCollection<T>.

So the solution is: instead of using dynamically created lists, you should use an ObservableCollection<User> as a source for the CollectionViewSource.

ObservableCollection<User> usersObservableCollection = new ObservableCollection<User>();
_usersCollection = new CollectionViewSource { Source = usersObservableCollection };

Additionally, you will need to change your code so that this usersObservableCollection is populated by the items from your database.

dymanoid
  • 14,771
  • 4
  • 36
  • 64
  • I modified the Source to be a ObservableCollection and still is not working, I even forced a raise of the usersObservableCollection but the UI remains the same. – Rock3rRullz Oct 04 '18 at 14:07