Click here to Skip to main content
15,879,326 members
Articles / Programming Languages / C#

MvvmCross - v3 - Writing a First App

Rate me:
Please Sign up or sign in to vote.
4.91/5 (8 votes)
23 Mar 2013Ms-PL2 min read 74.1K   34  
MvvmCross - A CrossPlatform MVVM Sample
<h1>
    MvvmCross TipCalc - Step5 Creating a Windows&nbsp;Store UI</h1>
<h2>
    Introduction</h2>
<p>
    This article is step&nbsp;5 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">
                                                                <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"></p>
                                                                <p>
                                                                    For our next project, let&#39;s shift to WindowsStore.</p>
                                                                <p>
                                                                    To create a WindowsStore MvvmCross UI, you can use the Visual Studio project template wizards, but here we&#39;ll instead build up a new project &#39;from empty&#39;, just as we did for the Core, Android, iOS and WindowsPhone projects.</p>
                                                                <p>
                                                                    Obviously, to work with WindowsStore, you will need to be working on the PC with Visual Studio</p>
                                                                <h2>
                                                                    Create a new WindowsStore Project</h2>
                                                                <p>
                                                                    Add a new project to your solution - a &#39;Blank App (XAML)&#39; application with name <code><font color="#000000">TipCalc.UI.WindowsStore</font></code></p>
                                                                <p>
                                                                    Within this, you&#39;ll find the normal WindowsStore application constructs:</p>
                                                                <ul>
                                                                    <li>
                                                                        the &#39;Assets&#39; folder</li>
                                                                    <li>
                                                                        the &#39;Common&#39; folder</li>
                                                                    <li>
                                                                        the &#39;Properties&#39; folder with just the &#39;AssemblyInfo&#39; file</li>
                                                                    <li>
                                                                        the App.Xaml &#39;application&#39; object</li>
                                                                    <li>
                                                                        the MainPage.Xaml and MainPage.Xaml.cs files that define the default Page for this app</li>
                                                                    <li>
                                                                        the &#39;Package.appxmanifest&#39; configuration file</li>
                                                                    <li>
                                                                        the debug private key for your development</li>
                                                                </ul>
                                                                <h2>
                                                                    Delete MainPage.xaml</h2>
                                                                <p>
                                                                    No-one really needs a <font color="#000000"><code>MainPage</code> :)</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 references to CoreCross and MvvmCross - WindowsStore specific versions</h3>
                                                                <p>
                                                                    Add references to the new project for the WindowsStore specific libraries:</p>
                                                                <ul>
                                                                    <li>
                                                                        <strong>Cirrious.CrossCore.WindowsStore.dll</strong></li>
                                                                    <li>
                                                                        <strong>Cirrious.MvvmCross.WindowsStore.dll</strong></li>
                                                                </ul>
                                                                <p>
                                                                    Each of these extends the functionality of its PCL counterpart with WindowsStore specific additions.</p>
                                                                <p>
                                                                    Normally these will be found in a folder path like <em>{SolutionRoot}/Libs/Mvx/WindowsStore/</em></p>
                                                                <p>
                                                                    Also, within that same folder you need to add:</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 and WO 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 WindowsStore 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 Cirrious.MvvmCross.ViewModels;
using Cirrious.MvvmCross.WindowsStore.Platform;
using Windows.UI.Xaml.Controls;

namespace TipCalc.UI.WindowsStore
{
    public class Setup : MvxStoreSetup
    {
        public Setup(Frame rootFrame) : base(rootFrame)
        {
        }

        protected override IMvxApplication CreateApp()
        {
            return new Core.App();
        }
    }
}
</font></code></pre>
                                                                <h2>
                                                                    Modify the App.xaml.cs to use Setup</h2>
                                                                <p>
                                                                    Your <font color="#000000"><code>App.xaml.cs</code> provides the WindowsStore &#39;main application&#39; object - an object which owns the User Interface and receives some callbacks from the operating system during some key events in your application&#39;s lifecycle.</font></p>
                                                                <p>
                                                                    To modify this <font color="#000000"><code>App.xaml.cs</code> for MvvmCross, we need to:</font></p>
                                                                <ul>
                                                                    <li>
                                                                        <p>
                                                                            modify the <font color="#000000"><code>OnLaunched</code> callback</font></p>
                                                                        <ul>
                                                                            <li>
                                                                                <p>
                                                                                    remove these lines</p>
                                                                                <pre>
<code><font color="#000000">    if (!rootFrame.Navigate(typeof(MainPage), args.Arguments))
    {
        throw new Exception(&quot;Failed to create initial page&quot;);
    }
</font></code></pre>
                                                                            </li>
                                                                            <li>
                                                                                <p>
                                                                                    add these lines to allow it to create <font color="#000000"><code>Setup</code>, and to then initiate the <code>IMvxAppStart</code> <code>Start</code> navigation</font></p>
                                                                                <pre>
<code><font color="#000000">var setup = new Setup(RootFrame);
setup.Initialize();

var start = Mvx.Resolve&lt;IMvxAppStart&gt;();
start.Start();
</font></code></pre>
                                                                            </li>
                                                                        </ul>
                                                                    </li>
                                                                </ul>
                                                                <p>
                                                                    To do this, you will need to add these <font color="#000000"><code>using</code> lines:</font></p>
                                                                <pre>
