0

I have a class which has an ObservableCollection called Items. That list should fill up a RadGridView. Even though the OC contains data, the list stays empty, and after a bit of debuggingg I noticed it has some odd behavior. I have a breakpoint in the Get and Set of the property. First it hits the Get. Then the Set, but it never hits the Get again. Shouldn't the NotifyChanged also trigger the get after that then, so it updates the list in the view?

Here is the code below of the class I am talking about:

public class PagedCollection<TEntity> where TEntity : class, INotifyPropertyChanged
{
    internal WorkflowEntities Context;
    internal DbSet<TEntity> DbSet;

    private ObservableCollection<TEntity> _items;
    public ObservableCollection<TEntity> Items
    {
        get
        {
            return _items;
        }
        set
        {
            SetField(ref _items, value, nameof(Items));
        }
    }

    public PagedCollection()
    {
        Context = new WorkflowEntities();
        DbSet = Context.Set<TEntity>();
    }

    public virtual IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null,
                                            Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null,
                                            string includeProperties = "")
    {
        IQueryable<TEntity> value = DbSet;

        if (filter != null)
        {
            value = value.Where(filter);
        }

        value = includeProperties.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Aggregate(value, (current, includeProperty) => current.Include(includeProperty));

        return query?.Invoke(value).ToList() != null ? query(value).ToList() : value.ToList();
    }

    // boiler-plate
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    protected bool SetField<T>(ref T field, T value, string propertyName)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

The public virtual IEnumerable<TEntity> Get(...) is being triggered by another class, which fills up the Items. Like this: PagedCollection.Items = PagedCollection.Get();. This in turn fires the get, set, but not a get anymore, so my list stays empty in the view, even though there is data in PagedCollection.Items

user2657943
  • 2,598
  • 5
  • 27
  • 49

4 Answers4

1

Your class, PagedCollection, doesn't implement INotifyPropertyChanged.

public class PagedCollection<TEntity> where TEntity : class, INotifyPropertyChanged

What this says is that TEntity must be a class and implement INotifyPropertyChanged.

Try this instead:

public class PagedCollection<TEntity> : INotifyPropertyChanged where TEntity : class, INotifyPropertyChanged
J.H.
  • 4,232
  • 1
  • 18
  • 16
0

You can't call PagedCollection.Get(); like that you have to instantiate something.

Safe
  • 313
  • 3
  • 13
0

A change in a property of an object within a regular ObservableCollection does not trigger the CollectionChanged event.

Maybe you could use the TrulyObservableCollection class, derived from the former:

ObservableCollection not noticing when Item in it changes (even with INotifyPropertyChanged)

Community
  • 1
  • 1
0

One thing is the ObservableCollection property itself.

When you run the program, it is get once when the view is loaded, and it is set once when you first initialize that property.

After that, when you populate the list, it's not the PropertyChanged event that is fired, since it would be fired only if you assign the whole OC property to another value (usually via Items = new ObservableCollection<TEntity>());

Thus, the event you should be watching is CollectionChanged, which is fired every time you add, remove, swap or replace elements.

heltonbiker
  • 26,657
  • 28
  • 137
  • 252