Silverlight communication/commands/events? between view and viewmodel? - silverlight

I am just getting into the Silverlight world, and wish I didn't learn WPF first so I wouldn't be so frustrated with the little things that are missing.
In WPF I was using commands (RoutedUICommand) for my view/UI to handle "events" (by event I mean something the user did) and passing them to the viewmodel.
Now in silverlight I find that I can't do it that way and on top of that there doesn't seem to be a consensus. I dislike putting code in my codebehind for my views but I keep finding myself having to do so, unless I am willing to subclass damn near every usercontrol I use. Or write a million lines of xaml for a one line codebehind statement.
And even then, I don't konw If I should use events, commands, or what seems like the best fit for me the LocalMessageSender/LocalMessageReceiver.
bottom line, is there a generally accepted approach for what must be a very common situation: telling the viewmodel what the user did?
Oh im using SL 4 if that matters.

is there a generally accepted approach for what must be a very common situation: telling the viewmodel what the user did?
Yes its called binding.
When it comes to button clicks in Silverlight 4 you should be looking at exposing a property on your ViewModel that has the type ICommand, you can then use a standard Binding on things like Button Command property.

Related

Is there a better way than handling CommandBindings in code behind?

I have an application using MVVM. I'm trying to Intercept key presses on an MCE Remote control for Play, Pause, Stop etc....
Currently I'm using command bindings with a method in the code behind performing the related action on a media element as such
<Window.CommandBindings>
<CommandBinding Command="MediaCommands.Play" Executed="PlayMediaElement"/>
<CommandBinding Command="MediaCommands.Stop" Executed="StopMediaElement"/>
</Window.CommandBindings>
Before trying to include the remote control functionality I had approx 10 view-models/views with nothing in code behind.
I'm wondering if there is a better way to do this so I retain the MVVM pattern or is it perfectly acceptable/preferable to implement in this way.
EDIT - I've moved the Command Bindings from a UserControl inside a View into my MainWindow.xaml and placed the methods into MainWindow.xaml.cs. MainWindow doesn't have a view/viewmodel relationship, simply a content control with a ViewModel linked to it.
In my code behind methods I'm making use of a Mediator to send messages (Play,Pause,Stop etc...) to my mediaplayerviewmodel which in turn interacts with it's respective view. Is this a good idea or is there a better way?
I think Josh Smith created a huge confusion in his 2009 article, when he made a point that his code-behind CS files remained mostly empty. MVVM is not about not having code-behind. It is about separation of concerns. If there is any practical rule you should follow, is to make the ViewModel view agnostic (i.e. no reference from the ViewModel to the View. Think having a second unit test implementation of a 'View' for your ViewModel).
This "no code behind" confusion caused very odd structures just to work arround a problem that shouldn't have existed to begin with.
Having code behind in the MainWindow.xaml.cs is perfectly reasonable solution, as long as you don't have logic there, but simply forward the call to an appropriate method in the View Model. If that was my code I would have created custom commands (a la DelegateCommand from the same article) that binds directly to commands in the ViewModel, but your design is 100% legit as well.
Head over to Codeplex.com and look for Caliburn (or better Caliburn Micro). It extends WPF to actually allow calling of methods with arbitrary parameters pulled from other objects and the method being in the view model / controller without having a "hook method" in code behind just fowwarding the call.
The extensions can do wonderfull thignsl ike pull the value of a textbox and pass it as parameter to a method, then react on the return value - much like a view should.
You run in a limitation of "stock" wpf - which simply can only point towards method handlers in code behind without any regards to parameters. Alterantives exist, even from microsoft.

Why does my WPF view not work without code-behind when applied through a DataTemplate?

I'm working on a large WPF project using MVVM. We're currently still deciding the extent to which we'll use code-behind, but so far we've gotten along fine with none at all (except for InitializeComponent on windows). However, I recently started using typed DataTemplates to apply views to my view models, and it seems these views, like windows, do not work without the InitializeComponent call, when, according to this article, I thought they would. The DataTemplate just declares a view. When I delete the view's code-behind file, the view model renders completely blank. When I leave it in, it's fine. Any ideas why I might be seeing this behavior?
First, you may be overlooking something important: I used that article heavily when learning MVVM/WPF as well, and I never thought it suggested eliminating InitializeComponent calls from the View.cs.
In fact, doing a quick search reveals the following (under Relaying Command Logic) [emphasis mine]:
Every view in the app has an empty
codebehind file, except for the
standard boilerplate code that calls
InitializeComponent in the class's
constructor.
I've been applying the same pattern you describe while leaving the default code-behind for each view in place, and so far it's smooth sailing. :)
Further: If you check out the definition for the default InitializeComponent(), you'll see that the generated code contains the following statement:
System.Windows.Application.LoadComponent(this, resourceLocater);
I haven't tested to make sure this is the case, but I'll wager a fiddle of gold against your soul that preventing that line from executing is going to affect the rendering of your view... ;)
According to djacobson, even the solution by Josh Smith that I referenced in my question cannot render its views without the code-behind, so the line stating this can be done is misleading. It seems the only way to avoid code-behind for your views is by not putting them into UserControls at all, but just keeping the XAML directly within a < DataTemplate > tag.

