It has become increasingly popular to use the Model-View-ViewModel (MVVM) in Silverlight. It’s easy to use the MVVM in Silverlight and it opens up for some extended testing scenarios. With Silverlight 4 we can also use some of the features from MEF (Managed Extensibility Framework). One scenario is to use MEF to load the ViewModel to a View.
How to do it
For this demo I have created a Silverlight project with a view called CustomerView.xaml and a viewmodel called CustomerViewModel.cs. The view contains an ItemsControl with an ItemTemplate that I will use to display a list of Customers and their address. I have bound the ItemsSource to the Customers property from my viewmodel.
In the code-behind of the MainPage.xaml file hosting the view, I have created a property called ViewModel. When the ViewModel property is set it will set the DataContext of our view to the provided value. I have added an Import attribute to the ViewModel. The Import attribute declare that this property relies on a service provided by some other component.
I have added an Export attribute to the CustomerViewModel class. The Export attribute declares that this class provides a particular kind of service.
To connect the components together I need to resolve the Imports and Exports. It is done by a class called CompositionContainer. In most cases you will just call CompositionInitializer.SatisfyImports method to try and provide components that export all the things you need to import.
You can write your own CompositionContainer explicitly if you want.
My viewmodel will now be resolved and an instance will be set the DataContext of the view.
This is a very simplified sample and can seem a bit like shooting birds with cannons. In larger scale you will really see the power of using this solution where your views do not need to know about its viewmodel.
This solution will let you use an other viewmodel in designtime supporting the use of using a viewmodel and Expression Blend.
On the other hand this solution will add some complexity to the project. It will be harder to follow the code and it is often not clear from looking at the code what sorts of objects you’re really using or how they were instantiated.
Get the sample code here: http://bit.ly/bxZ1Ly
In any cases you will use a WCF service to communicate with a server from your Silverlight client (in more and more cases you will probably use WCF RIA Services but that is an entirely different story).
To communicate between your client and server you need to generate a proxy. The proxy will contain the endpoint address specified as part of the service reference. In most cases the endpoint address will be localhost and it can be configured in ServiceReferences.ClientConfig.
At compile time the ServiceReferences.ClientConfig will be put into your XAP file. If you need to change the endpoint address in an other environment you need to change it inside the XAP file in the corresponding environment.
This is not a very flexible solution.
A more flexible solution
A more flexible solution would be to specify the endpoint address as part of the server configuration. And that is possible!
Instead of getting the endpoint address from ServiceReferences.ClientConfig you can sent it to the client as init parameter (initParams). When initializing the servicereference you will need to specify the binding you wish to use and the new endpoint.
In most cases you will refactor this out to some more generic methods but the point is simple and it will allow you to specify your endpoint address in a more flexible way.
Get the source code and a demo here: http://bit.ly/cPqoa6
Great VS2010 extension by Microsoft that keep zoom level in sync across all tabs.
“This extension creates a global zoom level so that if you zoom a single window, all editor instances will be updated to that zoom level. This helps a great deal if you want to use zooming during a presentation.”
Download it at http://bit.ly/9dqltR
WCF RIA Services amazing! I use it in a several Silverlight projects and keep getting amazed.
Today I got a question about retrieving data from a Stored Procedure in Silverlight using WCF RIA Services and a LINQ-to-SQL datamodel.
The LINQ-to-SQL datamodel in this sample contains a table called Book and a stored procedure called GetBooks. The stored procedure returns a list of books from the Book table and it is attached to the datamodel.
I have created a domain service that use the datamodel to return data to the Silverlight client. In the service I have created a method called GetBooks – it returns an ObservableCollection of Books.
The stored procedure return an ISingleResult of GetBooksResult. I have tried to convert the result to an ObservableCollection without success (any ideas?). To fix this issue I loop the result and add the items to a new ObservableCollection.
Finally, on the Silverlight I call my domain service (_context) and invoke the GetBooksQuery method to get the result.
I got inspiration from this blog post by Scott Gu.