Page 1 of 2
MVVM: how to pass constructor variables from the ViewModel to the View
Posted: Tue Dec 12, 2017 1:16 pm
by wriedmann
Hi (probably Nick again),
I have a rather strange need:
the composition of a View depends from data from the ViewModel. But how to pass these parameters from the ViewModel before the InitializeComponent() call?
Maybe I have to explain better: I have to define some measures for a door component, and the number and name of these variables depends on the data in the ViewModel (I show only two variants - there can be 0, 1 or 2 couples of variables, both external and internal):
- einfach.png (7.04 KiB) Viewed 705 times
- doppelt.png (9.64 KiB) Viewed 705 times
It is absolutely no problem building my views depending on only two parameters, but what is the right way in MVVM to do something like this?
This is only the first time I encounter such a problem, but it will be common issue in my WPF business applications and one of the possibilities that I have from building my views in code.
Thank you for any hint!
Wolfgang
MVVM: how to pass constructor variables from the ViewModel to the View
Posted: Tue Dec 12, 2017 2:43 pm
by NickFriend
Hi Wolfgang,
Not quite sure I understand where the problem is. The visibility of each pair can be bound to a boolean property in the VM, so after you've fired up the VM, the property can be set to true for each pair to be shown, and the appropriate controls become visible.
If there was an infinite possible number of pairs, you'd probably do something fancy with a dictionary or something like that, but since it's precisely 0, 1 or 2 I'd keep it simple with two properties, Pair1Visible and Pair2Visible and then a boolean to visibility converter to bind to the controls on the View.
No need to pass any info in the View constructor.
But I may be missing something here.
Nick
MVVM: how to pass constructor variables from the ViewModel to the View
Posted: Tue Dec 12, 2017 2:47 pm
by wriedmann
Hi Nick,
the problem is that the View has to be built depending on these two values of the ViewModel:
if there is only one value pair, the View contains only 2 textboxes (the minimum) and if there are 4 pairs, the View contains 4x 2 textboxes.
So the View needs to be read the parameters from the ViewModel before actually building the controls.
And this is a very common scenario in my applications: depending on the person that is using the application controls are shown or not, or sometimes it depends on the type of data if controls are there or not.
Wolfgang
MVVM: how to pass constructor variables from the ViewModel to the View
Posted: Tue Dec 12, 2017 2:59 pm
by NickFriend
Maybe this comes from the way you build your views in code, but from here it looks fairly normal in that you need to hide/show controls based on the contents of the VM.
So build the view with the maximum number of pairs of boxes (ie all 4 pairs), but with the visibility of each pair tied to a boolean value in the VM. So when the View is being constructed, the property value will automatically be false (the VM isn't connected to the View yet), so none of the 4 pairs will be visible. Once the VM is running and connected to the View as its DataContext, then you can set the visibility of each pair depending on the data in the VM - as you set each property to true for those pairs that are to be shown, the controls become visible on the View.
Visually you'll get an effect of a slight pause as the View shows with just space where the textboxes are, then as the VM gets its data and sets the properties the controls become visible.
The other way would be to send a message from the VM once it's ready - the View can intercept that message and call a method to set up the textboxes either referencing the VM as necessary (at that point you know the VM is available through the DataContext), or else by including the required parameters as data within the message. That way you don't need to hide/show the controls. However I think that straight forward binding to the VM ought to be able to handle it.
Nick
MVVM: how to pass constructor variables from the ViewModel to the View
Posted: Tue Dec 12, 2017 3:11 pm
by wriedmann
Hi Nick,
thank you very much!
It looks like I have to use the "message" method, and build the windows controls only when the message from the ViewModel is fired. In this case, I could pass the parameters directly in the message.
MVVM sometimes makes the life harder than needed <g>.
Thank you again for all your help and time!
Wolfgang
MVVM: how to pass constructor variables from the ViewModel to the View
Posted: Tue Dec 12, 2017 4:12 pm
by NickFriend
Hi Wolfgang,
Whatever works best for you. Though I still don't see why you can't use a normal binding to the visibility. This pattern of showing/hiding controls in a View based on values in the VM is completely standard.
Nick
MVVM: how to pass constructor variables from the ViewModel to the View
Posted: Tue Dec 12, 2017 4:38 pm
by wriedmann
Hi Nick,
I prefer the message method because the window changes the appearance completely based on the number of value pair. This is true not only for the names of the values, but also for the labels on the View.
Therefore I prefer to build the window contents when the message from the ViewModel comes in.
With WPF I'm able to build very, very flexible layouts....
Wolfgang
MVVM: how to pass constructor variables from the ViewModel to the View
Posted: Tue Dec 12, 2017 4:43 pm
by NickFriend
Hi Wolfgang,
Fair enough. I think it may come more naturally for me to do it the binding way because I also keep all text that's used in my views in the VM. All labels are already set by binding to VM properties, so changing labels on the fly is very easy.
Bye
Nick
MVVM: how to pass constructor variables from the ViewModel to the View
Posted: Tue Dec 12, 2017 4:52 pm
by wriedmann
Hi Nick,
thank you again for all your time!
In my VO applications, sometimes I move controls around based on the contained data or on the current user.
A sample is the article input mask: if the program is started in the Italian version, the Italian description is before the German one, and if the program is started in the German version, the Italian description field is showed below the German one (because for everyone it is important to have its own mothers language first).
I have no doubts that this is possible also with DataBinding, but I feel it is more natural to have layout logic in the View itself.
And the next step are completely dynamic windows, where the ViewModel dictates the controls that are shown on the View (in my VO applications, such a window is used over and over and saves a lot of time and code)
Wolfgang
MVVM: how to pass constructor variables from the ViewModel to the View
Posted: Tue Dec 12, 2017 5:56 pm
by Phil Hepburn
Guys,
Have I missed something in this story ?
Surely whether you have 1, 2, 3, or 4 controls is data, and con be placed in the 'Model'.
The VM then uses this Yes/No data as and when needed.
Sorry if this does not help - have been out of WPF and data binding for some months now.
From a distance it sounds to me that you may be mixing up your 'degree of separation'.
You could be making life difficult for yourself because you are not using Mark-Up script - yes, the dreaded XAML.
Best regards, and Good Luck,
Phil.