Click here to Skip to main content
12,406,687 members (55,320 online)
Click here to Skip to main content

Tagged as

Stats

48.9K views
32 bookmarked
Posted

MvvmCross - v3 - Writing a First App

, 23 Mar 2013 Ms-PL
MvvmCross - A CrossPlatform MVVM Sample
Images
AnMvvmCross4.png
TipCalc_Android.png
TipCalc_Android_Styled.png
TipCalc_Sketch.png
TipCalc_Store_Designer.png
TipCalc_Store_Emu.png
TipCalc_Summary.png
TipCalc_Touch_Design.png
TipCalc_Touch_Outlet.png
TipCalc_Touch_Sim.png
TipCalc_WP_Designer.png
TipCalc_WP_Emu.png
TipCalc_Wpf_Designer.png
TipCalc_Wpf_Run.png
<h1>
    MvvmCross TipCalc - Step6 Creating a WPF UI</h1>
<h2>
    Introduction</h2>
<p>
    This article is step&nbsp;6 in the TipCalc tutorial for MvvmCross v3 - Hot Tuna!</p>
<h2>
    The story so far...</h2>
<div id="wiki-content">
    <div class="wrap">
        <div class="gollum-markdown-content instapaper_body" id="wiki-body">
            <div class="markdown-body">
                <div id="wiki-content">
                    <div class="wrap">
                        <div class="gollum-markdown-content instapaper_body" id="wiki-body">
                            <div class="markdown-body">
                                <div id="wiki-content">
                                    <div class="wrap">
                                        <div class="gollum-markdown-content instapaper_body" id="wiki-body">
                                            <div class="markdown-body">
                                                <div id="wiki-content">
                                                    <div class="wrap">
                                                        <div class="gollum-markdown-content instapaper_body" id="wiki-body">
                                                            <div class="markdown-body">
                                                                <div id="wiki-content">
                                                                    <div class="wrap">
                                                                        <div class="gollum-markdown-content instapaper_body" id="wiki-body">
                                                                            <div class="markdown-body">
                                                                                <p>
                                                                                    We started with the goal of creating an app to help calculate what tip to leave in a restaurant</p>
                                                                                <p>
                                                                                    We had a plan to produce a UI based on this concept:</p>
                                                                                <p>
                                                                                    <img alt="Sketch" src="https://raw.github.com/slodge/MvvmCross/v3/v3Tutorial/Pictures/TipCalc_Sketch.png"></p>
                                                                                <p>
                                                                                    To satisfy this we built a &#39;Core&#39; Portable Class Library project which contained:</p>
                                                                                <ul>
                                                                                    <li>
                                                                                        our &#39;business logic&#39; - <font color="#000000"><code>ICalculation</code> </font></li>
                                                                                    <li>
                                                                                        our ViewModel - <font color="#000000"><code>TipViewModel</code> </font></li>
                                                                                    <li>
                                                                                        our <font color="#000000"><code>App</code> which contains the application wiring, including the start instructions.</font></li>
                                                                                </ul>
                                                                                <p>
                                                                                    We&#39;ve then three User Interfaces - for Xamarin.Android, Xamarin.iOS and WindowsPhone:</p>
                                                                                <p>
                                                                                    <img alt="Android" src="https://raw.github.com/slodge/MvvmCross/v3/v3Tutorial/Pictures/TipCalc_Android_Styled.png"><img alt="v1" src="https://raw.github.com/slodge/MvvmCross/v3/v3Tutorial/Pictures/TipCalc_Touch_Sim.png"><img alt="v1" src="https://raw.github.com/slodge/MvvmCross/v3/v3Tutorial/Pictures/TipCalc_WP_Emu.png"><img alt="v1" src="https://raw.github.com/slodge/MvvmCross/v3/v3Tutorial/Pictures/TipCalc_Store_Emu.png"></p>
                                                                                <p>
                                                                                    For our next project, let&#39;s shift to Windows Desktop - via WPF - Windows Presentation Framework.</p>
                                                                                <p>
                                                                                    Here we&#39;ll build up a new project &#39;from empty&#39;, just as we did for the Core, Android, iOS, WindowsPhone and WindowsStore projects.</p>
                                                                                <p>
                                                                                    Obviously, to work with WPF, you will need to be working on the PC with Visual Studio</p>
                                                                                <h2>
                                                                                    Create a new WPF Project</h2>
                                                                                <p>
                                                                                    Add a new project to your solution - a &#39;WPF Application&#39; with name <code><font color="#000000">TipCalc.UI.Wpf</font></code></p>
                                                                                <p>
                                                                                    <strong>Important</strong> - make sure this is at least <strong>.Net4.5</strong> - as this is the version required for PCL Profile104 - <em>goodbye, XP!</em></p>
                                                                                <p>
                                                                                    Within this, you&#39;ll find the normal Wpf application constructs:</p>
                                                                                <ul>
                                                                                    <li>
                                                                                        the &#39;Properties&#39; folder with the &#39;AssemblyInfo&#39; file, some resources and a settings file</li>
                                                                                    <li>
                                                                                        the &#39;App.Config&#39; configuration file</li>
                                                                                    <li>
                                                                                        the App.Xaml &#39;application&#39; object</li>
                                                                                    <li>
                                                                                        the MainWindow.Xaml and MainWindows.Xaml.cs files that define the default Window for this app</li>
                                                                                </ul>
                                                                                <h2>
                                                                                    Keep MainWindow.xaml</h2>
                                                                                <p>
                                                                                    We do actually want a <font color="#000000"><code>MainWindow</code> for this app :)</font></p>
                                                                                <h2>
                                                                                    Add references</h2>
                                                                                <h3>
                                                                                    Add references to CoreCross and MvvmCross - PCL versions</h3>
                                                                                <p>
                                                                                    Add references to the new project for the portable libraries:</p>
                                                                                <ul>
                                                                                    <li>
                                                                                        <strong>Cirrious.CrossCore.dll</strong>
                                                                                        <ul>
                                                                                            <li>
                                                                                                core interfaces and concepts including Trace, IoC and Plugin management</li>
                                                                                        </ul>
                                                                                    </li>
                                                                                    <li>
                                                                                        <strong>Cirrious.MvvmCross.dll</strong>
                                                                                        <ul>
                                                                                            <li>
                                                                                                Mvvm classes - including base classes for your views and viewmodels</li>
                                                                                        </ul>
                                                                                    </li>
                                                                                </ul>
                                                                                <p>
                                                                                    Normally these will be found in a folder path like <em>{SolutionRoot}/Libs/Mvx/Portable/</em></p>
                                                                                <h3>
                                                                                    Add a reference to MvvmCross - Wpf specific version</h3>
                                                                                <p>
                                                                                    Add a reference to the new project for the Wpf specific library:</p>
                                                                                <ul>
                                                                                    <li>
                                                                                        <strong>Cirrious.MvvmCross.Wpf.dll</strong></li>
                                                                                </ul>
                                                                                <p>
                                                                                    This extends the functionality of its PCL counterpart with Wpf specific additions.</p>
                                                                                <p>
                                                                                    Normally this will be found in a folder path like <em>{SolutionRoot}/Libs/Mvx/Wpf/</em></p>
                                                                                <h3>
                                                                                    Add a reference to TipCalc.Core.csproj</h3>
                                                                                <p>
                                                                                    Add a reference to your <font color="#000000"><code>TipCalc.Core</code> project - the project we created in the last step which included:</font></p>
                                                                                <ul>
                                                                                    <li>
                                                                                        your <font color="#000000"><code>Calculation</code> service, </font></li>
                                                                                    <li>
                                                                                        your <font color="#000000"><code>TipViewModel</code> </font></li>
                                                                                    <li>
                                                                                        your <font color="#000000"><code>App</code> wiring.</font></li>
                                                                                </ul>
                                                                                <h2>
                                                                                    Add a Setup class</h2>
                                                                                <p>
                                                                                    Just as we said during the Android, iOS, WP and WindowsStore construction <em>Every MvvmCross UI project requires a <font color="#000000"><code>Setup</code> class</font></em></p>
                                                                                <p>
                                                                                    This class sits in the root namespace (folder) of our UI project and performs the initialisation of the MvvmCross framework and your application, including:</p>
                                                                                <ul>
                                                                                    <li>
                                                                                        the Inversion of Control (IoC) system</li>
                                                                                    <li>
                                                                                        the MvvmCross data-binding</li>
                                                                                    <li>
                                                                                        your <font color="#000000"><code>App</code> and its collection of <code>ViewModel</code>s</font></li>
                                                                                    <li>
                                                                                        your UI project and its collection of <font color="#000000"><code>View</code>s</font></li>
                                                                                </ul>
                                                                                <p>
                                                                                    Most of this functionality is provided for you automatically. Within your Wpf UI project all you have to supply is:</p>
                                                                                <ul>
                                                                                    <li>
                                                                                        your <font color="#000000"><code>App</code> - your link to the business logic and <code>ViewModel</code> content</font></li>
                                                                                </ul>
                                                                                <p>
                                                                                    For <font color="#000000"><code>TipCalc</code> here&#39;s all that is needed in Setup.cs:</font></p>
                                                                                <pre>