Multiple "sibling" controls, one-at-a-time visible, MVVM

I've got what I think is a fairly simple problem in Silverlight, and I'd like to solve it using MVVM principles, largely as a way of enhancing my own understanding.
Let's say I have a simple LOB app that's designed to let me load up and edit a single Employee (just an example, for the sake of explanation). In my example, Employee is made up of a number of complex objects - an Employee has a ContactInfo, a Skillset, an EmploymentHistory, an AwardsEarned, etc. The idea is that I can have this app load up a single employee and get access to a number of different editor screens. Each component of an Employee has its own editor screen.
Visually, the app just ha a left-hand nav bar and a main view on the right side. The nav bar just lets me type in an employee number and load it into memory as the "active" employee. It has a simple list of links - clicking a link should load the appropriate editor screen on the right side.
There are a couple concepts that I don't think I understand well enough, and I'm having trouble proceeding. I know there's always more than one way to skin a cat, especially when it comes to WPF/Silverlight/XAML/MVVM, but I'm having trouble thinking through all the different concepts and their repurcussions.
View-First or ViewModel First
After much thinking about MVVM, what seems most natural to me is the concept of viewmodel composition that Josh Smith seems to promote in his often-quoted article. It seems like the idea here is that you literally model your UI by composing viewmodels together, and then you let the viewmodels render themselves via typed DataTemplates. This feels like a very good separation of concerns to me, and it also makes viewmodel communication very direct and easy to understand.
Of course, Silverlight doesn't have the DataType property on DataTemplates, to many complaints: one, two. Regardless, what I see promoted much more often than viewmodel composition is a more view-first design, where the viewmodel for the view is typically instantiated in the view's XAML or via a DI container, meaning that you can't hand it any parameters. I'm having a really hard time understanding this: how is a ViewModel supposed to serve a Model to a View if I never get to tell it what data is in the model? Reaching through a view to get to its viewmodel doesn't seem to make sense either. I'm very hazy in this area but it seems the accepted answer "use a mediator/lightweight messaging framework." I'm just going through some tutorials now on the messaging system in MVVMLight and I'll be looking at similar stuff, if for nothing else than simply to understand the concepts, but if anyone can shed some light on this I'd very much appreciate it. Anything involving Unity/Prism or MEF is valid, but I haven't gotten that far in my quest for knowledge yet :-)
Instantiating Views and Selecting Them
Theoretically (I say that because SL doesn't support DataTemplate DataType), the viewmodel composition approach could make this very simple. I could have the right side of the screen be a content control whose Content property is bound to a property called ActiveEditor. A parameterized command for the hyperlinks would set ActiveEditor to a given viewmodel.
With a more view-first approach, how would I proceed with this? The first thing that comes to mind is instantiating all of the controls in the XAML of the main view.
Is manipulating the Content property of a ContentControl a good way to go for this kind of situation, or am I better off doing something like setting visibility on each individual control?
The ViewModel (VM) is written so that it is 'wired up' to the Model but has no knowledge at all of the View - in fact, this is what makes it very good to unit test (see NUnit) as it has no idea, and less does it care, whether it is being used by a UI or a Test Framework.
The VM exposes public CLR properties which implement the ICommand interface, the View, having instantiated a VM using (generally speaking anyway) its default constructor, then binds its Buttons/Hyperlinks etc to these Command properties like. So, for example, you may have a VM that exposes a CloseCommand to exit the app, the View may contain a MenuItem that binds to that command, such as:
<MenuItem Header="E_xit" Command="{Binding Path=CloseCommand}" />
Now, the VM would also expose a public ObservableCollection of objects that you want to display in your UI. Whether you populate this ObservableCollection as part of the VM constructor, or whether you do it via a UI interaction (say another Command assigned to a Button click) is up to you but the end result is that you bind a View control to this exposed ObservableCollection in XAML like:
<y:DataGrid ItemsSource="{Binding Breakdown}"/>
or equivelant for whatever control you are using to display the data (not sure off the top of my head what elements a DataGrid has in Silverlight as opposed to WPF).
Meanwhile...: The Mediator pattern is used for VM's to interact with each other, not for the View to interact with the VM. For example, you might have a custom TreeView that has its own VM on the same View as the main chart screen. In this case you could use a Mediator for the TreeView's VM to communicate with the Charts VM.
As for the last bit of your question, I think set up a basic framework using Josh Smith way in the article you mentioned and use that method to add additional ViewModels to the right hand side of your silverlight app.
Hope that helps a bit at least.

Good practice or bad practice

i am new to WPF and i have one question(the first one actually, more to come)
Is it better to add some logic, for example the bindings for the window, in xaml or in the code behind.
If you can put it in XAML, it's generally better to do that than be wiring up stuff in your codebehind.
For one thing, this lets you use tools like Expression Blend more effectively, since you have more stuff available at design time. It also further shifts view logic into the view itself, and helps you stay away from stuffing view-based code in your viewmodels or controllers.
Most people wouldn't consider a binding to be logic. Bindings should generally go in xaml. It is a good idea to put logic in a separate ViewModel class which you bind to.
It's kind of a religious debate right now. With an MVVM approach, you can essentially get away with the only code in your codebehind being the creation of your ViewModel and its assignment to your DataContext.
Even all of your event handling can be managed in your ViewModel using UI Commands.

WPF: Binding with nonstatic parameter? (newbie question)

This will probably be obvious but I can't find the best way.
I want to show the user's ToDo's in a listbox. These ToDo's are in the database and consist of an Id, UserId and Description.
The user logged in to the app.
How can I retrieve the ToDo's for that certain userId and set it up for binding to the listbox?
I was trying with an ObjectDataProvider but I cant figure out how to use that in combination with nonstatic stuff (like my _dbService, userId, language, ...).
Are the only options to make all those things static versus binding in the code behind?
If so, this means that ObjectDataProvider isn't very useful, no?
I find a lot of examples of it being used with a hardcoded parameter but I hardly see any situation where I'd need such a functionality..
I do all my WPF using the Model-View-ViewModel pattern. I've given you one link there but Google will give you loads. MVVM seems to be the standard pattern for WPF. This project is probably more complicated than you need but it is well-written and brings home the use of MVVM.
Basically, you create a Model of your data. In this case, you'd probably create a simple class (I'll call it ToDoItem) with properties Id, UserID and Description. Use your preferred mechanism to get a collection of these from the database. Link to SQL, Entity Framework, a standard query, whatever.
Then you have your ViewModel - you have an instance of the ViewModel for each instance of the Model: the VM has a reference to the M and 'forwards' properties to it. The ViewModel is what you use to manipulate the model.
Then you have your View - this is the UI. You set the DataContext of the View to be the ViewModel and then your bindings automatically bind to the ViewModel. Your View just ends up being the things you can see. All of the work gets done in the ViewModel. This means it's very easy to test.
So, when you click on a button in your View, the bindings pass this onto a Command in your ViewModel which manipulates the Model.
The UI is also a View with a ViewModel. So, your UI VM might load a collection of Models from the database and stick them in an ObservableCollection. The ListBox items collection would be bound to this ObservableCollection.
It's hard to explain all of this in a post like this. Read a couple of articles and see what you think. I'm still quite new at this, too, but I believe my reading about MVVM has paid off.
Hela Thomas, Tom here from Orbit One :)
MVVM is the way to go. I'm on my 4th project and WPF really shines if you use mvvm. You already tried MVC (or MVP as we did on recy*tyre) and that's a nice separation of concern.
MVVM takes it a step further since the viewmodel knows absolutely nothing about the view.
The view binds to the viewmodel, so it has a reference to it (2 way, super powerful and works beyond the typical MS demo). The viewmodel is just a poco and is a representation of your view, data + behaviour. Once you dig this paragraph the cool term mvvm will have no secrets.
I see if I can come up with a small demo. Maybe I'll have time later.
What I will come up with is a view (xaml, file 1) that binds to a viewmodel (file 2, a poco class, not to be mistaken with code behind). The model can be whatever you like (service layer or directly to the repositories). Using the power of 2 way binding we will bind to an observable collection meaning that if we add/delete/... something to the collection the view will pick it up without us putting energy into it.
My first 2 wpf projects was done with Caliburn Micro (see codeplex) which is a powerful framework based on conventions. It shields you away from hardcore wpf (creating tour dependency properties yourself mainly) and you can create something relatively fast without fully understanding wpf. That's a downside of itself but it worked for me. As of project 3 I started taming those dependency properties myself and it will make you a better wpf developer.
I see the question is from October.. did you find a good solution?

Resources