[英]Why does Combobox binding not work with List<T>
我試圖像這樣在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無關。
更新:
使用可觀察的集合是可行的,但我想知道我是否在這樣的視圖模型中綁定了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是否在后台線程上運行? 我問的原因是設置程序是否需要一段時間才能從數據庫加載項目,所以會阻塞GUI?
這是我第一次嘗試使用ObservableCollection時出錯的地方,方法是使用BackgroundWorker在后台線程上的setter中運行代碼。 在這些情況下,更新ObservableCollection會導致異常。
我認為,如果您使用ObservableCollection <>而不是List <>,它將起作用。 除非您使用ObservableCollection,否則xaml不會知道列表的內容已更改。
要回答問題的第二部分,如果您嘗試直接使用BackgroundWorker設置ObservableCollection,則會出現異常。 解決異常的方法之一是使用BeginInvoke設置ObservableCollection
需要注意的一件事:您不需要調用NotifyPropertyChanged(this, x => x.ComboboxItems);
在你的二傳手中。 這是因為屬性沒有改變; 該屬性是一個集合,並且集合的內容正在更改。 ObservableCollection將通知訂閱者內容已更改。
使用ObservableCollection而不是List。
引用MSDN:
您可以枚舉實現IEnumerable接口的任何集合。 但是,要設置動態綁定,以便集合中的插入或刪除會自動更新UI,該集合必須實現INotifyCollectionChanged接口。 此接口公開CollectionChanged事件,該事件在基礎集合發生更改時應引發。
WPF提供了ObservableCollection類,它是實現INotifyCollectionChanged接口的數據集合的內置實現。
在實現自己的集合之前,請考慮使用ObservableCollection或現有的集合類之一,例如List,Collection和BindingList等。 如果您有高級方案並想要實現自己的集合,請考慮使用IList,它提供了可以由索引單獨訪問的對象的非通用集合。 實施IList可通過數據綁定引擎提供最佳性能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.