2015-12-08 49 views
1

如果一個結合於列表框的ItemsSource到列表類型的結構,諸如ObservableCollection(或任何唯一值容器真的)一類的類型(List< MyClass>),可以訪問該類的屬性。綁定到類屬性在字典中WPF

但是,如果有一個Dictionary<long, MyClass>並將itemssource綁定到Dictionary.Values不能再訪問類屬性。

所以基本上這是我的XAML

<ListBox ItemsSource="{Binding bm.Values}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <StackPanel> 
        <TextBlock Text="{Binding Name}"/> 
        <TextBlock Text="{Binding Property2}"/> 
        <TextBlock Text="{Binding Property3}"/> 
       </StackPanel> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 

並在視圖模型是

public Dictionary<long,MyClass> bm { get; set; } 

有了這樣的代碼,你有Texblock的DataContext設置爲MyClass,但你沒有訪問名稱,property2和property3。但是,如果將字典更改爲List,則TextBlock DataContext也將設置爲MyClass,但它可以訪問這些字段。

由於架構原因,我無法從字典切換到非密鑰集合。

所以問題是:你如何讓XAML看到屬性以及爲什麼這種情況確實發生?

+0

你所說的這個代碼?我能夠綁定dictionary.values,並且可以像預期的那樣查看屬性值。你如何設置datacontext? – AnjumSKhan

回答

1

隨意使用ObservableDictionary類

public class ObservableDictionary<TKey, TValue> : IDictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged { 
    private const string CountString = "Count"; 
    private const string IndexerName = "Item[]"; 
    private const string KeysName = "Keys"; 
    private const string ValuesName = "Values"; 

    private IDictionary<TKey, TValue> _Dictionary; 
    protected IDictionary<TKey, TValue> Dictionary { 
     get { return _Dictionary; } 
    } 

    #region Constructors 
    public ObservableDictionary() { 
     _Dictionary = new Dictionary<TKey, TValue>(); 
    } 
    public ObservableDictionary(IDictionary<TKey, TValue> dictionary) { 
     _Dictionary = new Dictionary<TKey, TValue>(dictionary); 
    } 
    public ObservableDictionary(IEqualityComparer<TKey> comparer) { 
     _Dictionary = new Dictionary<TKey, TValue>(comparer); 
    } 
    public ObservableDictionary(int capacity) { 
     _Dictionary = new Dictionary<TKey, TValue>(capacity); 
    } 
    public ObservableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) { 
     _Dictionary = new Dictionary<TKey, TValue>(dictionary, comparer); 
    } 
    public ObservableDictionary(int capacity, IEqualityComparer<TKey> comparer) { 
     _Dictionary = new Dictionary<TKey, TValue>(capacity, comparer); 
    } 
    #endregion 

    #region IDictionary<TKey,TValue> Members 

    public void Add(TKey key, TValue value) { 
     Insert(key, value, true); 
    } 

    public bool ContainsKey(TKey key) { 
     return Dictionary.ContainsKey(key); 
    } 

    public ICollection<TKey> Keys { 
     get { return Dictionary.Keys; } 
    } 

    public bool Remove(TKey key) { 
     if(key == null) throw new ArgumentNullException("key"); 

     TValue value; 
     Dictionary.TryGetValue(key, out value); 
     var removed = Dictionary.Remove(key); 
     if(removed) 
      //OnCollectionChanged(NotifyCollectionChangedAction.Remove, new KeyValuePair<TKey, TValue>(key, value)); 
      OnCollectionChanged(); 

     return removed; 
    } 


    public bool TryGetValue(TKey key, out TValue value) { 
     return Dictionary.TryGetValue(key, out value); 
    } 


    public ICollection<TValue> Values { 
     get { return Dictionary.Values; } 
    } 


    public TValue this[TKey key] { 
     get { 
      return Dictionary[key]; 
     } 
     set { 
      Insert(key, value, false); 
     } 
    } 


    #endregion 


    #region ICollection<KeyValuePair<TKey,TValue>> Members 


    public void Add(KeyValuePair<TKey, TValue> item) { 
     Insert(item.Key, item.Value, true); 
    } 


    public void Clear() { 
     if(Dictionary.Count > 0) { 
      Dictionary.Clear(); 
      OnCollectionChanged(); 
     } 
    } 


    public bool Contains(KeyValuePair<TKey, TValue> item) { 
     return Dictionary.Contains(item); 
    } 


    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { 
     Dictionary.CopyTo(array, arrayIndex); 
    } 


    public int Count { 
     get { return Dictionary.Count; } 
    } 


    public bool IsReadOnly { 
     get { return Dictionary.IsReadOnly; } 
    } 


    public bool Remove(KeyValuePair<TKey, TValue> item) { 
     return Remove(item.Key); 
    } 


    #endregion 


    #region IEnumerable<KeyValuePair<TKey,TValue>> Members 


    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { 
     return Dictionary.GetEnumerator(); 
    } 


    #endregion 


    #region IEnumerable Members 


    IEnumerator IEnumerable.GetEnumerator() { 
     return ((IEnumerable) Dictionary).GetEnumerator(); 
    } 


    #endregion 


    #region INotifyCollectionChanged Members 


    public event NotifyCollectionChangedEventHandler CollectionChanged; 


    #endregion 


    #region INotifyPropertyChanged Members 


    public event PropertyChangedEventHandler PropertyChanged; 


    #endregion 


    public void AddRange(IDictionary<TKey, TValue> items) { 
     if(items == null) throw new ArgumentNullException("items"); 


     if(items.Count > 0) { 
      if(Dictionary.Count > 0) { 
       if(items.Keys.Any((k) => Dictionary.ContainsKey(k))) 
        throw new ArgumentException("An item with the same key has already been added."); 
       else 
        foreach(var item in items) Dictionary.Add(item); 
      } else 
       _Dictionary = new Dictionary<TKey, TValue>(items); 


      OnCollectionChanged(NotifyCollectionChangedAction.Add, items.ToArray()); 
     } 
    } 


    private void Insert(TKey key, TValue value, bool add) { 
     if(key == null) throw new ArgumentNullException("key"); 


     TValue item; 
     if(Dictionary.TryGetValue(key, out item)) { 
      if(add) throw new ArgumentException("An item with the same key has already been added."); 
      if(Equals(item, value)) return; 
      Dictionary[key] = value; 


      OnCollectionChanged(NotifyCollectionChangedAction.Replace, new KeyValuePair<TKey, TValue>(key, value), new KeyValuePair<TKey, TValue>(key, item)); 
     } else { 
      Dictionary[key] = value; 

      OnCollectionChanged(NotifyCollectionChangedAction.Add, new KeyValuePair<TKey, TValue>(key, value)); 
     } 
    } 


    private void OnPropertyChanged() { 
     OnPropertyChanged(CountString); 
     OnPropertyChanged(IndexerName); 
     OnPropertyChanged(KeysName); 
     OnPropertyChanged(ValuesName); 
    } 


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


    private void OnCollectionChanged() { 
     OnPropertyChanged(); 
     if(CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
    } 


    private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> changedItem) { 
     OnPropertyChanged(); 
     if(CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, changedItem)); 
    } 


    private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> newItem, KeyValuePair<TKey, TValue> oldItem) { 
     OnPropertyChanged(); 
     if(CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, newItem, oldItem)); 
    } 


    private void OnCollectionChanged(NotifyCollectionChangedAction action, IList newItems) { 
     OnPropertyChanged(); 
     if(CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, newItems)); 
    } 
}