[英]wpf ViewModel Property Binding from another viewmodel
how do i bind a property declared in a viewmodel to take value from another viewModel? 如何绑定在ViewModel中声明的属性以从另一个ViewModel获取值?
let me explain 让我解释
i have 2 ViewModels (Implements INotifyPropertyChanged) and 1 View 我有2个ViewModel(实现INotifyPropertyChanged)和1个视图
InvoiceView ( just my invoice design no matter if is a user control or window or a dataTemplate) InvoiceView(无论我是用户控件,窗口还是dataTemplate,都只是我的发票设计)
InvoiceViewModel InvoiceViewModel
NoteListingVM (this viewmodel has a property let's name it TableRefID) NoteListingVM(此视图模型具有一个属性,让我们将其命名为TableRefID)
In the ViewInvoice i have an expander with it's dataContext set to (NoteListingVM) to show some notes that are linked with the specific invoiceID 在ViewInvoice中,我有一个扩展器,其dataContext设置为(NoteListingVM)以显示与特定invoiceID链接的一些注释
I have a problem when i try the following 我尝试以下操作时遇到问题
<Expander Header="NOTES" DockPanel.Dock="Top" Foreground="{StaticResource AlternateForeGround}">
<DockPanel>
<DockPanel.DataContext>
<WendBooks:NoteListingVM TableRefID="{Binding InvoiceID}" x:Name="TransactionNotes"></WendBooks:NoteListingVM>
</DockPanel.DataContext>
A 'Binding' cannot be set on the 'TableRefID' property of type 'NoteListingVM'. 不能在“ NoteListingVM”类型的“ TableRefID”属性上设置“绑定”。 A 'Binding' can only be set on a DependencyProperty of a DependencyObject. 只能在DependencyObject的DependencyProperty上设置“绑定”。
so as the error said, i cannot use a property. 如错误所述,我无法使用属性。
Then i think to use a DependencyProperty. 然后,我想使用DependencyProperty。 But DependencyProperty cannot work properly in ViewModels if you implement an InotifyPropertyChanged. 但是,如果实现InotifyPropertyChanged,则DependencyProperty将无法在ViewModels中正常工作。 ( and this is what most users suggest when you implement a ViewModel - "INotifyPropertychanged") (这是大多数用户在实施ViewModel时的建议-“ INotifyPropertychanged”)
DependencyPropertys are work well when you have a userControl or CustomControl. 当您拥有userControl或CustomControl时,DependencyPropertys可以很好地工作。 But this is not my case(i dont have a usercontrol or customControl i only have a ViewModel that i want to assign / pass "parameter" to the NoteListingViewModel when the InvoiceID changed) 但这不是我的情况(当InvoiceID更改时,我没有要分配/传递“参数”给NoteListingViewModel的ViewModel,我没有userControl或customControl。)
so how i will send the InvoiceID (only xaml) to the NoteListingViewModel to filter and show only notes that are link to the current invoice i have front on me? 因此,我如何将InvoiceID(仅xaml)发送到NoteListingViewModel进行过滤并仅显示与当前发票相关联的注释,而这些注释却在我眼前? what is the proper way? 正确的方法是什么? i am sure something i missed or misunderstand the mvvm pattern? 我确定我错过或误解了mvvm模式吗?
Don't do it that way. 不要那样做。 Do it in a viewmodel-centric way instead: Make the NoteListingVM
a property of the parent viewmodel. 而是以以视图模型为中心的方式进行操作:将NoteListingVM
设置为父视图NoteListingVM
的属性。
Instead of structuring your application as a tree of views which own viewmodels that struggle to know what they need to about each other, make it a tree of viewmodels that own their own relationships. 与其将您的应用程序构建为拥有视图模型的视图树,而这些视图模型很难了解彼此之间的需求,而应将其构建为拥有自己关系的视图模型树。 Festoon them with views that don't need to know about anything but their own viewmodels. 用他们自己的视图模型将不需要的其他信息添加到花彩中。
Note that the InvoiceID
property below updates Notes.InvoiceID
when it changes. 请注意,下面的InvoiceID
属性在更改时会更新Notes.InvoiceID
。 Easy as pie. 易如反掌。
public MyViewModel()
{
Notes = new NoteListingVM();
}
private int _invoiceID = 0;
public int InvoiceID
{
get { return _invoiceID; }
set
{
if (value != _invoiceID)
{
_invoiceID = value;
Notes.InvoiceID = this.InvoiceID;
OnPropertyChanged();
}
}
}
private NoteListingVM _notes = null;
public NoteListingVM Notes
{
get { return _notes; }
protected set
{
if (value != _notes)
{
_notes = value;
OnPropertyChanged();
}
}
}
XAML. XAML。 You could wrap a DockPanel
around the ContentControl
if you want. 如果需要,可以将DockPanel
包裹在ContentControl
周围。
<Expander
Header="NOTES"
DockPanel.Dock="Top"
Foreground="{StaticResource AlternateForeGround}"
>
<ContentControl Content="{Binding Notes}" />
</Expander>
You could also write a NotesView
UserControl
that has an InvoiceID
dependency property, and bind that in the XAML. 您还可以编写具有InvoiceID
依赖项属性的NotesView
UserControl
,并将其绑定到XAML中。 It would use the same NoteListingVM
; 它将使用相同的NoteListingVM
; you'd assign that via the DataContext
property just as you've been doing. 您可以像以前一样通过DataContext
属性进行分配。 The user control's InvoiceID
dependency property would have a change handler that updates the viewmodel's InvoiceID
, which would let you use a binding to set the InvoiceID
. 用户控件的InvoiceID
依赖项属性将具有一个更改处理程序,用于更新视图模型的InvoiceID
,这将使您可以使用绑定来设置InvoiceID
。 That's a "proper XAML" way to do what you originally had in mind. 这是做您最初打算的“适当的XAML”方法。
You could also entirely rewrite NoteListingVM
as a UserControl
, but that's more work and I don't see a whole lot of point to it. 您也可以将NoteListingVM
完全重写为UserControl
,但这还需要更多工作,我对此没有多大意义。
You don't mix viewmodel/ INotifyPropertyChanged
properties with dependency properties in the same class. 您不要在同一类中将viewmodel / INotifyPropertyChanged
属性与依赖项属性混合使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.