双向数据绑定与WPF中的字典

我想将Dictionary绑定到WPF中的ListView 。 我想通过数据绑定机制更新Dictionary中的Values来实现这一点。 我不想仅仅改变Keys 。 我也不关心在Dictionary添加新的映射。 我只是想更新现有的。

将Dictionary设置为ListViewItemsSource不能实现此目的。 它不起作用,因为ListView使用Enumerator来访问Dictionary的内容,并且该枚举的元素是不可变的KeyValuePair对象。

我当前的调查线试图使用Keys属性。 我将它分配给ListViewItemsSource属性。 这允许我显示Keys但我不太了解WPF的数据绑定机制来访问DictionaryValues

我发现了这个问题: 在XAML中访问codebehind变量但仍然无法弥补差距。

你们中的任何人都知道如何使这种方法有效吗? 有没有人有更好的方法?

看起来,作为最后的手段,我可​​以构建一个自定义对象并将其粘贴在List ,我可以从中重新创建/更新我的Dictionary但这似乎是一种绕过内置数据绑定function而不是有效利用它的方法。

我不认为你能用词典做你想做的事。

  1. 因为Dictionary没有实现INotifyPropertyChanged或INotifyCollectionChanged
  2. 因为它不会像你想要的那样允许双向绑定。

我不确定它是否完全符合您的要求,但我会使用ObservableCollection和自定义类。

我正在使用DataTemplate来展示如何以两种方式对值进行绑定。

当然在这个实现中没有使用Key,所以你可以使用ObservableCollection

自定义类

 public class MyCustomClass { public string Key { get; set; } public int Value { get; set; } } 

设置ItemsSource

 ObservableCollection dict = new ObservableCollection(); dict.Add(new MyCustomClass{Key = "test", Value = 1}); dict.Add(new MyCustomClass{ Key = "test2", Value = 2 }); listView.ItemsSource = dict; 

XAML

             

这有点hacky,但我让它工作(假设我明白你想要的)。

我首先创建了一个视图模型类:

 class ViewModel : INotifyPropertyChanged { public ViewModel() { this.data.Add(1, "One"); this.data.Add(2, "Two"); this.data.Add(3, "Three"); } Dictionary data = new Dictionary(); public IDictionary Data { get { return this.data; } } private KeyValuePair? selectedKey = null; public KeyValuePair? SelectedKey { get { return this.selectedKey; } set { this.selectedKey = value; this.OnPropertyChanged("SelectedKey"); this.OnPropertyChanged("SelectedValue"); } } public string SelectedValue { get { if(null == this.SelectedKey) { return string.Empty; } return this.data[this.SelectedKey.Value.Key]; } set { this.data[this.SelectedKey.Value.Key] = value; this.OnPropertyChanged("SelectedValue"); } } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propName) { var eh = this.PropertyChanged; if(null != eh) { eh(this, new PropertyChangedEventArgs(propName)); } } } 

然后在XAML中:

            

Data属性的值绑定到ListBoxItemsSource 。 正如您在问题中所述,这导致使用KeyValuePair实例作为ListBox背后的数据。 我将DisplayMemberPath设置为Key以便键的值将用作ListBox每个项目的显示值。

如您所见,您不能仅使用KeyValuePairValue作为TextBox的数据,因为它是只读的。 相反, TextBox绑定到视图模型上的属性,该属性可以获取和设置当前所选键的值(通过将ListBoxSelectedItem属性绑定到视图模型上的另一个属性来更新)。 我必须使这个属性可以为空(因为KeyValuePair是一个结构),所以代码可以检测何时没有选择。

在我的测试应用程序中,这似乎导致对TextBox编辑传播到视图模型中的Dictionary

这或多或少是你想要的吗? 它似乎应该更清洁,但我不确定是否有任何方法可以这样做。

只是发布我从上面得到的东西。 您可以将以下内容放在ObservableCollection>

将密钥设为只读,因为密钥可能不应更改。 这需要Prism工作 – 或者您可以实现自己的INotifyPropertyChanged版本

 public class ObservableKvp : BindableBase { public K Key { get; } private V _value; public V Value { get { return _value; } set { SetProperty(ref _value, value); } } public ObservableKvp(K key, V value) { Key = key; Value = value; } } 

代替

 Dictionary 

你能拥有吗?

 Dictionary? 

让IntWrapperClass实现INotifyPropertyCHanged。 然后,您可以将Listview / Listbox双向绑定到字典中的项目。