<code><font color="#000000">using System.Windows.Threading;
using Cirrious.MvvmCross.ViewModels;
using Cirrious.MvvmCross.Wpf.Platform;
using Cirrious.MvvmCross.Wpf.Views;

namespace TipCalc.UI.Wpf
{
    public class Setup : MvxWpfSetup
    {
        public Setup(Dispatcher uiThreadDispatcher, IMvxWpfViewPresenter presenter) : base(uiThreadDispatcher, presenter)
        {
        }

        protected override IMvxApplication CreateApp()
        {
            return new Core.App();
        }
    }
}
</font></code></pre>
                                                                                <h2>
                                                                                    Modify the App.xaml.cs to use Setup</h2>
                                                                                <p>
                                                                                    There are other lifecycles and display techniques that you can use to write Wpf apps.</p>
                                                                                <p>
                                                                                    However, here we will just use a &#39;one window with one view&#39; approach.</p>
                                                                                <p>
                                                                                    To achieve this, add some lines to the WPF <font color="#000000"><code>App</code> class that:</font></p>
                                                                                <ul>
                                                                                    <li>
                                                                                        <p>
                                                                                            provide a private flag to determine if setup has already been done</p>
                                                                                        <pre>
<code><font color="#000000">private bool _setupComplete = false;
</font></code></pre>
                                                                                    </li>
                                                                                    <li>
                                                                                        <p>
                                                                                            perform the setup - using a <font color="#000000"><code>Simple</code> presenter based on <code>MainWindow</code></font></p>
                                                                                        <pre>
