MVVMLight and ModernUI Part 1 - Setup

MVVMLight and ModernUI Part 1 - Setup

 

 

At Yahara Software, we have implemented several Windows projects using the ModernUI library as well as MVVMLight alongside our internal service/data access layer and framework.  I really like ModernUI because it provides a functional and attractive shell for Windows applications and takes care of a lot of the styling and consistency issues for you.

For implementation of the Model/View/ViewModel pattern, we have been using Laurent Bugnion’s MVVMLight Toolkit for a while now.  It really helps implement MVVM in a consistent and orthodox manner without having to resort to workarounds.

This series of posts is intended to help with initial setup of a ModernUI-based app with the MVVMLight toolkit.  A following post will walk through implementation of navigation using the Messenger, as well as design-time view models

Setup

1.       File/New Project/WPF Application


 

2.       Right click the solution, select “Manage NuGet Packages for Solution”


 

3.       Click “Online”, search for “MVVMLight” and install the latest version of MVVM Light

4.       Now search for “ModernUI”.  As of this writing, the one we want is the second on the list, the “ModernUI for WPF” by First Floor Software.  Install this package.

Implement ModernUI

The example in this blog post is a simple window with two controls; the steps below are pretty much the same as the “My First Modern UI App” tutorial. You can get a lot more information on ModernUI and access more advanced tutorials on their site, http://mui.codeplex.com/.

1.       Build the project

2.       Modify the MainWindow xaml as follows to change it to a ModernWindow

 

<mui:ModernWindow x:Class="ModernUI_MVVMLight.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mui="http://firstfloorsoftware.com/ModernUI"

        Title="MainWindow" Height="350" Width="525">

    <Grid>

       

    </Grid>

</mui:ModernWindow>

 

3.       Modify MainWindow.xaml.cs as follows to set the class to inherit from the MUI “ModernWindow

using FirstFloor.ModernUI.Windows.Controls;

 

namespace ModernUI_MVVMLight

{

    /// <summary>

    /// Interaction logic for MainWindow.xaml

    /// </summary>

    public partial class MainWindow : ModernWindow

    {

        public MainWindow()

        {

            InitializeComponent();

        }

    }

}

 

4.       Add styling by modifying the App.xaml file as follows.  Note MVVMLight has put some content in this file already – we’ll discuss that shortly:

<?xml version="1.0" encoding="utf-8"?>

<Application x:Class="ModernUI_MVVMLight.App"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             StartupUri="MainWindow.xaml"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:vm="clr-namespace:ModernUI_MVVMLight.ViewModel"

             mc:Ignorable="d">

    <Application.Resources>

        <ResourceDictionary>

            <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />

            <ResourceDictionary.MergedDictionaries>

                <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.xaml" />

                <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.Light.xaml"/>

            </ResourceDictionary.MergedDictionaries>

        </ResourceDictionary>

    </Application.Resources>

</Application>

5.       Compile and run the app, it should result in a blank window with the ModernUI style

6.       Add some content navigation to the MainWindow.xaml – it’s all XAML in ModernUI:

<mui:ModernWindow x:Class="ModernUI_MVVMLight.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mui="clr-namespace:FirstFloor.ModernUI.Windows.Controls;assembly=FirstFloor.ModernUI"

        xmlns:presentation="clr-namespace:FirstFloor.ModernUI.Presentation;assembly=FirstFloor.ModernUI"

        Title="MainWindow" Height="350" Width="525">

    <mui:ModernWindow.MenuLinkGroups>

        <presentation:LinkGroup DisplayName="Views">

            <presentation:LinkGroup.Links>

                <presentation:Link DisplayName="View 1"/>

                <presentation:Link DisplayName="View 2"/>

            </presentation:LinkGroup.Links>

        </presentation:LinkGroup>

    </mui:ModernWindow.MenuLinkGroups>

</mui:ModernWindow>

7.       When you run this, you’ll get the basic window with nav (although it doesn’t go anywhere yet)

Add the Views using MVVMLight

The next steps will add some views into the shell, and rig them up with MVVMLight.

1.       Create a “Views” folder in your solution and then add two Views to it:


2.       Create a ViewModel class for each of the Views, in the ViewModel folder:


3.       Add a property to each ViewModel to provide data for binding, and initialize it in the default constructor.  Each of the ViewModel classes should look like this:

namespace ModernUI_MVVMLight.ViewModel

{

    public class View1ViewModel

    {

        public View1ViewModel()

        {

            Info = "This is View 1";

        }

 

        public string Info { getset; }

    }

}

4.       Now add the ViewModels to the ViewModelLocator, which is found in the “ViewModel” folder.  This is a class that was added by the MVVMLightToolkit NuGet package.  Essentially, you are doing two things to this class for your new ViewModels:

a.       Adding ViewModel instances to the Inversion of Control container (MVVMLight comes with a SimpleIoC that works fine if you don’t have another IoC container)

b.      Adding a public property for each ViewModel that can be used by the views to get an instance of their VM declaratively

    public class ViewModelLocator

    {

        /// <summary>

        /// Initializes a new instance of the ViewModelLocator class.

        /// </summary>

        public ViewModelLocator()

        {

            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

 

...

 

            // ViewModel registration

            SimpleIoc.Default.Register<MainViewModel>();

            SimpleIoc.Default.Register<View1ViewModel>();

            SimpleIoc.Default.Register<View2ViewModel>();

        }

 

        // Public accessors for ViewModels

        public MainViewModel Main { get { return ServiceLocator.Current.GetInstance<MainViewModel>(); } }

        public View1ViewModel View1 { get { return ServiceLocator.Current.GetInstance<View1ViewModel>(); } }

        public View2ViewModel View2 { get { return ServiceLocator.Current.GetInstance<View2ViewModel>(); } }

       

...

    }

5.       In View1.xaml and View2.xaml, add the call to the ViewModelLocator to get the DataContext.  This is a line of code that goes in the UserControldeclaration, which will now look like this:

<UserControl x:Class="ModernUI_MVVMLight.Views.View1"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             mc:Ignorable="d"

             d:DesignHeight="300" d:DesignWidth="300"

             DataContext="{Binding View1, Source={StaticResource Locator}}">

    <Grid>

           

    </Grid>

</UserControl>

Essentially, this is setting up a reference to a Static Resource that is declared in the App.xaml file.  When the application starts up, the static resource is created, which creates an instance of the ViewModelLocator and attaches it as a static (singleton) instance to the application.  Any xaml file in the app can reference this by it’s key, “Locator”.  The “Binding” statement is the property of the Locator object that is being bound as the DataContext.

 

6.       To wrap up the UserControls and exercise our binding, add a control to each of the Views to display it’s Info property value

    <Grid>

        <Label Content="{Binding Info}" />

    </Grid>

 

7.       Finally, we need to tie the new views into ModernUI’s navigation, established in MainWindow.xaml.  You can also set a default view using the “ContentSource” property on the ModernWindow declaration.

 

            <presentation:LinkGroup.Links>

                <presentation:Link DisplayName="View 1" Source="Views/View1.xaml"/>

                <presentation:Link DisplayName="View 2" Source="Views/View2.xaml"/>

            </presentation:LinkGroup.Links>

What’s Next

This concludes the initial setup of the sample app.  In the next part, I’ll add some navigation using commands and the MVVMLight Messenger.

No Comments