Click here to Skip to main content
15,867,594 members
Articles / Mobile Apps / Windows Phone 7

Apex Part 1: Create Your First MVVM Application

Rate me:
Please Sign up or sign in to vote.
5.00/5 (16 votes)
21 May 2012CPOL5 min read 63.7K   1.5K   76   12
Write your first MVVM application in ten minutes using the Apex SDK!

The Series

This is part of a series of articles on Apex and MVVM:

  1. Apex Part 1: Create Your First MVVM Application
  2. Apex Part 2: Adding Commands to an MVVM Application

What Is Apex?

Apex is a framework that I have written for rapidly building MVVM applications in WPF, Silverlight or Windows Phone 7.

I have published a few articles that have touched on topics relating to Apex - and one that describes its internals in some detail. In this series, I'm going to be showing you how to actually use Apex to build real-world applications with the MVVM design pattern.

Look familiar? I have a couple of other articles that relate to the basics of MVVM and the internals of Apex - this covers some of the same ground but is the baseline for a series of articles that will be covering new ground!

Video Article

Each of these articles will have an associated video. The video below contains the content of this article - if that's your preferred way of working, then you will miss very little by watching the video rather than reading the text.

Click the image or link below to go straight to the video:

Image 1

http://youtu.be/m4cx9w5fiwk

Getting Started

To get started with Apex, you'll want to download the Apex SDK. The Apex SDK installs the Apex binaries into the Global Assembly Cache and also adds some new features to Visual Studio. You can get the Apex SDK from the front page of the project home page:

Once you have downloaded the SDK, install it - this will add the extensions to Visual Studio.

Your New Project

Create a new WPF application and call it 'Contacts'. We're going to create a simple application that shows the details of a list of contacts. Now that we have the new application, go to 'Project > Add New Item'. We're going to create our first ViewModel - a ViewModel for a Contact. You'll see that there are some new items in the C# group - choose 'Apex ViewModel' and name it ContactViewModel.cs.

Image 2

When we create a new ViewModel, we get the options below:

Image 3

These options are only used to create some example code in the ViewModel. We can create one of each of the following:

A Notifying Property

A NotifyingProperty is a property that will update a UI element that it is bound to. When you change the value of a notifying property programmatically, visual elements that represent it are automatically updated and vice versa. This is the key element to Apex.

An Observable Collection

An observable collection is a collection that works in a similar way to a notifying property - it updates the associated view automatically when it is changed.

A Command

A Command is an object that allows an element of user interface to invoke a function of a view model. We'll see more about these later.

In this case, we don't need any example properties. Now if we're going to represent a Contact, we'll need some properties. We're keeping this example really simple, so we're just going to have a Name and Birthday property. We can rapidly create notifying properties by keying in 'apexnp' and pressing tab twice. 'apexnp' is a snippet for 'Apex Notifying Property' - it'll give us something like below (key in 'Name' first, then press tab and key in 'string' as the type):

C#
/// <summary>
/// The NotifyingProperty for the Name property.
/// </summary>
private NotifyingProperty NameProperty =
    new NotifyingProperty("Name", typeof(string), default(string));

/// <summary>
/// Gets or sets Name.
/// </summary>
/// <value>The value of Name.</value>
public string Name
{
    get { return (string)GetValue(NameProperty); }
    set { SetValue(NameProperty, value); }
}      

This is how notifying properties look - part of their design is to try and emulate now DependencyProperties are defined, to keep things familiar.

We also need a property for the Birthday:

C#
/// <summary>
/// The NotifyingProperty for the Birthday property.
/// </summary>
private NotifyingProperty BirthdayProperty =
    new NotifyingProperty("Birthday", typeof(DateTime), DateTime.Today);

/// <summary>
/// Gets or sets Birthday.
/// </summary>
/// <value>The value of Birthday.</value>
public DateTime Birthday
{
    get { return (DateTime)GetValue(BirthdayProperty); }
    set { SetValue(BirthdayProperty, value); }
}

This is enough for a Contact ViewModel - it has the key properties and they are defined as notifying properties, which means that we will be able to bind to them.

The Main ViewModel

Now add a new ViewModel to the application and call it 'MainViewModel'. This is going to be the ViewModel for the main view of the application - showing a list of contacts and a selected contact. We'll need a list of contacts in the main viewmodel - and we'll need the view to update when it changes, so it'll have to be an Observable Collection. You can use 'apexoc' as the snippet to create an ObservableCollection, just like below:

C#
/// <summary>
/// The Contacts observable collection.
/// </summary>
private ObservableCollection<ContactViewModel> ContactsProperty =
    new ObservableCollection<ContactViewModel>();

/// <summary>
/// Gets the Contacts observable collection.
/// </summary>
/// <value>The Contacts observable collection.</value>
public ObservableCollection<ContactViewModel> Contacts
{
    get { return ContactsProperty; }
} 

The last property we'll need on the main ViewModel is a property to represent the selected contact. Add a new notifying property of type 'ContactViewModel' - don't forget to use the snippet 'apexnp'!

C#
/// <summary>
/// The NotifyingProperty for the SelectedContact property.
/// </summary>
private NotifyingProperty SelectedContactProperty =
    new NotifyingProperty("SelectedContact", 
    typeof(ContactViewModel), default(ContactViewModel));