<code><font color="#000000">private void DoSetup()
{
    var presenter = new MvxSimpleWpfViewPresenter(MainWindow);

    var setup = new Setup(Dispatcher, presenter);
    setup.Initialize();

    var start = Mvx.Resolve&lt;IMvxAppStart&gt;();
    start.Start();

    _setupComplete = true;
}
</font></code></pre>
                                                                                    </li>
                                                                                    <li>
                                                                                        <p>
                                                                                            override the <font color="#000000"><code>OnActivated</code> event to perform this startup</font></p>
                                                                                        <pre>
<code><font color="#000000">protected override void OnActivated(System.EventArgs e)
{
    if (!_setupComplete)
        DoSetup();

    base.OnActivated(e);
}
</font></code></pre>
                                                                                    </li>
                                                                                </ul>
                                                                                <p>
                                                                                    After you&#39;ve done this your <font color="#000000"><code>App.xaml.cs</code> might look like:</font></p>
                                                                                <pre>
<code><font color="#000000">using System.Windows;
using Cirrious.CrossCore.IoC;
using Cirrious.MvvmCross.ViewModels;
using Cirrious.MvvmCross.Wpf.Views;

namespace TipCalc.UI.Wpf
{
    public partial class App : Application
    {
        private bool _setupComplete = false;

        private void DoSetup()
        {
            var presenter = new MvxSimpleWpfViewPresenter(MainWindow);

            var setup = new Setup(Dispatcher, presenter);
            setup.Initialize();

            var start = Mvx.Resolve&lt;IMvxAppStart&gt;();
            start.Start();

            _setupComplete = true;
        }

