2009-05-10 5 views
1

나는이 콜렉션 (ShoutBox.Entities) 인 특성을 가진 개체를 보유하고이 DependencyProperty :WPF : 데이터 바인딩 컬렉션에 요소를 추가 (A 종속성 속성)

public static readonly DependencyProperty ShoutBoxProperty = DependencyProperty.Register("ShoutBox",typeof (ShoutBox),typeof (ShoutBoxViewerControl)); 

public ShoutBox ShoutBox 
{ 
    get { return (ShoutBox) GetValue(ShoutBoxProperty); } 
    set { SetValue(ShoutBoxProperty, value); } 
} 

그것은 같은 xaml에 바인더 제본되고있다 같은 :

<ItemsControl ItemsSource="{Binding ShoutBox.Entries}"> 
. 
. 
</ItemsControl> 

내가 처음을 결합하면 예상대로 작동하지만이 같은처럼 (같은 제어하는 ​​방법) 컬렉션에 항목을 추가 할 때 거기에 시간 :

public void AddNewEntry(ShoutBoxEntry newEntry) 
{ 
    Dispatcher.Invoke(new Action(() =>{ 
     ShoutBox.Entries.Add(newEntry); //Adding directly the the Dependency property 
    })); 
} 

위의 방법으로 새 ​​요소를 추가 할 때 항목이 ItemsControl에 표시되지 않는 것이 문제입니다.


내 질문은 왜이 ItemsControl에 표시되지 않는 추가하고 새로운 요소는 아니다, 입니까?


[편집]

Entries (ShoutBox.Entries)이

답변

3

항목 유형이 무엇 형 List<ShoutBoxEntry>이다? ObservableCollection이거나 ICollectionChanged를 구현해야합니다. 그렇지 않으면 바인딩은 새 항목이 추가되었음을 알지 못합니다.

+0

목록

+0

합니다. List 를 ObservableCollection 로 변경하면 제대로 작동합니다. http://msdn.microsoft.com/en-us/library/ms668604.aspx – NotDan

+0

항목 추가 및 제거를 선택하려면 컬렉션에서 INotifyPropertyChanged가 아닌 ICollectionChanged를 구현해야합니다. –

0

항목 유형을 변경하면 실제로 문제가 해결됩니다. Dispatcher.Invoke에 대한 명시 적 호출을 피하려면 콜렉션을 생성 한 스레드에서 CollectionChanged 및 PropertyChanged 이벤트를 발생시키는 콜렉션을 작성했습니다.

public class AsyncObservableCollection<T> : ObservableCollection<T> 
{ 
    private SynchronizationContext _synchronizationContext = SynchronizationContext.Current; 

    public AsyncObservableCollection() 
    { 
    } 

    public AsyncObservableCollection(IEnumerable<T> list) 
     : base(list) 
    { 
    } 

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) 
    { 
     if (SynchronizationContext.Current == _synchronizationContext) 
     { 
      // Execute the CollectionChanged event on the current thread 
      RaiseCollectionChanged(e); 
     } 
     else 
     { 
      // Post the CollectionChanged event on the creator thread 
      _synchronizationContext.Post(RaiseCollectionChanged, e); 
     } 
    } 

    private void RaiseCollectionChanged(object param) 
    { 
     // We are in the creator thread, call the base implementation directly 
     base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param); 
    } 

    protected override void OnPropertyChanged(PropertyChangedEventArgs e) 
    { 
     if (SynchronizationContext.Current == _synchronizationContext) 
     { 
      // Execute the PropertyChanged event on the current thread 
      RaisePropertyChanged(e); 
     } 
     else 
     { 
      // Post the PropertyChanged event on the creator thread 
      _synchronizationContext.Post(RaisePropertyChanged, e); 
     } 
    } 

    private void RaisePropertyChanged(object param) 
    { 
     // We are in the creator thread, call the base implementation directly 
     base.OnPropertyChanged((PropertyChangedEventArgs)param); 
    } 
} 

자세한 내용은 여기에서 찾을 수 있습니다 : 문제의 http://www.thomaslevesque.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/