1


0

WPF:データバインドコレクションへの要素の追加(依存関係プロパティ)

コレクション(ShoutBox.Entities)であるプロパティを持つエンティティを保持するこの `DependencyProperty`があります:

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`に束縛されています。

.
.

最初にバインドしたときは期待通りに動作しますが、次のようにコレクションにアイテムを追加する必要がある場合があります(同じコントロール内にあるメソッドを使用)。

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

問題は、私が上記のメソッドで新しい要素を追加したとき、アイテムが `ItemsControl`に表示されていないことです。

'' '' '

私の質問は、「*追加した新しい要素が「ItemsControl」に表示されていないのはなぜですか?」

'' '' '

  • [編集] *

EntriesShoutBox.Entries)は` List`型です。

2 Answer


3


エントリーの種類は? ObservableCollectionであるか、ICollectionChangedを実装する必要があります。 そうでなければ、バインディングは新しい項目が追加されたことを知りません。


0


エントリーのタイプを変更することは確かに問題を解決するはずです…​ Dispatcher.Invokeを明示的に呼び出さないようにするには、コレクションを作成したスレッドでCollectionChangedイベントとPropertyChangedイベントを発生させるコレクションを作成しました。

パブリッククラスAsyncObservableCollection:ObservableCollection {private SynchronizationContext _synchronizationContext = SynchronizationContext.Current;

public AsyncObservableCollection(){}

public AsyncObservableCollection(IEnumerable list):base(list){}

OnCollectionChanged(NotifyCollectionChangedEventArgs e){if(SynchronizationContext.Current == _synchronizationContext){//現在のスレッドでCollectionChangedイベントを実行します。RaiseCollectionChanged(e); } else {// CollectionChangedイベントを作成者スレッドにポストする_synchronizationContext.Post(RaiseCollectionChanged、e);} }}

private void RaiseCollectionChanged(object param){//作成者スレッド内にいるので、基本実装を直接呼び出しますbase.OnCollectionChanged((NotifyCollectionChangedEventArgs)param); }

protected override void OnPropertyChanged(PropertyChangedEventArgs e){if(SynchronizationContext.Current == _synchronizationContext){//現在のスレッドでPropertyChangedイベントを実行しますRaisePropertyChanged(e); } else {// PropertyChangedイベントを作成者スレッドにポストする_synchronizationContext.Post(RaisePropertyChanged、e);} }}

private void RaisePropertyChanged(object param){//作成者スレッドにいます。ベース実装を直接呼び出していますbase.OnPropertyChanged((PropertyChangedEventArgs)param); }}

詳細はここで見つけることができます:http://www.thomaslevesque.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/