Thursday, September 24, 2009

View-Model first data binding problem

I recently had a problem concerning data binding in silverlight and prism. When I used the view-first approach everything worked fine. When I used the view-model first approach nothing seemed to work.

public MyViewModel(IMyView view)
View = view;View.SetModel(this);
Use r = new User();
User.Username = "TestUser";

After long hours of head busting and searching for an answer, I found one. After creating a bare bones test app, I noticed a very enlightening error. But first let’s see how I got there. Well first all the typical PRISM stuff happens. Created shell, added the module to the module catalog programmatically, register the interfaces and implementations with the unity container, and then the interesting part:

() => Container.Resolve<IMyViewModel>().View);

The dependency injection container resolved the view model, which means it created an instance of the view model based on the interface you specified. But notice the method header below:

public MyViewModel(IMyView view) 

The dependency injection container (unity in this case, part of PRISM) detects in the method header that an instance of IMyView is needed and goes ahead and creates one, then injects it into the method as the view parameter. At this point, the data context for the view is not yet set, since the constructor does not take care of that (we created the SetModel method for that, which is in the view). So what did I do? I set the View property, and then set the data context of the view, and then I instantiate all my data objects. Frustratingly, this seemingly working code, does not work. Why…? Mind you we are taking the view-model first approach. On the flipside, the view first approach, things would look like this:

rm.RegisterViewWithRegion(“TestRegion”, typeof(IMyView));

public MyView(IMyViewModel viewModel)
this.DataContext = viewModel;

Unity would resolve the IMyView interface, instantiating the view first, but then noticing the IMyViewModel in the method header would first instantiate the view model, and all it’s associated data objects, and second pass it as a parameter to the constructor of the view, and third, the data context is set in the constructor of the view. Well after realizing this, it’s not so difficult anymore, let’s compare the flow of code and see what the problem is.

View-Model first (broken)

  1. Resolve IMyViewModel
  2. Begin instantiation of MyViewModel
  3. Resolve IMyView from MyViewModel constructor.
  4. Instantiate MyView, then return.
  5. Set the MyView data context.
  6. Create data objects. 

View first (working)

  1. Resolve IMyView
  2. Begin instantiation of MyView.
  3. Resolve IMyViewModel from MyView constructor   
  4. Begin to instantiate MyViewModel
  5. Create data objects in MyViewModel, then return.
  6. Set the views data context, in the views constructor.

If you notice that the last to steps in the broken code are reversed. Then you guessed it! Calling the SetModel method after all the data objects we are binding to are created solves the problem.

Tuesday, September 22, 2009

Virtual PC 7 Auto Publish

Now this is cool. The new version of Virtual PC allows you to publish application to the host OS. I found my Published apps in the virtual pc folder in the start menu, under the name of my virtual machine. On a side note, if your running a Windows 7 virtual machine and want to have an application published, you will need to have a shortcut in the “all users” start menu. This basically means that you need to go to “C:\Program Data\Microsoft\Windows\Star Menu” and create/paste a shortcut in that location, which is the hidden location of the all users start menu, that does not give you an access denied message. Thanks Microsoft for making that so clear!

Does anyone know why the text looks so weird in auto published applications? It seems like there is no anti-aliasing.

Example Prism App

As part of testing, i developed a simple prism silverlight application. Ok I know it doesn’t do much (anything). But hey look I got views, ok scratch that, I have one view, and plus I’m using merged resource dictionaries, with a toolkit theme.

I’m unsure as to what the best project structure is. This is what I got so far. It would be great to have some comments on namespace and project structure.


Share it