2011-12-02 3 views
1

좋아, 그래서 개체에 INotifyCollectionChanged 속성을 연결하는 첨부 된 속성 (정적 클래스에서 선언 된)이 있습니다.첨부 된 속성에 저장된 컬렉션의 CollectionChanged 이벤트 구독 취소

속성을 설정하면 변경 내용을 모니터링하기 위해 컬렉션을 시작한 다음 컬렉션이 연결된 개체에 몇 가지 작업을 수행하려고합니다..

첫 번째 시도 : 컬렉션이 핸들러에 부착 된 객체를 얻기 위하여

private static void MyProperty_OnChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    // We need both the dependency object, and the collection args to process the notification 
    NotifyCollectionChangedEventHandler changedFunc = (sender, eventArgs) => MyProperty_OnCollectionChanged(d, sender, eventArgs); 

    if(e.OldValue != null) 
     e.OldValue.CollectionChanged -= changedFunc; // Can you see the bug? 
    if(e.NewValue != null) 
     e.NewValue.CollectionChanged += changedFunc; 

} 

, 나는 폐쇄에 d 당깁니다. 충분히 쉽지, 그렇지?

글쎄, 여기 버그를 볼 수있을 것입니다. changedFunc가 다른 클로저를 가진 새로운 핸들러이기 때문에 컬렉션이 제거되거나 새 컬렉션으로 대체되면 이벤트 핸들러의 등록을 취소하지 못합니다.

그럼 어떻게해야할까요?

답변

0

다른 첨부 된 속성은 이벤트 처리기가 포함 된 개인 개체를 보유하고 d을 참조하여이 문제를 해결했습니다. 효과적으로 클로저 클래스를 명시 적으로 작성하고 이에 대한 참조를 유지합니다.

그러나 이것은 나에게 매우 무거운 손으로 접근 한 것처럼 보입니다. 저는 더 우아한 해결책을 찾고있었습니다.

0

코드에서이 정적 방법의 위치가 명확하지 않습니다.

이벤트 처리기를 속한 클래스의 멤버 변수로 저장할 수있는 방법이 있습니까? 필요한 경우 추가하고 제거 할 수있는 단수의 참조가됩니다. 현재 MyProperty_OnChanged가 발생할 때마다 새 이벤트 처리기를 구성하고 있습니다.

또는, 나중에 액세스 할 수 있도록 e.OldValue.OldHandler (또는 비슷한)를 통해 액세스 할 수 있도록 이벤트 핸들러에 대한 참조를 저장하도록 컬렉션을 변경할 수 있습니까?

+0

첨부 된 속성이므로 처리기를 구성원으로 저장할 수있는 클래스가 없습니다. 현재 _another_ 객체를 _another_ 속성에 저장하고 있습니다 만이 문제를 해결할 수 있지만 더 깨끗한 솔루션을 찾고 있습니다. – Mark

+0

또한 "내"컬렉션이 아닙니다. 연결된 속성은 모든 INotifyCollectionChanged 구현 객체와 함께 작동해야합니다. – Mark

관련 문제