        protected override void OnActivated(System.EventArgs e)
        {
            if (!_setupComplete)
                DoSetup();

            base.OnActivated(e);
        }
    }
}
</font></code></pre>
                                                                                <h2>
                                                                                    Add your View</h2>
                                                                                <h3>
                                                                                    Create the UserControl</h3>
                                                                                <p>
                                                                                    Create a Views folder</p>
                                                                                <p>
                                                                                    Within this folder, add a new &#39;User Control (WPF)&#39; and call it <code><font color="#000000">TipView.xaml</font></code></p>
                                                                                <p>
                                                                                    The page will generate:</p>
                                                                                <ul>
                                                                                    <li>
                                                                                        TipView.xaml</li>
                                                                                    <li>
                                                                                        TipView.xaml.cs</li>
                                                                                </ul>
                                                                                <h3>
                                                                                    Turn TipView into the MvvmCross View for TipViewModel</h3>
                                                                                <p>
                                                                                    Open the TipView.cs file.</p>
                                                                                <p>
                                                                                    Change the class to inherit from <code><font color="#000000">MvxWpfView</font></code></p>
                                                                                <pre>
<code><font color="#000000">public partial class TipView : MvxWpfView
</font></code></pre>
                                                                                <p>
                                                                                    To link <font color="#000000"><code>TipView</code> to <code>TipViewModel</code> create a <code>public new TipViewModel ViewModel</code> property - exactly as you did in Xamarin.Android, Xamarin.iOS, WindowsPhone and WindowsStore:</font></p>
                                                                                <pre>
<code><font color="#000000">public new TipViewModel ViewModel
{
    get { return (TipViewModel) base.ViewModel; }
    set { base.ViewModel = value; }
}
</font></code></pre>
                                                                                <p>
                                                                                    Altogether this looks like:</p>
                                                                                <pre>
<code><font color="#000000">using Cirrious.MvvmCross.Wpf.Views;
using TipCalc.Core.ViewModels;

namespace TipCalc.UI.Wpf.Views
{
    public partial class TipView : MvxWpfView
    {
        public new TipViewModel ViewModel
        {
            get { return (TipViewModel)base.ViewModel; }
            set { base.ViewModel = value; }
        }

        public TipView()
        {
            InitializeComponent();
        }
    }
}
</font></code></pre>
                                                                                <h3>
                                                                                    Edit the XAML layout</h3>
                                                                                <p>
                                                                                    Double click on the XAML file</p>
                                                                                <p>
                                                                                    This will open the XAML editor within Visual Studio.</p>
                                                                                <p>
                                                                                    Just as with the WindowsPhone and WindowsStore, I won&#39;t go into much depth at all here about how to use the XAML or do the Windows data-binding. I&#39;m assuming most readers are already coming from at least a little XAML background.</p>
                                                                                <p>
                                                                                    Change the root node from:</p>
                                                                                <pre>
<code><font color="#000000">&lt;UserControl 
         ...
&lt;/UserControl&gt;
</font></code></pre>
                                                                                <p>
                                                                                    to:</p>
                                                                                <pre>
<code><font color="#000000">&lt;views:MvxWpfView 
         xmlns:views=&quot;clr-namespace:Cirrious.MvvmCross.Wpf.Views;assembly=Cirrious.MvvmCross.Wpf&quot;
         ...
&lt;/views:MvxWpfView&gt;
</font></code></pre>
                                                                                <p>
                                                                                    To add the XAML user interface for our tip calculator, we will add exactly the same XAML as we added inside the <font color="#000000"><code>ContentPanel</code> grid for the WindowsStore example. This includes:</font></p>
                                                                                <ul>
                                                                                    <li>
                                                                                        a <font color="#000000"><code>StackPanel</code> container, into which we add: </font>
                                                                                        <ul>
                                                                                            <li>
                                                                                                some <font color="#000000"><code>TextBlock</code> static text</font></li>
                                                                                            <li>
                                                                                                a bound <font color="#000000"><code>TextBox</code> for the <code>SubTotal</code> </font></li>
                                                                                            <li>
                                                                                                a bound <font color="#000000"><code>Slider</code> for the <code>Generosity</code> </font></li>
                                                                                            <li>
                                                                                                a bound <font color="#000000"><code>TextBlock</code> for the <code>Tip</code> </font></li>
                                                                                        </ul>
                                                                                    </li>
                                                                                </ul>
                                                                                <p>
                                                                                    This will produce finished XAML like:</p>
                                                                                <pre>
