繁体   English   中英

在WPF中绑定到字典中的类属性

[英]Binding to a class property in a dictionary in wpf

如果将列表框的ItemsSource绑定到列表类型的结构,例如具有类类型( List< MyClass> )的ObservableCollection (或实际上是任何仅值容器),则可以访问该类的属性。

但是如果有一个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 ,但是您无法访问Name,property2和property3。 但是,如果将字典更改为List,则TextBlock DataContext也将设置为MyClass ,但是它将有权访问这些字段。

出于体系结构原因,我无法从“词典”切换到非关键集合。

所以问题是:如何使XAML看到属性,以及为什么这种情况实际上发生了呢?

随意使用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));
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM