Getting Silverlight MVVM working with Expression Blend design-time data?

I am a big proponent of the MVVM template with Silverlight. I am currently connecting the ViewModel to View, updating the ViewModel in the code behind the view, this way:

public partial class SomePage : UserControl { public SomePage() { InitializeComponent(); // New up a ViewModel and bind to layout root var vm = new SomeViewModel(); LayoutRoot.DataContext = vm; } } 

And then all the binding is processed in the view, and all the logic is processed in the ViewModel, as the template suggests.

However, connecting these devices means that the designer is not working well, and I cannot use the Expression Blend design-time data. I know that there are libraries, such as MVVM Light, that will help get all of this, but I prefer not to contribute the library, as this is “one more thing” to deal with.

Is there a simple template for connecting MVVM in Silverlight while maintaining designer functionality, especially in Blend? I did some Googling, but there are so many legacy articles and so much confusion between WPF and Silverlight and older versions that I find it hard to find to use.

By the way. I am focusing on SL4 with VS2010, if that matters.

+4
source share
3 answers

There are several methods you can use.

First , let the designer take samples of sample data and development-time attributes (i.e. d: DataContext). In your code, you simply set the view model binding:

 if (!DesignerProperties.IsInDesignTool) { var vm = new SomeViewModel(); LayoutRoot.DataContext = vm; } 

Second , you can have a special watch time model that you associate:

 LayoutRoot.DataContext = DesignerProperties.IsInDesignTool ? new DesignViewModel() : new MyViewModel(); 

Finally , another way is to manage the data in the view model. I don’t like this because it distributes responsibility among all view models, but you have higher accuracy:

 // constructor private Widget[] _designData = new[] { new Widget("Test One"), new Widget("Test Two") }; public MyViewModel() { if (DesignerProperties.IsInDesignTool) { MyCollection = new ObservableCollection<Widget>(_designData); } else { MyService.Completed += MyServiceCompleted; MyService.RequestWidgets(); } } private void MyServiceCompleted(object sender, AsynchronousEventArgs ae) { // load up the collection here } 

Hope this helps!

+3
source

What you are looking for is Blendibility . MVVM Light has the concept of ViewModelLocator, and I use it in a project with excellent results.

Here's a great Roboblob post on this topic. http://blog.roboblob.com/2010/01/17/wiring-up-view-and-viewmodel-in-mvvm-and-silverlight-4-blendability-included/ This post has an approximate solution, so it really helps in understanding. Rob is improving the implementation of MVVM Light, and I think this is a good job.

+2
source

I had similar problems when developing WPF applications. One trick I found out is to declare xmlns so you can embed an array of objects in XAML:

 xmlns:coll="clr-namespace:System.Collections;assembly=mscorlib" 

Then you can remove the ArrayList in just XAML:

 <coll:ArrayList x:Key="questions"> <local:QuestionItem Title="FOO"></local:QuestionItem> </coll:ArrayList> 

Then you can set the ItemsSource grid, listbox, etc. to array:

 <ListBox x:Name="lstStuff" ItemsSource="{StaticResource questions}" /> 

This method allows you to "view" the appearance of the list controls in the designer. It does not solve all the problems with the visual prototype, but it has come a long way and can be adapted to several different scenarios.

You could, for example, declare your local namespace as xmlns, and then remove the mocks of your ViewModel in the Resources window or control. I have not tried this, but theoretically you could get a full time preview.

+1
source

All Articles