Home > Metro, Windows 8 > Windows 8 Metro Style App Development with XAML and C#

Windows 8 Metro Style App Development with XAML and C#

Updated for VS 2012 RTM

In this post i will show how to create a small app, which can be used to add, edit or delete small notes. The app will use the MVVM concept, where all the data is stored in the Viewmodel and data binding is used to synchronize data and views.

The app allows to edit or add notes, where each note contains a few properties like Last Update, Title and text

At the end of all the steps the app should look like this:

image image

My recommended steps for creating a new app with VS 2012:

Step 1: Create the base app

  1. Create new App based on the Split App (XAML) template
    (I’m using this, because the “Blank App” template is missing some template code)

    image

  2. Remove all XAML-Pages, but not the App.xaml
  3. Create new folders named Pages, Model and ViewModel
  4. Add a new Page to Pages folder named MainPage based on “Basic Page” item template
  5. Change all references in App.xaml.cs from ItemsPage to MainPage
  6. Remove x:Key=AppName in MainPage and update corresponding entry in App.xaml
  7. In MainPage add a new GridView to row 1 of the existing toplevel grid (LayoutRootStyle)
  8. Starting the app should now show a blank page with only the app name at the top

    image

Step 2: Adding Model and ViewModel classes

  1. Add a new classfile Note.cs to the Model folder, which derives from BindableBase
    (See Common folder)
    public class Note : BindableBase
    {
        private DateTime lastUpdate;
        public DateTime LastUpdate
        {
            get { return lastUpdate; }
            set { this.SetProperty(ref lastUpdate, value); }
        }
    
        private string title;
        public string Title
        {
            get { return title; }
            set { this.SetProperty(ref title, value); }
        }
    
        private string text;
        public string Text
        {
            get { return text; }
            set { this.SetProperty(ref text, value); }
        }
    }
  2. Add MainViewModel class to ViewModel folder, based on BindableBase
    public class MainViewModel : BindableBase
    {
        public ObservableCollection<Note> Notes
        {
            get;
            set;
        }
    
    
        public MainViewModel()
        {
            if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
                GenerateDesignTimeData();
        }
    }
  3. Add static property ViewModel of type MainViewModel to App.xaml.cs

    sealed partial class App : Application
    {
        private static MainViewModel viewModel; 
        public static MainViewModel ViewModel 
        { 
            get 
            { 
                if (viewModel ==null) 
                    viewModel = new MainViewModel(); 
                return viewModel;  
            } 
            
            set 
            { 
                viewModel = value; 
            }  
        } 

  4. Add Designtime data generation to MainViewModel ctor

    public class MainViewModel : BindableBase
    {
        public ObservableCollection<Note> Notes
        {
            get;
            set;
        }
    
        public MainViewModel()
        {
            if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
                GenerateDesignTimeData();
        }
    
        private void GenerateDesignTimeData()
        {
            Notes = new ObservableCollection<Note>();
            for (int i = 0; i < 50; i++)
            {
                Notes.Add(new Note()
                {
                    LastUpdate = DateTime.Now.AddMinutes(-150),
                    Title = "Designtime Sample data title " + i,
                    Text = "Designtime Sample data text " + i,
                });
            }
        }
  5. Comment out all references to 
    – DefaultViewModel,

    – DefaultViewModelProperty,

    – IObservableMap and

    – ObservableDictionary in Common\LayoutAwarePage.cs

Step 3: Enable display of designtime data

  1. Remove Datacontext statement from MainPage.xaml

  2. Add this to the header of MainPage.xaml, but adjust the namespace

    image

  3. Set GridView ItemsSource to {Binding Notes} and adjust Margin
  4. Define ItemTemplate and Bind to the properties of the Note classimage

  5. Now the designtime data should be visible in VS designer

    image

 

Step 4: Load data at runtime

  1. Open App.xaml.cs and add the call to the data loading function from inside OnLaunch:

    image

     

  2. Implement dummy data loading in MainViewModel.LoadData(): 

    internal void LoadData()
    {
        Notes = new ObservableCollection<Note>();
        for (int i = 0; i < 50; i++)
        {
            Notes.Add(new Note()
            {
                LastUpdate = DateTime.Now.AddMinutes(-150),
                Title = "Runtime Sample data title " + i,
                Text = "Runtime Sample data text " + i,
            });
        }
    }
  3. Set DataContext = App.ViewModel in ctor of MainPage 
  4. Starting the app should now display the dummy data

    image

Step 5: Navigate with selected item to detail page

  1. A click on any entry should display the edit page with the selected item

  2. Therefore add a new page named EditPage of type BasicPage to the pages folder
  3. Remove Datacontext statement from EditPage.xaml
  4. Add this to the header of EditPage.xaml, but adjust the namespace and note, that we are binding the page in design mode to the first entry of the designtime dummy data.
  5. (See Binding Notes[0])image

  6. Now add the following properties to the GridView in MainPage:

    image

     

  7. Add the new property SelectedNote to the MainViewModel:
    private Note selectedNote; 
    public Note SelectedNote 
    { 
        get { return selectedNote; } 
        set { this.SetProperty(ref selectedNote, value); } 
    }
  8. The statement SelectedItem={Binding SelectedNote, Mode=”TwoWay”} will set SelectedItem in the viewmodel and we just need to navigate to the EditPage
    private void GridView_ItemClick_1(object sender, ItemClickEventArgs e)
    {
        App.ViewModel.SelectedNote = (Note)e.ClickedItem;
        this.Frame.Navigate(typeof(EditPage), null);
    }

     

Step 6: Display selected item on detail page

 

    1. Open EditPage.xaml.cs and set DataContext to App.ViewModel.SelectedNote in ctor
    2. This enables now to bind UI elements to the properties of a single Note:

      For this add a Grid to row 1 of the existing root grid and paste in the following UI elements:

      image

    3. The app should now allow to navigate to the EditPage and display the selected note:



      image

Step 7: Add AppBar to EditPage

  1. To update the selected note, a “Save” button must be added to the bottom AppBar by adding this to EditPage.xaml:

    image

  2. This Style definition must be added to App.xaml
  3. <Style x:Key="SaveAppBarButtonStyle" TargetType="Button" 
    BasedOn="{StaticResource AppBarButtonStyle}"> <Setter Property="AutomationProperties.AutomationId" Value="SaveAppBarButton"/> <Setter Property="AutomationProperties.Name" Value="Save"/> <Setter Property="Content" Value=""/> </Style>

  4. This will place the Save button to the bottom right corner like this:

    image

  5. The click event handler will then navigate back to the MainPage:
    private void btnSave_Click_1(object sender, RoutedEventArgs e)
    {
        if (this.Frame.CanGoBack)
        {
            this.Frame.GoBack();
        }
    }

    Now changes should be visible on MainPage after pressing Save!

Step 8: Implement “Add Note” functionality

  1. Adding new notes will be done with the add Button in the bottom AppBar:

    image

  2. Add a new page “AddPage to the pages folder
  3. Remove Datacontext statement from AddPage.xaml and add this, but update the namespace:



    image

  4. In the AppBar AddButton click handler navigate to the AddPage:
    btnAdd_Click_1(RoutedEventArgs e)
    {
        Frame.Navigate(typeof(AddPage)); 
    }

  5. Add the same UI as in EditPage
  6. In the AddPage ctor set DataContext to a new instance of Note()
  7. Add the same Save AppBarButton as in the EditPage
  8. In the Save Button click handler add the new note to the Notes collection of App.ViewModel
    private void btnSave_Click_1(object sender, RoutedEventArgs e)
    {
        App.ViewModel.Notes.Add((Note) DataContext); 
        if (this.Frame.CanGoBack) 
        { 
            this.Frame.GoBack(); 
        } 
    } 

 

Step 9: Implement Process lifecycle

need to do some some more work here…. stay tuned…

==========================

Implement Process lifecycle (Suspending/resume):

==========================

Add [DataContract] and [DataMember] to MainViewModel and all public members

Add [DataContract] to BindableBase

Add SaveViewModelData and RestoreViewModelData to App.xaml.cs and call from OnSupend / OnLaunch after termination

 .
Categories: Metro, Windows 8
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: