Skip to content

Instantly share code, notes, and snippets.

@dansiegel
Last active June 29, 2018 21:40
Show Gist options
  • Save dansiegel/226a26bb528baed4e18dcc9d5554b665 to your computer and use it in GitHub Desktop.
Save dansiegel/226a26bb528baed4e18dcc9d5554b665 to your computer and use it in GitHub Desktop.
MVVM Loading ViewModel for Design Time

Overview

The purpose of this Gist is to help provide a workaround to load a ViewModel into a Xamarin Forms View following a MVVM pattern that dynamically loads the ViewModel such as Prism. This example will be based on the use of such a project.

Getting Started

To Start Create a Build Profile in your Solution and any project containing your Views that you can use for Design Time. The name doesn't really matter, but for the purposes of this example we'll simply call it Design. You may need to do some tweaking, but the most critical is that your project containing your Views and ViewModel's should be mapped to use the Design Build Profile when using the Solution's Build Profile. The Unit Tests do not have to be built in this profile but they can depending on your needs.

Next edit the build properties for the solution containing those Views and ViewModels. You will want to define a new Compiler constant. If you copied the Debug profile you should see constants already defined like DEBUG;TRACE;. For the purposes of this example we will define the constant DESIGN.

Design Notes

For the purposes of this example it is important to note that things like the IntelliSense and Xamarin Forms Previewer do not work when services like Prism's ViewModelLocator are used. To add the ViewModel directly in Xaml will cause an exception to be thrown if you have a constructor with any parameters, after all that is why we use dependency injection. For Design time we simply want to bootstrap something together so we have the capacity to get IntelliSense or Preview our Form. There is also the fact that there may be something you are relying on to provide a value as shown below. If we did not provide a default in our DESIGN default constructor, our Message property would remain null and we would see nothing in the Previewer anyway.

It's also worth nothing that while each container is a little different some containers provide a method for allowing you to maintain multiple constructors and define which one should be used by the container. For example Unity provides the InjectionConstructorAttribute. While I don't generally support doing this, I do believe knowing how to do something is more powerful for a developer as each of us and each project has it's own requirements that may require we break our own rules from time to time.

using Xamarin.Forms;
namespace FooApp.Views
{
public partial class ViewA : ContentPage
{
public class ViewA()
{
InitializeComponent();
#if DESIGN
BindingContext = new FooApp.ViewModels.ViewAViewModel();
#endif
}
}
}
using Prism.Navigation;
namespace FooApp.ViewModels
{
public class ViewAViewModel : BindableBase, INavigatingAware
{
private INavigationService _navigationService { get; }
#if DESIGN
public ViewAViewModel()
{
Message = "Hello World";
}
#endif
public ViewAViewModel( INavigationService navigationService )
{
_navigationService = navigationService;
}
private string _message;
public string Message
{
get { return _message; }
set { SetProperty( ref _message, value ); }
}
public void OnNavigatingTo( NavigationParameters parameters )
{
Message = parameters.GetValue<string>( "message" );
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment