Views not bound to VM and naming conventions in CM for WP7?

Topics: Bugs, Conventions
Jun 18, 2011 at 9:12 PM

Hi, sorry to bother, maybe it's just me, but I'm experiencing a blocking issue with this scenario (repro dummy solution downloadable from: http://www.filesonic.it/file/1254881394): it seems that the expected naming conventions do not work and Views do not get connected to ViewModels. Here is what I did:

  1. create a new WP7 application with VS standard template for this (7.0, it must be run on real devices);
  2. in the latest NuGet console (Vs2010 Ultimate SP1) I type: Install-Package Caliburn.Micro to install into project; installation is successful;
  3. I change App.xaml so that it just contains the bootstrapper in its resources, and its code so that it just calls InitializeComponent in its constructor;
  4. I launch the application: it works.

Now if I create a Views folder, a ViewModels folder, rename MainPage.xaml in MainView.xaml moving it under Views, and move MainPageViewModel into ViewModels, changing the namespaces accordingly, the application no more starts up: it just closes unexpectedly as it evidently cannot find the main page. OK, I can live without the main page in subfolders, so back to the original configuration: it works. How is it that? I suppose the naming convention should work like in other platforms (in WPF I could do the same with success).

Another (probably related) issue: keeping the working structure, I create Views and ViewModels folders, and add a dummy V and VM into them. I then have a button in the main view which when clicked causes the VM to navigate (via navigation service) to this newly created V with its underlying VM. I can effectively view the target, but its data context is null: no VM was apparently located and bound to it, so I cannot interact as expected. Again, this is due to some naming conventions? Or what else? Please see the repro solution for the names and locations of these files (essentially: Views/AlphaView and ViewModels/AlphaViewModel; namespaces: PhoneApp1.Views.AlphaView and PhoneApp1.ViewModels.AlphaViewModel; navigation from main: _navigation.Navigate(new Uri("/Views/AlphaView.xaml", UriKind.RelativeOrAbsolute))).

Thank you!


Jun 19, 2011 at 12:27 AM

Mathetes,

Yea I noticed the same thing but I just settled for using a MainPage and MainPageViewmodel at the root of the application, doesn't hurt anything, also placed my MainPageModelStorage.cs file in the root as well... probably don't have to but for simplicity.. I am sure the naming convention has something to do with it.  You can add your own pattern to it if its critical to you.  Not necessarily a bug.

For navigation give _navigation.UriFor<AlphaViewModel>().Navigate() a whirl.  Since CM is more of a ViewModel first oriented framework pretty much everthing starts at the ViewModel and moves forward from there.
If you need to include parameter values with the navigation...   _navigation.UriFor<AlphaViewModel>().WithParams<SomeObject>( x = x.SomePropertyInSomeObjectClass, SomePropertyInSomeObjectClass).Navigate();
SomePropertyInSomeObjectClass this value is a property or variable in the calling ViewModel.  Also note that the property named will be automagically set to the value that is passed through via the navigation service.

UriFor builds your navigation Uri and if you need the params it will build the querystring for you.

reference the HelloWP7 application for this as well.

Morgan.

Jun 19, 2011 at 7:48 AM

Thank you Morgan! As for navigation, I did not know about the new UriFor, every addition towards a more viewmodel-centric architecture is welcome :). Anyway,  even if I use UriFor, I keep getting a view (AlphaView) without viewmodel (AlphaViewModel): probably it's just a matter of naming conventions, and effectively I can see that in the WP7 sample all the views and viewmodels are in the root and named like SomethingPage and SomethingPageViewModel.

As for the target page, I tried the following with my dummy sample and none worked; what I'm missing there?

  1. renamed V and VM to AlphaPage and AlphaPageViewModel, keeping them in folders and namespaces Views and ViewModels: no success.
  2. removed the Views and ViewModels namespace but kept the V and VM in those folders: no success.
  3. moved V and VM to the root, so that now they resemble the sample app: AlphaPage.xaml and AlphaPageViewModel.cs in the root, with namespace PhoneApp1 (the root namespace). Still, no success. So what is the convention I am supposed to use? Googling around I always find (mostly non-WP7) samples where the convention is simply SomethingView and SomethingViewModel.
Jun 19, 2011 at 8:52 AM

Hi Mathetes,

I just had a look at your repro.
As for MainPage, you can certainly move the page in Views NS and the VM in the ViewModel NS. Since it is the start page, however, you have to tweak Properties\WMAppManifest.xml file like this:

...
<Tasks>
      <DefaultTask  Name ="_default" NavigationPage="Views\MainPage.xaml"/>
</Tasks>
...

This instructs the phone platform of the location of the starting page.

As for you second issue (AlphaViewModel not picked up correcly), it was due to a missing registration of the VM in the container.
You just have to add

container.PerRequest<AlphaViewModel>();

in the bootstrapper's Configure method. 

Jun 19, 2011 at 9:05 AM

A little clarification: unlike SL, in WP7 apps Caliburn.Micro can't take complete control of root model creation (due to some limitation in navigation infrastructure), so it relies on the system creating the intended page, then it attaches the correct VM.
The same goes when the platform restore the last active page after resuming a tombstoned app: the phone will create the view instance on the first place, so CM can just bind the related VM afterwards.
For this reason, the pages participating in the app navigation history are basically handled in a view-first fashion (UriFor syntax is just a convenience mean to build a view uri).
You CAN, however, use model-first composition to build the content of more complex pages which may need some sub-VM to support its behavior.

Jun 19, 2011 at 10:08 AM

Thank you very much! As for the 2nd issue it was my fault, I forgot to add the registration because I was still used to the previous CM sample bootstrapper with its "register all". Thanks again.