<code><font color="#000000">&lt;views:MvxWpfView 
             xmlns:views=&quot;clr-namespace:Cirrious.MvvmCross.Wpf.Views;assembly=Cirrious.MvvmCross.Wpf&quot;
             xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
             xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
             x:Class=&quot;TipCalc.UI.Wpf.Views.TipView&quot;&gt;
    &lt;StackPanel&gt;
        &lt;TextBlock
                    Text=&quot;SubTotal&quot;
                    /&gt;
        &lt;TextBox 
                    Text=&quot;{Binding SubTotal, Mode=TwoWay}&quot; 
                    /&gt;

        &lt;TextBlock
                    Text=&quot;Generosity&quot;
                    /&gt;
        &lt;Slider 
                    Value=&quot;{Binding Generosity, Mode=TwoWay}&quot; 
                    SmallChange=&quot;1&quot; 
                    LargeChange=&quot;10&quot; 
                    Minimum=&quot;0&quot; 
                    Maximum=&quot;100&quot; /&gt;

        &lt;TextBlock
                    Text=&quot;Tip&quot;
                    /&gt;
        &lt;TextBlock 
                    Text=&quot;{Binding Tip}&quot; 
                    /&gt;
    &lt;/StackPanel&gt;
&lt;/views:MvxWpfView&gt;
</font></code></pre>
                                                                                <p>
                                                                                    <strong>Note</strong> that in XAML, <font color="#000000"><code>OneWay</code> binding is generally the default. To provide TwoWay binding we explicitly add <code>Mode</code> to our binding expressions: e.g. <code>Value=&quot;{Binding Generosity,Mode=TwoWay}&quot;</code></font></p>
                                                                                <p>
                                                                                    In the designer, this will look like:</p>
                                                                                <p>
                                                                                    <img alt="Designer" src="https://raw.github.com/slodge/MvvmCross/v3/v3Tutorial/Pictures/TipCalc_Wpf_Designer.png"></p>
                                                                                <h2>
                                                                                    The Wpf UI is complete!</h2>
                                                                                <p>
                                                                                    At this point you should be able to run your application.</p>
                                                                                <p>
                                                                                    When it starts... you should see:</p>
                                                                                <p>
                                                                                    <img alt="Designer" src="https://raw.github.com/slodge/MvvmCross/v3/v3Tutorial/Pictures/TipCalc_Wpf_Run.png"></p>
                                                                                <p>
                                                                                    This seems to work perfectly, although you may notice that if you edit the value in the <font color="#000000"><code>SubTotal</code> TextBox then you rest of the display does not correctly update.</font></p>
                                                                                <p>
                                                                                    This is a View concern - it is a UI problem. So we can fix it just in the Wpf UI code - just as we did in the WindowsPhone and WindowsStore examples.</p>
                                                                                <h2>
                                                                                    Moving on...</h2>
                                                                                <p>
                                                                                    There&#39;s more we could do to make this User Interface nicer and to make the app richer... but for this first application, we will leave it here for now.</p>
                                                                                <p>
                                                                                    And actually... that&#39;s the end of our journey through this first app.</p>
                                                                                <p>
                                                                                    One day soon there will be more steps - a step for Mac desktop, a step for XBox, a step for TV, etc - but for now this is the end.</p>
                                                                            </div>
                                                                        </div>
                                                                    </div>
                                                                </div>
                                                            </div>
                                                        </div>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<h2>
    History</h2>
<p>
    22nd March 2013 - First&nbsp;Submission</p>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

slodge
Software Developer Cirrious Ltd
United Kingdom United Kingdom
Developing software since 1982. Currently engrossed in both cloud and mobile technologies. Currently spending far too much time on MvvmCross... and loving every second of it Smile | :)

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.160730.1 | Last Updated 23 Mar 2013
Article Copyright 2013 by slodge
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid