How to make custom collection editable in DataGrid in C#

1

I have business object class that contains definition of List<T> for other business objects.

I cannot change class structure, so I cannot simply use ObservableCollection<T> instead of List<T> but I want to leverage ObservableCollection<T> functionality. So I created a sort of a observable collection wrapper class like this (also tried it with IList<T> instead of ICollection<T>).

public class CollectionObservableOverlay<T> : ICollection<T>, INotifyCollectionChanged
{
    protected ICollection<T> _wrappedCollection;

    #region ICollection<T> properties
    public int Count { get { return _wrappedCollection.Count; } }

    public bool IsReadOnly { get { return _wrappedCollection.IsReadOnly; } }
    #endregion

    public event NotifyCollectionChangedEventHandler CollectionChanged;

    public CollectionObservableOverlay(ICollection<T> wrappedCollection)
    {
        _wrappedCollection = wrappedCollection;
    }

    protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        CollectionChanged?.Invoke(this, e);
    }

    #region ICollection<T> methods

    public void Add(T item)
    {
        _wrappedCollection.Add(item);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));

    }

    public void Clear()
    {
        _wrappedCollection.Clear();
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    public bool Contains(T item)
    {
        return _wrappedCollection.Contains(item);
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        CopyTo(array, arrayIndex);
    }

    public virtual bool Remove(T item)
    {
        bool removed = _wrappedCollection.Remove(item);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        return removed;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return _wrappedCollection.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable)_wrappedCollection).GetEnumerator();
    }
    #endregion
}

The problem is, when I bind instance of CollectionObservableOverlay to DataGrid as ItemsSource and try to edit items, i get the following error:

System.InvalidOperationException
  HResult=0x80131509
  Message='EditItem' is not allowed for this view.
  Source=PresentationFramework

I tried binding to underlying collection directly, and that works fine for DataGrid editing purposes, so underlying list or it's contained objects should not be the source of the problem.

My guess is that I am missing some functionalities which are implemented in concrete List<T> type, but are not present at IList<T> or ICollection<T> interfaces.

I read this, and other related questions and answers but none of them are providing solution on how to do this, or answer if it is even possible. As far as I understand, ICollectionView provided to DataGrid should implement IEditableCollectionView, but I don't know how to achieve that kind of behavior. Any help is welcome.

c#
wpf
data-binding
asked on Stack Overflow Oct 24, 2018 by Miljac

1 Answer

1

Your source collection must implement the non-generic IList interface for the internal editing functionality of the DataGrid control to work as expected.

List<T> and ObservableCollection<T> do this but HashSet<T> doesn't for example.

answered on Stack Overflow Oct 24, 2018 by mm8 • edited Oct 24, 2018 by mm8

User contributions licensed under CC BY-SA 3.0