<code><font color="#000000">using Cirrious.CrossCore.IoC;
using Cirrious.MvvmCross.ViewModels;
</font></code></pre>
                                                                <h2>
                                                                    Add your View</h2>
                                                                <h3>
                                                                    Create an initial Page</h3>
                                                                <p>
                                                                    Create a Views folder</p>
                                                                <p>
                                                                    Within this folder, add a new &#39;Basic Page&#39; and call it <code><font color="#000000">TipView.xaml</font></code></p>
                                                                <p>
                                                                    You will be asked if you want to add the missing &#39;Common&#39; files automatically in order to support this &#39;Basic Page&#39; - answer <strong>Yes</strong></p>
                                                                <p>
                                                                    The page will generate:</p>
                                                                <ul>
                                                                    <li>
                                                                        TipView.xaml</li>
                                                                    <li>
                                                                        TipView.xaml.cs</li>
                                                                </ul>
                                                                <p>
                                                                    Within Common you will also have new files added:</p>
                                                                <ul>
                                                                    <li>
                                                                        BindableBase.cs</li>
                                                                    <li>
                                                                        BooleanNegationConverter.cs</li>
                                                                    <li>
                                                                        BooleanToVisibilityConverter.cs</li>
                                                                    <li>
                                                                        LayoutAwarePage.cs</li>
                                                                    <li>
                                                                        RichTextColumns.cs</li>
                                                                    <li>
                                                                        SuspensionManager.cs</li>
                                                                </ul>
                                                                <h3>
                                                                    Convert LayoutAwarePage into an MvvmCross base view</h3>
                                                                <p>
                                                                    Change <font color="#000000"><code>LayoutAwarePage</code> so that it inherits from <code>MvxStorePage</code></font></p>
                                                                <p>
                                                                    Change:</p>
                                                                <pre>
<code><font color="#000000">public class LayoutAwarePage : Page
</font></code></pre>
                                                                <p>
                                                                    to:</p>
                                                                <pre>
<code><font color="#000000">public class LayoutAwarePage : MvxStorePage
</font></code></pre>
                                                                <p>
                                                                    This requires the addition of:</p>
                                                                <pre>
<code><font color="#000000">using Cirrious.MvvmCross.WindowsStore.Views;
</font></code></pre>
                                                                <h3>
                                                                    Persuade LayoutAwarePage to cooperate more reasonably with the <code><strong>MvxStorePage</strong></code> base class</h3>
                                                                <p>
                                                                    Either remove the <font color="#000000"><code>region</code>:</font></p>
                                                                <pre>
<code><font color="#000000">    #region Process lifetime management

    // all sorts of &#39;stuff&#39; including
    //  OnNavigatedTo
    //  OnNavigatedFrom
    //  LoadState
    //  SaveState

    #endregion 
</font></code></pre>
                                                                <p>
                                                                    Or change the <font color="#000000"><code>OnNavigatedTo</code> and <code>OnNavigatedFrom</code> methods so that they call their base class implementations:</font></p>
                                                                <pre>
<code><font color="#000000">base.OnNavigatedTo(e);
</font></code></pre>
                                                                <p>
                                                                    and</p>
                                                                <pre>
<code><font color="#000000">base.OnNavigatedFrom(e);
</font></code></pre>
                                                                <h3>
                                                                    Turn TipView into the MvvmCross View for TipViewModel</h3>
                                                                <p>
                                                                    Open the TipView.cs file.</p>
                                                                <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 and WindowsPhone:</font></p>
                                                                <pre>
<code><font color="#000000">public new TipViewModel ViewModel
{
    get { return (TipViewModel) base.ViewModel; }
    set { base.ViewModel = value; }
}
</font></code></pre>
                                                                <p>
                                                                    Remove the <font color="#000000"><code>LoadState</code> and <code>SaveState</code> methods.</font></p>
                                                                <p>
                                                                    Altogether this looks like:</p>
                                                                <pre>
<code><font color="#000000">using TipCalc.Core.ViewModels;
using TipCalc.UI.WindowsStore.Common;

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

        public TipView()
        {
            this.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, 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>
                                                                    To add the XAML user interface for our tip calculator, we will add a <font color="#000000"><code>ContentPanel</code> Grid just above the existing <code>&lt;VisualStateManager.VisualStateGroups&gt;</code> XAML node.</font></p>
                                                                <p>
                                                                    This <font color="#000000"><code>Content Panel</code> will include <strong>almost</strong> exactly the same XAML as we added to the WindowsPhone example - only the <code>Style</code> attributes are removed:</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 XAML like:</p>
                                                                <pre>
<code><font color="#000000">    &lt;Grid x:Name=&quot;ContentPanel&quot; Grid.Row=&quot;1&quot; Margin=&quot;12,0,12,0&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;/Grid&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_Store_Designer.png"></p>
                                                                <h2>
                                                                    The Store 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_Store_Emu.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 WindowsStore UI code - just as we did in the WindowsPhone example.</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>
                                                                    Let&#39;s move on to one final piece of Windows!</p>
                                                            </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)


Written By
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 | :)

Comments and Discussions