我试图像这样在WPF中绑定一个组合框,
<ComboBox Width="350" Margin="5" IsEditable="True" ItemsSource="{Binding ComboboxItems}" DisplayMemberPath="Name">
public List<ExpandoObject> ComboboxItems
{
get
{
return comboboxItems;
}
}
如果我在我的视图模型中设置了这样的列表,
comboboxItems.Clear();
foreach (ExpandoObject comboboxItem in repository.LoadComboboxItems())
{
comboboxItems.Add(comboboxItem);
}
NotifyPropertyChanged(this, x => x.ComboboxItems);
NotifyPropertyChanged似乎有效,因为ComboboxItems上的断点被击中,但组合框列表不会在GUI上更新。 Snoop没有显示任何绑定错误或类似的错误。
第一次更新上面的列表似乎有用,所以它与使用我不认为的ExpandoObject无关。
更新:
使用可观察的集合是有效的,但我想知道我是否在这样的viewmodel中有一个setter,它绑定到GUI上的一个控件,
public string Database
{
get
{
return importData.Database;
}
set
{
importData.Database = value;
NotifyPropertyChanged(this, x => x.Database);
comboboxItems.Clear();
foreach (ExpandoObject comboboxItem in repository.LoadComboboxItems())
{
comboboxItems.Add(comboboxItem);
}
NotifyPropertyChanged(this, x => x.ComboboxItems);
}
}
该setter是否在后台线程上运行?我问的原因是,如果从数据库加载项目需要一段时间,setter会阻止GUI吗?
这是我第一次尝试使用ObservableCollection时出错,通过使用BackgroundWorker在后台线程上运行setter中的代码。在这些条件下更新ObservableCollection会导致异常。
答案 0 :(得分:4)
我认为如果您使用ObservableCollection&lt;&gt;而不是List&lt;&gt;。除非您使用ObservableCollection,否则xaml将不知道列表的内容已更改。
要回答问题的第二部分,如果您尝试直接使用BackgroundWorker设置ObservableCollection,则会出现异常。解决异常的方法之一是使用BeginInvoke
设置ObservableCollection有一点需要注意:您不需要在您的二传手中调用NotifyPropertyChanged(this, x => x.ComboboxItems);
。这是因为财产没有变化;该属性是一个集合,集合内容正在发生变化。 ObservableCollection将通知订阅者内容已更改。
答案 1 :(得分:0)
使用ObservableCollection代替List。
引用MSDN:
您可以枚举任何实现IEnumerable的集合 接口。但是,要设置动态绑定以便插入或插入 集合中的删除会自动更新UI 集合必须实现INotifyCollectionChanged接口。这个 interface公开了CollectionChanged事件,应该是一个事件 每当基础集合发生变化时都会引发。
WPF提供了ObservableCollection类,它是一个内置的 实现实现的数据集合的实现 INotifyCollectionChanged接口。
在实施您自己的收藏之前,请考虑使用 ObservableCollection或现有集合类之一, 例如List,Collection和BindingList等等。 如果您有高级方案并想要实现自己的方案 集合,考虑使用IList,它提供非泛型 可以通过索引单独访问的对象集合。 实现IList可以提供数据绑定的最佳性能 发动机。