目前我正在编写自己的字典,实现INotifyPropertyChanged。见下文:
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
new public Item this[TKey key]
{
get { return base.Item[key]; }
set(TValue value)
{
if (base.Item[key] != value)
{
base.Item[key] = value;
OnPropertyChanged("XXX"); // what string should I use?
}
}
}
我的目标很简单:当“词典”中的某个值发生更改时,请通知它已更改。所有与相应键名绑定的WPF元素都应该自行更新。
现在我的问题是:我应该使用哪个字符串propertyName
来通知?
我尝试了"[" + key.ToString() + "]"
,"Item[" + key.ToString() + "]"
,只是key.ToString()
。它们似乎都不起作用,因为WPF元素没有更新。
使用String.Empty
(""
)会更新WPF元素,但我没有使用它,因为这将更新绑定到同一个字典的所有WPF元素,即使它们具有不同的键
这就是我的绑定在XAML中的样子:
<TextBlock DataContext="{Binding Dictionary}" Text="{Binding [Index]}" />
Index
当然是我字典中密钥的名称。
有些人建议使用INotifyCollectionChanged而不是使用INotifyPropertyChanged。我试过这个:
Dim index As Integer = MyBase.Keys.ToList().IndexOf(key)
Dim changedItem As Object = MyBase.ToList().ElementAt(index)
RaiseEvent CollectionChanged(Me, New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, changedItem, index))
但是,这也不会更新绑定的WPF元素。
答案 0 :(得分:6)
也许你需要考虑INotifyCollectionChanged界面而不是INotifyPropertyChanged
。如果是这种情况,请查看this question以及与之关联的博文。
另外,请检查this answer之前与您类似的问题。它建议您使用Binding.IndexerName的值作为更改通知的属性名称。
修改强>
如果您想避免使用INotifyCollectionChanged
,可以尝试其他方法。更改字典,使其值的类型是实现INotifyPropertyChanged
的代理对象。
public class MyProxy<T> : INotifyPropertyChanged
{
public T Value
{
// Getter and setter with change notification code here.
}
}
然后只将此类型的实例插入到字典中一次。使用检索代理的代码替换更新字典中值的代码,然后更新其Value
属性。
您需要将XAML绑定更改为([Item]).Value
。
在审核了您的其他一些评论后,看起来这种方法可能对您有用。它与我最近必须做的事情相似。创建自定义KeyedCollection和相应的代理。向代理添加ItemName
属性;它只能是只读的,不需要支持更改通知。在KeyedCollection
属性上创建ItemName
实施索引。干得好吃!如果您愿意,我会添加示例代码。
答案 1 :(得分:0)
if (base.Item[key] != value)
{
base.Item[key] = value;
if (key == "notifykey") OnPropertyChanged("[Item]");
}
String.empty将通知所有属性,而不仅仅是Item
认为这是所有绑定到Dictionary仍然更新的问题 所以我会创建一个新的属性
我们假设你的值是字符串 绑定到KeyedValue
public String KeyedValue
{
get { return base.Item[Index]; }
}
if (key == "Index") OnPropertyChanged("KeyedValue");