我需要制作物品清单。我将用户集合绑定到列表框。一切都很好,但列表框中的项目不会实时更新。它们根本没有更新。因此,当我从列表中删除任何用户时,即使其源已正确更改,列表框也不会更新。
Source位于路径DataViewModel.Instance.AllUsers的数据视图模型中;每当我向此列表添加新项目或删除一项时,布局都不会更新。其他绑定工作得很好。我尝试更新列表框布局,引发源更新事件,添加/删除项目的其他方式,但没有任何效果。
我尝试调试绑定,但是我有太多的绑定来查找错误。
提前感谢任何有用的建议。
列表框:
<ListBox x:Name="ListboxUsers" ItemsSource="{Binding Path=AllUsers, Mode=OneWay}" Grid.Column="1" Margin="0" Grid.Row="5" Background="DimGray" BorderThickness="0" Visibility="Hidden" SelectionChanged="ListboxUsers_SelectionChanged"/>
代码隐藏:
CatalogueGrid.DataContext = DataViewModel.Instance; //whole view model added as datacontext
DataViewModel类:
public class DataViewModel : INotifyPropertyChanged
{
private static DataViewModel _dataViewModel;
private Collection<UserModel> allUsers;
public Collection<UserModel> AllUsers
{
get
{
return allUsers;
}
set
{
allUsers = value;
NotifyPropertyChanged("AllUsers");
}
}
private DataViewModel()
{
AllUsers = new Collection<UserModel>();
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string info)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(info));
}
}
.
.
.
}
答案 0 :(得分:6)
如果ObservableColLection
实现了Collection
接口,则使用INotifyCollectionChanged
:
private ObservableCollection<UserModel> allUsers;
public ObservableCollection<UserModel> AllUsers
{
get
{
return allUsers;
}
set
{
allUsers = value;
NotifyPropertyChanged("AllUsers");
}
}
答案 1 :(得分:5)
对于要传播到UI的集合的更改,集合类需要实现INotifyCollectionChanged
。
已经实现此功能的非常有用的类是ObservableCollection<T>
(MSDN)。使用它而不是Collection<T>
。
答案 2 :(得分:3)
您已将列表框绑定到Collection<T>
- 这只是一个列表,它不向绑定属性发出任何通知,其内容已更改。因此,您的列表框无法知道集合何时发生变化。
相反,您可以使用ObservableCollection<T>
class(或更确切地说,任何也实现INotifyCollectionChanged
的集合),并且更改将自动传播到列表框。
请注意,您的媒体资源 无法输入ObservableCollection<T>
,您也可以将公共媒体资源声明为IEnumerable<T>
或IList<T>
;绑定将自行查明返回的类是否也实现了INotifyCollectionChanged
。像这样,您可以稍后替换您的实际底层集合类,例如使用ReadOnlyObservableCollection<T>
,以防您想要禁止来自外部的更改。
说到这一点,请注意您的代码:您已为AllUsers
属性提供了一个setter。这可能会导致意外后果,因为您为其他代码开辟了将属性设置为null
的可能性,这可能会导致异常(取决于代码的其余部分)。除非您确实希望为ItemsSource
属性绑定分配新值,否则只要返回的集合对象实现INotifyCollectionChanged
,只读属性就足够了。