C# 使绑定在不同类中的属性上工作
因此,我有一个类C# 使绑定在不同类中的属性上工作,c#,wpf,xaml,binding,C#,Wpf,Xaml,Binding,因此,我有一个类MainViewModel,其中有一个按钮。该按钮导航到具有自己视图模型的视图,让我们调用ListViewModel。它位于MainViewModel内部。它有一个名为WorkOrders的ObservableCollection 在我的主视图模型中,我有一个属性,它返回ListViewModel中列表中的项数。但是,如果我将按钮文本绑定到此属性(NumberOfWorkOrders),则当WorkOrders.Count()更改时,不会发生任何事情。即使我调用OnPropert
MainViewModel
,其中有一个按钮。该按钮导航到具有自己视图模型的视图,让我们调用ListViewModel
。它位于MainViewModel内部。它有一个名为WorkOrders
的ObservableCollection
在我的主视图模型中,我有一个属性,它返回ListViewModel中列表中的项数。但是,如果我将按钮文本绑定到此属性(NumberOfWorkOrders
),则当WorkOrders.Count()
更改时,不会发生任何事情。即使我调用OnPropertyChanged(“NumberOfWorkOrders”)
但是,如果我绑定到ListViewModel中的相同属性,它确实可以工作。为什么在MainViewModel中的属性不起作用?是否因为INotifyPropertyChanged的通知在其他视图模型中不起作用
按钮绑定不起作用(使用MainViewModel中的属性)
ListViewModel.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; }
}
}
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");
}
}
公共类ListViewModel:BindableBase
{
//INotifyPropertiesChanged在BindableBase中实现
公众可观察收集工作单
{
获得;设置;
}
//我更喜欢在MainViewModel中使用此版本
公共国际号码
{
获取{return listViewModel.WorkOrders.Count();}
}
公共订单()
{
(…)//加载工单并将其添加到集合中
关于财产变更(“工作订单数量”);
}
}
您的MainViewModel
绑定无法工作的原因是,您从ListViewModel
上下文调用了OnPropertyChanged(“NumberOfWorkOrders”)
。
我建议在MainViewModel
中对listViewModel.WorkOrders
中的更改进行签名,并在WorkOrders
更改时,从MainViewModel
对属性更改(“NumberOfWorkOrders”)
发出。您需要查看ObservableCollection
的文档,以找到如何签署已更改的收款通知。您遇到了
,其中您有需要额外作业的聚合属性:您必须订阅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));
};
}
}
<Button Content="{Binding LVM.NumberOfWorkOrders}" ... />
第一个按钮(不起作用)将MainViewModel
作为数据上下文,绑定将只侦听此类中的通知
作为一个简单的修复,您可以在绑定的Path
中包含LVM
。绑定是智能的,将开始侦听两个事件:主视图模型的事件和由LVM
property给出的实例的事件:
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));
};
}
}
<Button Content="{Binding LVM.NumberOfWorkOrders}" ... />
您可以从MainViewModel
中删除NumberOfWorkOrders
。请参见您需要实现inotifPropertyChanged
@Decoder94我已经在我的BindableBase
类中实现了inotifPropertyChanged
,这是由两个视图模型继承的。我还应该在哪里实现它?它是绑定的源,即定义NumberOfWorkOrders属性的类,需要引发PropertyChanged事件。谢谢,它可以工作。除了一件事。我不允许在MainViewModel()
中的构造函数中使用nameof()。我可以通过将属性的名称键入字符串来解决问题,所以唯一真正的问题是我的混淆。。。