通知字典中的某个值已更改

时间:2013-01-30 13:31:17

标签: .net wpf dictionary key inotifypropertychanged

目前我正在编写自己的字典,实现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元素。

2 个答案:

答案 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");