How to utilize MVVM in Unity? - c#

Someone asked me to implement MVVM in Unity and I'm sure they were not happy with my version, so I'm trying to clear things out and improve.
I know what MVC or MVVM stands for. But in Unity the "View" and "ViewModel" blur in scope. I'm not sure what does specific developers expect when they want to see a "ViewModel" in Unity.
It's more of a clear separation for MVC in Unity for me, but I have no idea what people expect when they want to see a "ViewModel".
Does it mean the Button will also have the logic script? Which sometimes seems like a horrible break of SRP when your button also initializes bullets.
Question: How to utilize MVVM in Unity?
Thank you.

ViewModel:
I'd expect a ViewModel to:
Be a component.
Contain properties.
Allow Views to be subscribed to receive updates whenever the value of a property changes.
View:
A View in Unity on the other hand would be a component that causes something to be drawn on the screen, or is used for receiving the user's input, such as a Button or a Renderer.
The command pattern can be used to handle button clicks in MVVM: bind a button to an ICommand or delegate type property in a ViewModel, and execute it when the button is clicked.

Related

Open EditAppointmentDialog MVVM

I currently have a viewmodel such that it has a grid full of appointments. I would like to double click and open up my CalendarView with the editappointmentdialog opened for the record that was selected. May I ask how would I do that in an MVVM style?
I searched the internet and found this RadScheduleViewCommands.EditAppointment.Execute(appointment, this.scheduleView); but I don't have access to the scheduleView object from the MVVM. May I ask how abouts I should do this?
I think I can achieve this if I relay it back to the view, but I'm trying to look for another approach.
The issue you have is that you can't open a view from a view model as it'll break the MVVM design pattern.
There are a couple of ways you can open a view from the view model without too much hassle:
Implement a Messenger service to publish an event to the view, like MVVMLight does.
Straight up add a Click event handler on your button and open the view in the code behind (It's still view code after all).
However my preferred method is to use an ICommand, or RelayCommand. I have written a repository on GitHub which demonstrates how to achieve this.

Navigation MVVM

My attempts at trying to stick with the MVVM design pattern has left me spinning in my tracks. I have a view that is a pick list of site locations. I have a viewmodel that the view gets its data context from and I've bound some items to it with buttons and such (yay!).
Now I'm trying to switch the current view from a button click from within the view.
By clicking on the "start maintenance" button I would like to switch the view to another view with a different viewmodel.
So I know MVVM is just a design pattern and there seems to be a bajillion different ways of implementing navigation with MVVM. But the majority of these solutions I've seen point to having a main navigation pane and that is not what i am intending to do.
I plan on now trying to use a viewmodellocator with MVVM light messenger pattern to try and get my views to change. But after spending the past 3 days trying to shoehorn this thing to work, I'm growing desperate. Are there any other suggestions on how to implement this? I do like Sheridan's answer to a similar post:WPF MVVM navigate views because it avoids using a toolkit/framework. But I think the answer was perhaps too vague for me and I couldn't implement it because I didn't understand how to change the views (Sheridan's custom relay message was hard to follow as a novice).
Help please you Internet Denizens! :) If you could point me to any examples that would appreciated as well!
A big thank you to Rachel! I created a mainviewmodel that instantiates the other view models in my app. Then I used MVVM light to send a message using a template of a generic object to stuff the message between the models which then allowed me to handle the message in my main view model and switch the viewmodel context!
Thanks for all the help!

How do I keep the MVVM pattern while implementing lookup dialogs?

I am in the process of recreating a Win32 (Delphi 5) screen using WPF in C# with the MVVM pattern. The purpose is to create a demo that I can use to push my company to make the move from Delphi 5 to C#. In this demo I want to do things the "right" way so we have a good example to start with. With that in mind, I am trying to adhere to MVVM as strictly as possible which is where I am currently running in to a problem.
In the original program/screen we have lookup dialogs that we can attach to edit boxes and grid cells. The way it works is that the lookup dialog is an implementation of a specific search (i.e. Customer lookup). When you attach the lookup dialog to a control, it listens to the key press events for the control. It has a progressive search feature so that when you start typing, if it can find results that start with what you are typing it will insert the first result in control you attached it to. While doing this it keeps the cursor where you were typing and highlights the part of the data that you typed in so that if you keep typing it can narrow down the results to find the more specific answer you were looking for. Where the dialog part comes in to play is when you hit the ellipse button next to the control or if you type in something that it couldn't find while doing the progressive search. In either of those cases it will bring up the lookup gui which will show you all the possible results, provide filters to help you narrow your search down etc. This gui is visually attached to the control you assigned it to. It always pops up right under the cell or edit box etc that you assigned it to.
So this lookup dialog is throwing me off when it comes to trying to figure out how to implement it using MVVM. So far my code mostly pure as far as MVVM goes. The only code in the Views code behind is the one line creating the ViewModel and assigning it to its DataContext. The ViewModel makes no references to the view. But with this lookup dialog the lines seem a little blurred to me. I envision the lookup having it's own ViewModel. When you lookup something, say an Item to be put in a Sales Order, we may want to get information like the Item's price from the lookup so that it can be copied in to the Sales Order record. So to do that the main ViewModel for the screen needs to know about the lookup's ViewModel. The View for the main screen needs to know about the View for the lookup too though because it has to be able to "attach" the lookup to a gui control so it can listen to key press events and know where to visually popup when it needs to be shown. I'm not sure if the code determining the visual position of the lookup should reside in the lookups ViewModel which would break the MVVM concept totally or maybe in the lookup's view's code behind which would muddy the purity of the view a bit since now the View isn't just the XAML.
The original lookup, after being created, would be given a reference to the control that it should attach to. It would then attach functions within its object to the key press and button click events (our edit boxes can have buttons built-in). When it was told to popup, it would figure out the current position of the control it is attached to so that it could figure out where to put itself. In the case of attaching it to a grid, it was actually attached to the column of the grid because there is only one instance of the lookup, and it would figure out the current position of the cell in the grid it is supposed to be popping up under.
What is the best way to do this while still staying in the realm of MVVM. I really would like to stay as "pure" as possible so I can come back later and add integration and possibly unit tests for the ViewModels in the program and these should be ViewModels that are "headless" (no View).
To make it easier to understand what I am trying to achieve I have included a picture of the screen I am recreating for my demo with the lookup shown.

How to change control template from the view model in WP7?

Hi basically I've been able to completely seperate my logic into a view model with the exception of one thing. I have a a button and two different templates that can be applied to the button. Basically when audio is playing one template is displayed and when its not the other is displayed. When I was using the code behind this was easy because I had access to the page's Resources and all I had to do was set it accordingly. Now that my code is in the VM though I'm not really sure how to change the template.
The first thought that comes to mind is to maybe send a message to the view to change it when I need to. Is this the only way? I did see that WPF had triggers which looks pretty nice because you don't have to send messages and no code is placed in the code behind. Has anyone found a work around for this?
You can probably write a ValueConverter that would look at a public bool IsPlaying property and transform it to the appropriate template. Then you can databind your Button template property to the IsPlaying property, using the converter as a translator.
I haven't tried this with templates, but I've used it to great success with Bitmap and Visibility, so I'm pretty sure it would work here as well.
Here's a good intro to ValueConverter, if you haven't used one before.
That said, messaging isn't such a horrible solution in this case. Sometimes there is code that just wants to live in the codebehind file. Animation start/stop code is another example that comes to mind.

How to open a Dialog Window using MVVM

Can someone please help me work out how to open a Dialog Window,
the simplest scenario I can think of is:
We have a main window with a button and a Label,
when the user presses that button,
a dialog window with a text box and 2 buttons appear,
one button says submit,
when the user presses submit it closes the window,
it changes the color of the mainwindows background to red,
and takes the input placed in the textbox and changes a label on the main window to that content(I am bot so much worried about this part I get how to do this part),
while the other button just cancels the operation,
Assume that the Datacontext of the MainWindow and DialogWindow is MainWindowViewModel and UserInputViewModel respectivily.
Now on this link Cameron talks about using a service, ie IDialogService and DialogService
now could someone please explain to me how to implement those methods in the scenario above? Or if there is another way to do this then please let me know?
Please don't link me to any to any pages because I've probably read them all and I can't seem to get a clear understanding of what is meant to be happening?
~Slowly loosing his sanity because MVVM makes things so much harder :(
Not really an answer, but I think I'll add my POV anyway. How to use dialogs in an MVVM way, is something no one has really managed to do in an elegant fashion yet. There's basically 3 camps:
(1) The people who use an dialogservice like you described,
(2) The people who thinks that MVVM is good, but not something you should spent countless of hours trying to get right, so they use the codebehind, and
(3) people like me, who thinks that more often than not, the dialog and the parentview are so tied together that they should share viewmodels (as-in, the dialog is just one way of showing the data from your viewmodel).
The learning curve for MVVM can be slightly steeper when attempting to do something a little more advanced than simple data binding. Have you checked out the MVVM Light toolkit? It includes a Messenger class that facilitates sending messages around the place. A listener registers for messages they want, and a sender just publishes them. In this manner, neither the listener or sender know about each other, but can communicate. Meaning the View can register for a message, and the ViewModel can send one.
This question talks about doing something very similar to what you want to do. I recommend the MVVM Light toolkit by the way!
I'm not sure about how you use the results of a dialog to send them through to the ViewModel. I'm assuming the harder part for you is communicating from the VM to the View.

Categories