Archive

Archive for the ‘Windows 8.1’ Category

Create Windows 8.1 Store app from blank template using simple MVVM pattern

March 24, 2014 5 comments

Create new project in VS 2013 using “Blank App” template

image

 

Make the ViewModel bindable

Add a new directory ViewModels and add a new class BaseViewModel.cs insde this directory with this content inside the namespace:

 

public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

 

Download source from here

Add another class file called MainViewModel.cs with this content inside the namespace:

public class MainViewModel : BaseViewModel
{
    private string firstname = String.Empty;
    public string Firstname
    {
        get { return firstname; }
        set { SetField( ref firstname, value ); }
    }

    private string lastname = String.Empty;
    public string Lastname
    {
        get { return lastname; }
        set { SetField(ref lastname, value); }
    }
}

 

This way the properties in MainViewModel will automatically be able to databind in both directions.

 

Create a singleton for central access to the ViewModel

Now we must find a way to access the ViewModel from every place inside the app.

This can be done using a singleton pattern like this in app.xaml.cs:

 

private static MainViewModel myMainViewModel = null;
public static MainViewModel MyMainViewModel
{
    get
    {
        if (myMainViewModel == null)
        {
            myMainViewModel = new MainViewModel();
        }
        return myMainViewModel;
    }
}

 

Define the UI

Now add a few controls to Mainpage.xaml.cs (red block)

image

 

Setting the DataContext

in Mainpage.xaml.cs inside the ctor:

image

 

Please note:

Setting the DataContext in the XAML-file using <Page.Resources> does create a new instance of our MainViewModel class each time we open the MainPage, which is not what we want.

Therefore this statement for setting the DataContext is NOT USED here!

See the section “Adding designtime support..” below!

 

<!-- Does create a new instance every thime, because it's not using our singleton -->
<!--<Page.Resources>
    <ViewModels:MainViewModel /> NOT USED HERE !!
</Page.Resources>-->

 

 

Saving data when the OS terminates / suspends the app

Now add saving and loading to LocalSettings or RoamingSettings using code like this in the OnSuspend event:

 

private void OnSuspending(object sender, SuspendingEventArgs e)
{
    var deferral = e.SuspendingOperation.GetDeferral();
    //TODO: Save application state and stop any background activity
    ApplicationData.Current.LocalSettings.Values[Constants.LocalStorage.VIEWMODELDATA] 
        = Utility.SerializeToString(App.ViewModel);
    deferral.Complete();
}

Helper class for serialization / Deserialization

public static string SerializeToString(object obj)
{
    XmlSerializer serializer = new XmlSerializer(obj.GetType());
    using (StringWriter writer = new StringWriter())
    {
        serializer.Serialize(writer, obj);
        return writer.ToString();
    }
}

public static T DeserializeFromString<T>(string xml)
{
    XmlSerializer deserializer = new XmlSerializer(typeof(T));
    using (StringReader reader = new StringReader(xml))
    {
        return (T)deserializer.Deserialize(reader);
    }
}

 

 

 

Reload data after app was suspended

Then make sure, that when the program starts up after it was supended through the OS, that it’s loading the last data using code like this in the OnLaunched event:

if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
    //TODO: Load state from previously suspended application
    if (ApplicationData.Current.LocalSettings.Values[Constants.LocalStorage.VIEWMODELDATA] != null)
    {
        var serializedData 
            = ApplicationData.Current.LocalSettings.Values[Constants.LocalStorage.VIEWMODELDATA] as string;
        App.ViewModel = Utility.DeserializeFromString<MainViewModel>(serializedData);
    }
}

 

 

Adding designtime support / Intellisense for binding statements

using Blend:

Open MainPage.xaml in Blend and click on “Set design-time DataContext” in the right lower corner:

image

 

Select DesignInstance in the following dialog like this:

image

 

 

Create demo data for design time

 

Create dummy data in the ctor of the ViewModel and decide whether its running in design mode using:

if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)

 

 

 

 

.

Categories: Windows 8.1