Jos*_*nel 25 c# data-binding wpf
我正在尝试在C#中为WPF DataBinding创建一个Observable Dictionary Class.我在这里找到了Andy的一个很好的例子:双向数据绑定在WPF中的字典
据此,我试图将代码更改为以下内容:
class ObservableDictionary : ViewModelBase
{
public ObservableDictionary(Dictionary<TKey, TValue> dictionary)
{
_data = dictionary;
}
private Dictionary<TKey, TValue> _data;
public Dictionary<TKey, TValue> Data
{
get { return this._data; }
}
private KeyValuePair<TKey, TValue>? _selectedKey = null;
public KeyValuePair<TKey, TValue>? SelectedKey
{
get { return _selectedKey; }
set
{
_selectedKey = value;
RaisePropertyChanged("SelectedKey");
RaisePropertyChanged("SelectedValue");
}
}
public TValue SelectedValue
{
get
{
return _data[SelectedKey.Value.Key];
}
set
{
_data[SelectedKey.Value.Key] = value;
RaisePropertyChanged("SelectedValue");
}
}
}
Run Code Online (Sandbox Code Playgroud)
}
不幸的是我仍然不知道如何传递"一般"字典对象..任何想法?
谢谢!
干杯
And*_*ndy 35
如果你真的想打一个ObservableDictionary,我建议创建一个实现既类IDictionary和INotifyCollectionChanged.您可以随时使用Dictionary内部方法来实现这些方法,IDictionary这样您就不必重新实现它们.
由于您完全了解内部Dictionary更改的时间,因此您可以使用该知识来实现INotifyCollectionChanged.
出于历史目的并将人们放在"当前"路径上......重要的是要知道Microsoft现在在Visual Studio 2012中的Windows Store"基本页面"模板中解决了这个要求.为了支持LayoutAwarePage,他们生成一个私有ObservableDictionary类.
但是它们直接实现了一个新的IObservableMap接口而不是IDictionary.此接口添加了一个MapChanged事件和MapChangedEventHandler,它在Windows.Foundation.Collections命名空间中定义.
下面的代码段只是项目"Common"文件夹中生成的LayoutAwarePage.cs中的ObservableDictionary类:
/// <summary>
/// Implementation of IObservableMap that supports reentrancy for use as a default view
/// model.
/// </summary>
private class ObservableDictionary<K, V> : IObservableMap<K, V>
{
private class ObservableDictionaryChangedEventArgs : IMapChangedEventArgs<K>
{
public ObservableDictionaryChangedEventArgs(CollectionChange change, K key)
{
CollectionChange = change;
Key = key;
}
public CollectionChange CollectionChange { get; private set; }
public K Key { get; private set; }
}
private Dictionary<K, V> _dictionary = new Dictionary<K, V>();
public event MapChangedEventHandler<K, V> MapChanged;
private void InvokeMapChanged(CollectionChange change, K key)
{
var eventHandler = MapChanged;
if (eventHandler != null)
{
eventHandler(this, new ObservableDictionaryChangedEventArgs(change, key));
}
}
public void Add(K key, V value)
{
_dictionary.Add(key, value);
InvokeMapChanged(CollectionChange.ItemInserted, key);
}
public void Add(KeyValuePair<K, V> item)
{
Add(item.Key, item.Value);
}
public bool Remove(K key)
{
if (_dictionary.Remove(key))
{
InvokeMapChanged(CollectionChange.ItemRemoved, key);
return true;
}
return false;
}
public bool Remove(KeyValuePair<K, V> item)
{
V currentValue;
if (_dictionary.TryGetValue(item.Key, out currentValue) &&
Object.Equals(item.Value, currentValue) && _dictionary.Remove(item.Key))
{
InvokeMapChanged(CollectionChange.ItemRemoved, item.Key);
return true;
}
return false;
}
public V this[K key]
{
get
{
return _dictionary[key];
}
set
{
_dictionary[key] = value;
InvokeMapChanged(CollectionChange.ItemChanged, key);
}
}
public void Clear()
{
var priorKeys = _dictionary.Keys.ToArray();
_dictionary.Clear();
foreach (var key in priorKeys)
{
InvokeMapChanged(CollectionChange.ItemRemoved, key);
}
}
public ICollection<K> Keys
{
get { return _dictionary.Keys; }
}
public bool ContainsKey(K key)
{
return _dictionary.ContainsKey(key);
}
public bool TryGetValue(K key, out V value)
{
return _dictionary.TryGetValue(key, out value);
}
public ICollection<V> Values
{
get { return _dictionary.Values; }
}
public bool Contains(KeyValuePair<K, V> item)
{
return _dictionary.Contains(item);
}
public int Count
{
get { return _dictionary.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
{
return _dictionary.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _dictionary.GetEnumerator();
}
public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex)
{
if (array == null) throw new ArgumentNullException("array");
int arraySize = array.Length;
foreach (var pair in _dictionary)
{
if (arrayIndex >= arraySize) break;
array[arrayIndex++] = pair;
}
}
}
Run Code Online (Sandbox Code Playgroud)
对新的Windows.Foundation.Collections命名空间的进一步检查显示了已定义的新接口的加载,但只实现了一个PropertySet类.实际上这似乎是一个非常好的ObservableDictionary本身.但是必须有一个原因,MS仍然会生成一个私有的ObservableDictionary.因此,需要进一步检查以确定优缺点.
简而言之,PropertySet或您自己的基于IObservableMap的ObservableDictionary应解决"当前"Windows 8和Phone 8项目的即时需求.但是对于旧框架(WPF 4和Phone 7.5),还有更多工作要做.
| 归档时间: |
|
| 查看次数: |
29044 次 |
| 最近记录: |