/// <summary>
/// Gets or sets SelectedContact.
/// </summary>
/// <value>The value of SelectedContact.</value>
public ContactViewModel SelectedContact
{
    get { return (ContactViewModel)GetValue(SelectedContactProperty); }
    set { SetValue(SelectedContactProperty, value); }
}

We now have the two key ViewModels - the next step is to create the views.

Creating the Views

From 'Project > Add New Item', add a new 'Apex View' and call it 'MainView'. This is going to be the presentation layer for the MainViewModel. Because of this, we need to make sure the ViewModel Type is 'MainViewModel'.

Image 4

We're going to have an instance of the View as the main part of the application. Since we don't have an instance of a ViewModel yet, we can check the option to let the view create it.

We should also create a View for contacts - ContactView. In the case of ContactView, we don't want to create the ViewModel - because the MainViewModel already has instances of ContactViewModel that we bind to. The ContactView is very simple and is defined by the XAML below:

XML
<UserControl x:Class="Contacts.ContactView"
             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" 
             xmlns:local="clr-namespace:Contacts"
             xmlns:apexMVVM="clr-namespace:Apex.MVVM;assembly=Apex"
             xmlns:apexCommands="clr-namespace:Apex.Commands;assembly=Apex"
             xmlns:apexControls="clr-namespace:Apex.Controls;assembly=Apex"
             xmlns:apexConverters="clr-namespace:Apex.Converters;assembly=Apex"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    
    <apexControls:PaddedGrid Rows="Auto,Auto" Columns="*,2*" Padding="4">

        <!-- The Name label and textbox. -->
        <Label Grid.Row="0" Grid.Column="0" Content="Name" />
        <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Name}" />

        <!-- The Birthday label and textbox. -->
        <Label Grid.Row="1" Grid.Column="0" Content="Birthday" />
        <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Birthday}" />
        
    </apexControls:PaddedGrid>
</UserControl>

Here, we are also using one of the Apex Controls - the Padded Grid. The Padded Grid is a grid that allows a padding to be set.

Now that we have a View for a Contact - we can build the final view for the application. This is the code for MainView:

XML
<UserControl x:Class="Contacts.MainView"
             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" 
             xmlns:local="clr-namespace:Contacts"
             xmlns:apexMVVM="clr-namespace:Apex.MVVM;assembly=Apex"
             xmlns:apexCommands="clr-namespace:Apex.Commands;assembly=Apex"
             xmlns:apexControls="clr-namespace:Apex.Controls;assembly=Apex"
             xmlns:apexConverters="clr-namespace:Apex.Converters;assembly=Apex"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">    
    
    <!-- The View creates its own ViewModel, so set the ViewModel 
    to a new instance of the ViewModel class. -->
    <apexMVVM:View.ViewModel>
        <local:MainViewModel x:Name="viewModel" />
    </apexMVVM:View.ViewModel>
            
    <apexControls:ApexGrid Columns="*,2*">
        
        <!-- The list of contacts. -->
        <ListBox Grid.Column="0" ItemsSource="{Binding Contacts}" DisplayMemberPath="Name"
                 SelectedItem="{Binding SelectedContact}" />
        
        <!-- A contact view - bound to the selected contact. -->
        <local:ContactView Grid.Column="1" DataContext="{Binding SelectedContact}" />
        
    </apexControls:ApexGrid>
</UserControl>

Now we drop an instance of this View into the main window of the application. Hitting F5 shows us what we've got so far. It's basic, but it's a great beginning!

What's Next

We've created the basics of an MVVM application - a good start! In the next part of this series, we're going to take this Contact application and start making it a bit more functional. And along the way, we'll get to see some other features of Apex.

History

  • 21st May, 2012: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United Kingdom United Kingdom
Follow my blog at www.dwmkerr.com and find out about my charity at www.childrenshomesnepal.org.

Comments and Discussions

 
QuestionAdding a new class to Apex.MVVM Pin
marcelo.nicolet14-Jun-17 7:42
marcelo.nicolet14-Jun-17 7:42 
AnswerRe: Adding a new class to Apex.MVVM Pin
marcelo.nicolet14-Jun-17 9:12
marcelo.nicolet14-Jun-17 9:12 
QuestionDouble version problem when installing the Apex SDK Pin
Member 1150234817-Jun-15 17:10
Member 1150234817-Jun-15 17:10 
GeneralMy vote of 5 Pin
JF201521-May-12 3:22
JF201521-May-12 3:22 
GeneralRe: My vote of 5 Pin
Dave Kerr29-May-12 23:04
mentorDave Kerr29-May-12 23:04 
GeneralMy vote of 5 Pin
sonnywu@gmail.com2-May-12 9:12
sonnywu@gmail.com2-May-12 9:12 
GeneralRe: My vote of 5 Pin
Dave Kerr2-May-12 22:41
mentorDave Kerr2-May-12 22:41 
QuestionThanks Pin
Patrick Kalkman27-Apr-12 8:59
Patrick Kalkman27-Apr-12 8:59 
AnswerRe: Thanks Pin
Dave Kerr2-May-12 22:42
mentorDave Kerr2-May-12 22:42 
QuestionAPEX? Pin
noireen23-Apr-12 19:41
noireen23-Apr-12 19:41 
AnswerRe: APEX? Pin
Dave Kerr2-May-12 22:43
mentorDave Kerr2-May-12 22:43 
AnswerRe: APEX? Pin
Ashley van Gerven20-May-12 18:54
Ashley van Gerven20-May-12 18:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.