0

how do i bind a property declared in a viewmodel to take value from another viewModel?

let me explain

i have 2 ViewModels (Implements INotifyPropertyChanged) and 1 View

InvoiceView ( just my invoice design no matter if is a user control or window or a dataTemplate)

InvoiceViewModel

NoteListingVM (this viewmodel has a property let's name it 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

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'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

so as the error said, i cannot use a property.

Then i think to use a DependencyProperty. But DependencyProperty cannot work properly in ViewModels if you implement an InotifyPropertyChanged. ( and this is what most users suggest when you implement a ViewModel - "INotifyPropertychanged")

DependencyPropertys are work well when you have a userControl or CustomControl. 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)

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? what is the proper way? i am sure something i missed or misunderstand the mvvm pattern?

1 Answer 1

2

Don't do it that way. Do it in a viewmodel-centric way instead: Make the NoteListingVM a property of the parent viewmodel.

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. 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. You could wrap a DockPanel around the ContentControl if you want.

<Expander Header="NOTES" DockPanel.Dock="Top" Foreground="{StaticResource AlternateForeGround}" > <ContentControl Content="{Binding Notes}" /> </Expander> 

Alternate

You could also write a NotesView UserControl that has an InvoiceID dependency property, and bind that in the XAML. It would use the same NoteListingVM; you'd assign that via the DataContext property just as you've been doing. 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. That's a "proper XAML" way to do what you originally had in mind.

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.

You don't mix viewmodel/INotifyPropertyChanged properties with dependency properties in the same class.

Sign up to request clarification or add additional context in comments.

4 Comments

aha:) i guess you are right , but is this the proper way to follow when you have such requirement ? shouldn't be more convenient and acceptable path if you keep your central View Model separate from the other ViewModels? (either if they have some logic between of them or not ) just thinking.. ( thought that this what MVVM pattern is and dose.) somehow...
@user2160275 Who told you that? What problem are you trying to avoid by hiding your viewmodels from each other?
yes i think.. is this wrong?(correct me) , ( when we say hiding them i mean that why the InvoiceVM need to know that i have the NotesVM ? ) simply i have a view with 2 ViewModels and i expect to share values between of them without ViewModels know each other ..
@user2160275 I just did correct you. If you don't want to listen, that's your choice. Good luck.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.