所以我有一个班级MainViewModel
我有一个按钮。该按钮导航到具有自己的视图模型的视图,让我们在ListViewModel
中调用。它驻留在MainViewModel中。它有ObservableCollection
名为WorkOrders
。
在我的主视图模型中,我有一个属性,它返回ListViewModel列表中的项目数。但是,如果我将我的按钮文本绑定到此属性(NumberOfWorkOrders
),那么当WorkOrders.Count()
更改时没有任何反应。即使我致电OnPropertyChanged("NumberOfWorkOrders")
。
但是,如果我绑定到ListViewModel中的相同属性,它确实有效。为什么它不起作用,MainViewModel中的属性?是因为来自INotifyPropertyChanged的通知在不同的视图模型中不起作用吗?
不起作用的按钮绑定(使用MainViewModel中的属性)
<Button
Content="{Binding NumberOfWorkOrders}"
ContentStringFormat="WorkOrders ({0})" />
可以工作的按钮绑定(使用ListViewModel中的属性)
<Button
DataContext="{Binding LVM}"
Content="{Binding NumberOfWorkOrders}"
ContentStringFormat="WorkOrders ({0})" />
MainViewModel.cs
public class MainViewModel : BindableBase
{
// INotifyPropertiesChanged is implemented in BindableBase
private ListViewModel listViewModel = new ListViewModel();
// This is where I would like to bind my button text to
public int NumberOfWorkOrders
{
get { return listViewModel.WorkOrders.Count(); }
}
// I would prefer not to have this
public ListViewModel LVM
{
get { return listViewModel; }
}
}
ListViewModel.cs
public class ListViewModel : BindableBase
{
// INotifyPropertiesChanged is implemented in BindableBase
public ObservableCollection<WorkOrder> WorkOrders
{
get; set;
}
// I would prefer to use the version of this in the MainViewModel
public int NumberOfWorkOrders
{
get { return listViewModel.WorkOrders.Count(); }
}
public void RefreshWorkOrders()
{
(...) // Load work orders and add them to collection
OnPropertyChanged("NumberOfWorkOrders");
}
}
答案 0 :(得分:1)
您正在遇到this problem
,如果您有需要额外工作的聚合属性:您必须订阅FrameworkElement
并提升ListViewModel.PropertyChanged
属性的通知:
MainViewModel.NumberOfWorkOrders
第一个按钮(不起作用)有public class MainViewModel : BindableBase
{
readonly ListViewModel listViewModel = new ListViewModel();
public int NumberOfWorkOrders => listViewModel.WorkOrders.Count();
public MainViewModel()
{
// since you already rise notification in ListViewModel
// listen to it and "propagate"
listViewModel.PropertyChanged += (s, e) =>
{
if(e.PropertyName == nameof(ListViewModel.NumberOfWorkOrders))
OnPropertyChanged(nameof(NumberOfWorkOrders));
};
}
}
作为数据上下文,绑定只会侦听此类中的通知。
作为一个简单的修复,您可以在MainViewModel
绑定中包含LVM
。绑定很聪明,将开始监听两个事件:主视图模型和Path
属性给出的实例:
LVM
您可以从<Button Content="{Binding LVM.NumberOfWorkOrders}" ... />
删除NumberOfWorkOrders
。
答案 1 :(得分:0)
MainViewModel
绑定无法正常工作的原因,因为您从OnPropertyChanged("NumberOfWorkOrders")
上下文调用了ListViewModel
。
我建议在MainViewModel
时签署listViewModel.WorkOrders
中的更改,并在OnPropertyChanged("NumberOfWorkOrders")
更改MainViewModel
时触发WorkOrders
。您需要查看ObservableCollection
的文档,以了解如何签署收集更改通知。