Nice programing

ReadOnlyObservableCollection.CollectionChanged가 공개되지 않는 이유는 무엇입니까?

nicepro 2020. 10. 10. 11:00
반응형

ReadOnlyObservableCollection.CollectionChanged가 공개되지 않는 이유는 무엇입니까?


ReadOnlyObservableCollection.CollectionChanged보호되고 공개되지 않는 이유는 무엇입니까 (해당하는대로 ObservableCollection.CollectionChanged)?

이벤트에 INotifyCollectionChanged액세스 할 수없는 경우 구현하는 컬렉션의 용도는 무엇입니까 CollectionChanged?


해결책은 다음과 같습니다 . ReadOnlyObservableCollection의 CollectionChanged 이벤트

컬렉션을 INotifyCollectionChanged캐스팅 해야합니다 .


이 작업을 수행하는 방법을 찾았습니다.

ObservableCollection<string> obsCollection = new ObservableCollection<string>();
INotifyCollectionChanged collection = new ReadOnlyObservableCollection<string>(obsCollection);
collection.CollectionChanged += new NotifyCollectionChangedEventHandler(collection_CollectionChanged);

INotifyCollectionChanged 인터페이스에서 명시 적으로 컬렉션을 참조하면 됩니다.


ReadOnlyObservableCollection 에 대한 컬렉션 변경 알림을 구독하려는 데에는 확실히 좋은 이유가 있습니다 . 따라서 단순히 컬렉션을 INotifyCollectionChanged 로 캐스팅하는 대신 ReadOnlyObservableCollection을 서브 클래 싱 하는 경우 다음은 CollectionChanged 이벤트 에 액세스하는보다 구문 상 편리한 방법을 제공합니다 .

    public class ReadOnlyObservableCollectionWithCollectionChangeNotifications<T> : ReadOnlyObservableCollection<T>
{
    public ReadOnlyObservableCollectionWithCollectionChangeNotifications(ObservableCollection<T> list)
        : base(list)
    {
    }

    event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanged2
    {
        add { CollectionChanged += value; }
        remove { CollectionChanged -= value; }
    }
}

이것은 이전에 잘 작동했습니다.


이 게시물은 오래되었지만 사람들은 주석을 달기 전에 .NET에서 사용되는 패턴을 이해하는 데 시간을 투자해야합니다. 읽기 전용 컬렉션은 소비자가 직접 수정하지 못하도록하는 기존 컬렉션의 래퍼입니다. 살펴보면 변경 가능할 수도 있고 그렇지 않을 수도 ReadOnlyCollection있는 래퍼임을 알 IList<T>수 있습니다. 불변 컬렉션은 다른 문제이며 새로운 불변 컬렉션 라이브러리 에서 다룹니다.

즉, 읽기 전용은 불변과 동일하지 않습니다 !!!!

제쳐두고 ReadOnlyObservableCollection암시 적으로 구현해야합니다 INotifyCollectionChanged.


이 문제를 설명하는 Microsoft Connect의 버그 항목 : https://connect.microsoft.com/VisualStudio/feedback/details/641395/readonlyobservablecollection-t-collectionchanged-event-should-be-public 에 투표 할 수 있습니다.

최신 정보:

Connect 포털은 Microsoft에 의해 종료되었습니다. 따라서 위의 링크는 더 이상 작동하지 않습니다.

My Win Application Framework (WAF) 라이브러리는 다음과 같은 솔루션을 제공합니다. ReadOnlyObservableList 클래스 :

public class ReadOnlyObservableList<T> 
        : ReadOnlyObservableCollection<T>, IReadOnlyObservableList<T>
{
    public ReadOnlyObservableList(ObservableCollection<T> list)
        : base(list)
    {
    }

    public new event NotifyCollectionChangedEventHandler CollectionChanged
    {
        add { base.CollectionChanged += value; }
        remove { base.CollectionChanged -= value; }
    }

    public new event PropertyChangedEventHandler PropertyChanged
    {
        add { base.PropertyChanged += value; }
        remove { base.PropertyChanged -= value; }
    }
}

이것은 Google에서 최고 인기를 얻었으므로 다른 사람들이 이것을 찾을 경우에 대비하여 솔루션을 추가 할 것이라고 생각했습니다.

위의 정보 ( INotifyCollectionChanged 로 캐스트해야하는 경우)를 사용하여 등록 및 등록 취소를위한 두 가지 확장 메서드를 만들었습니다.

내 솔루션 -확장 방법

public static void RegisterCollectionChanged(this INotifyCollectionChanged collection, NotifyCollectionChangedEventHandler handler)
{
    collection.CollectionChanged += handler;
}

public static void UnregisterCollectionChanged(this INotifyCollectionChanged collection, NotifyCollectionChangedEventHandler handler)
{
    collection.CollectionChanged -= handler;
}

IThing.cs

public interface IThing
{
    string Name { get; }
    ReadOnlyObservableCollection<int> Values { get; }
}

확장 방법 사용

public void AddThing(IThing thing)
{
    //...
    thing.Values.RegisterCollectionChanged(this.HandleThingCollectionChanged);
}

public void RemoveThing(IThing thing)
{
    //...
    thing.Values.UnregisterCollectionChanged(this.HandleThingCollectionChanged);
}

OP의 솔루션

public void AddThing(IThing thing)
{
    //...
    INotifyCollectionChanged thingCollection = thing.Values;
    thingCollection.CollectionChanged += this.HandleThingCollectionChanged;
}

public void RemoveThing(IThing thing)
{
    //...
    INotifyCollectionChanged thingCollection = thing.Values;
    thingCollection.CollectionChanged -= this.HandleThingCollectionChanged;
}

대안 2

public void AddThing(IThing thing)
{
    //...
    (thing.Values as INotifyCollectionChanged).CollectionChanged += this.HandleThingCollectionChanged;
}

public void RemoveThing(IThing thing)
{
    //...
    (thing.Values as INotifyCollectionChanged).CollectionChanged -= this.HandleThingCollectionChanged;
}

참고 URL : https://stackoverflow.com/questions/2058176/why-is-readonlyobservablecollection-collectionchanged-not-public

반응형