嗯,那是一个非常艰难的!
我所做的是:
ObservableKeyedCollection
1 ) 扩展
public class ObservableKeyedCollection<TKey, TItem> : KeyedCollection<TKey, TItem>, INotifyCollectionChanged
{
...
Func<TKey,TItem> m_newItemDelegate;
public ObservableKeyedCollection(Func<TItem, TKey> getKeyForItemDelegate, Func<TKey, TItem> newItemDelegate = null)
: base()
{
...
m_newItemDelegate = newItemDelegate;
}
public new TItem this[TKey key]
{
get
{
if (m_newItemDelegate != null && !Contains(key))
{
TItem i = m_newItemDelegate(key);
var i_as_inpc = i as INotifyPropertyChanged;
if (i_as_inpc != null)
i_as_inpc.PropertyChanged += new PropertyChangedEventHandler(AddItemOnChangeHandler);
else
Add(i);
return i;
}
return base[key];
}
set
{
if (Contains(key)) Remove(key);
Add(value);
}
}
private void AddItemOnChangeHandler(object sender, PropertyChangedEventArgs e)
{
(sender as INotifyPropertyChanged).PropertyChanged -= AddItemOnChangeHandler;
Add((TItem)sender);
}
- 尽管索引器被声明为
new
,绑定引擎正确地解析它。
- 如果提供了 new-item-delegate,我们利用它来获取缺失键的一些默认项目实例。此新项目不会立即添加到集合中,因为它可能违反仅在用户实际编辑值后才添加值的要求。反而,
- 如果项目实现了
INotifyPropertyChanged
,我们挂钩它的PropertyChanged
事件,将项目从处理程序添加到集合中并立即取消订阅PropertyChanged
。
仅此一项就足够了,但是……出于某种奇怪的原因,嵌套属性通知不会触发!
2)重写绑定如下:
<TextBox DataContext="{Binding Params[APN_HOST]}" Text="{Binding Value}" />
现在它触发了,触发了上述机制!
编辑。在这里进行了一些讨论之后,我现在看到第二次修改是解决方案中不可避免的一部分,因为默认行为。根本没有其他可能性可以确定哪个实例已更改。