2017-04-08 5 views
1

私は自分のObservableDictionaryを実装しました.A)私は他の人が投稿したと思ったコードに満足していませんでした。私が知る限り、リスナーに通知するなど、すべて正常に動作しますが、何らかの理由でListViewの内容を表示しようとしていますが、更新されません。カスタムObservableがUWPを更新していないListView

INotifyCollectionChangedを使用して変更をリッスンしています。サニティチェックと同じように、ページ初期化時にCollectionChangedイベントにリスナーを添付しましたが、アイテムを追加すると正しく表示されますが、ListViewに何も表示されません。私はXAMLを正しく設定したことを知っています。辞書にすべてを追加した後にコードバスにItemsSourceを再設定すると、すべてが正しく表示されます。同様に、ObservableDictionaryを組み込みのObservableCollection(XAMLに触れることなく)に置き換えると、2要素の辞書.Add(...)のパラメータを単一要素のコレクション1に合わせて変更する限り、手動による介入なしでも完全にうまく機能します。

ObservableCollectionのコードとの比較では、追加されたオブジェクトのインデックスが含まれていることがわかりますが、コードに追加しても何も変更されません。私のように

protected override void InsertItem(int index, T item) 
{ 
    CheckReentrancy(); 
    base.InsertItem(index, item); 

    OnPropertyChanged(CountString); 
    OnPropertyChanged(IndexerName); 
    OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index); 
} 

private void OnPropertyChanged(string propertyName) 
{ 
    OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); 
} 

protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) 
{ 
    if (PropertyChanged != null) 
    { 
     PropertyChanged(this, e); 
    } 
} 

private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index) 
{ 
    OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index)); 
} 

protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) 
{ 
    if (CollectionChanged != null) 
    { 
     using (BlockReentrancy()) 
     { 
      CollectionChanged(this, e); 
     } 
    } 
} 

:(私の知る限り)

Tuple<bool, TValue> SendAddEvents(Func<bool> preTest, Func<Tuple<bool, TValue>> action, KeyValuePair<TKey, TValue> item) { 
    if (preTest.Invoke()) { 
#if (SUPPORT_PROPERTYCHANGING_EVENT) 
     PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(nameof(Keys))); 
     PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(nameof(Values))); 
     PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(nameof(Count))); 
#endif 
     OnAdding(item); 
    } 

    var result = action.Invoke(); 
    if (result.Item1) { 
     CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(
      NotifyCollectionChangedAction.Add, 
      item 
     )); 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Keys))); 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Values))); 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Count))); 

     OnAdd(item); 
    } 

    return result; 
} 

そして、公式のシステム:関連するコード、システムをトリガ私の(確かにやや過剰設計)イベントを抽出するために

言った、私は2つの間に実質的な違いを見ることはできません。明らかに何かが見当たりませんか、または誰かが回避する方法を知っているという観察可能なコレクションを、ListViewがどのように扱うのか、何か特有のことがありますか?

EDIT:参照のため、XAMLの要素は次の行でバインドされています。インデックスがゼロの行にはTextBlockが含まれています。これは、コレクションが完全に移入されたことを示すために使用しています。上で述べたように、単に "Library"プロパティのタイプをObservableDictionary<string, StorageFile>からObservableCollection<string>(そしてObservableCollection<StorageFile>も同じです)に変更すると、XAMLに触れることなくすべての作業ができます。

<ListView ItemsSource="{Binding Library, ElementName=page}" Grid.Row="1" /> 
+0

リストにどのようにバインドしていますか? xamlバインディングコードはどのようなものですか? – Laith

+0

@Laith元の投稿に追加しました。 –

答えて

0

は、ソースコードを見ると、私はあなたのObservableDictionaryBase<TKey, TValue>IList<TValue>を実装していません気づきました。 ListViewのインデクサが必要です。

ListView.ItemsSourceにバインドされているものは、INotifyCollectionChangedIListの両方を実装する必要があります。辞書の変更が通知されると、インデクサー(つまりpage.Library[n])を介して変更を取得しようとします。

これは最終的にKeyedCollection<TKey, TValue>のような実装につながります。ここでは、キー付き要素の順序付きリストがあります。

+0

それは、ありがとう!私は 'IEnumerable'が十分であると仮定していました。今私はそれを働かせる必要があります。 'OrderedDictionary'には一般的なバージョンがありません(そして、Nugetパッケージは.NETStandardをサポートしていません)。少なくともC#は 'LinkedListNode'を公開します。 –

関連する問題