The ball

Windows Phone 7 Tutorial – Creating a simple notes app with Silverlight Part 1

July 25, 2010 by onishimura
Filed under: .NET, Silverlight, Windows Phone 7 

This is part 1 in a 3 part tutorial for creating a notes application using Silverlight and Windows Phone 7. The other articles can be read here
Windows Phone 7 Tutorial – Creating a simple notes app with Silverlight Part 2
Windows Phone 7 Tutorial – Creating a simple notes app with Silverlight Part 3

Admittedly a bouncing ball on Windows Phone 7 isn’t all that useful, so I decided to create a sample application that could do a little more than draw a ball or say ‘hello world’. Ideally I wanted to work with some of the core concepts on the phone, such as lists, navigation and the application bar. Additionally I wanted a Windows Phone 7 app that persisted it’s data, which meant working with Isolated Storage. Obviously this calls for a note-taking app…after all who doesn’t love taking notes? Notes are only second to bouncing balls in my book.

To keep the scope of the app small and focused, I wanted the note app to do only the following

  • View a list of notes
  • Add a note
  • Delete a note


Pretty simple, right? The actual implementation turned out to be fairly quick as well. The full step by step is a little long for a single blog post so I’m breaking it up into three posts. The first post covers creating the project, adding a support class to help manage the isolated storage, and defining the model. The second post will cover adding a note, and the third post will cover deleting a note.

  1. To start with, create a Windows Phone List Application, named MyNotes. This will create a basic silverlight template for managing list-based apps. The structure of the project follows the MVVM pattern, so the views are populated by ViewModel classes, defined in the ViewModel folder.

    Here’s a quick run down of the files in the base list project:

    • MainPage.xaml : The initial screen of the site, which displays data in a ListBox named MainListBox by default. Selecting an item fires the MainListBox_SelectionChanged which navigates the user to the details page
    • DetailsPage.xaml : Individual item details for each item in the list. Clicking on an item on the main page brings you here
    • MainViewModelSampleData.xaml : Just as the name states, sample data that’s displayed during design time. Basically allows the design surface to render with the xaml designer.
    • MainViewModel.cs : ViewModel for the MainPage, by default the project populates itself with dummy “runtime” data when the project is run. The application has a property, ViewModel, which is an instance of this class and used in both the main page and details page to show the items.
    • ItemViewModel.cs : ViewModel for each individual item in the list. This default class has really only three properties, LineOne, LineTwo, LineThree, but also demonstrates an implementation for INotifyPropertyChanged

  2. Create a helper class to save notes data. Local data storage using silverlight in Windows Phone 7 is currently limited to using isolated storage. There’s no limit on the amount of data that can be stored though, other than the physical limit of the device of course. I’ve used something similar to the following in the past (This uses System.Runtime.Serialization so you’ll have to add that as a reference):

    using System.IO.IsolatedStorage;
    using System.Runtime.Serialization;
    
    namespace MyNotes
    {
        public class StorageHelper
        {
            public static T Load<T>(string name) where T : class, new()
            {
                T loadedObject = null;
                using (IsolatedStorageFile storageFile = IsolatedStorageFile.GetUserStoreForApplication())
                using (IsolatedStorageFileStream storageFileStream = new IsolatedStorageFileStream(name, System.IO.FileMode.OpenOrCreate, storageFile))
                {
                    if (storageFileStream.Length > 0)
                    {
                        DataContractSerializer serializer = new DataContractSerializer(typeof(T));
                        loadedObject = serializer.ReadObject(storageFileStream) as T;
                    }
                    if (loadedObject == null)
                    {
                        loadedObject = new T();
                    }
                }
    
                return loadedObject;
            }
    
            public static void Save<T>(string name, T objectToSave)
            {
                using (IsolatedStorageFile storageFile = IsolatedStorageFile.GetUserStoreForApplication())
                using (IsolatedStorageFileStream storageFileStream = new IsolatedStorageFileStream(name, System.IO.FileMode.Create, storageFile))
                {
                    DataContractSerializer serializer = new DataContractSerializer(typeof(T));
                    serializer.WriteObject(storageFileStream, objectToSave);
                }
            }
    
            public static void Delete(string name)
            {
                using (IsolatedStorageFile storageFile = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    storageFile.Remove();
                }
            }
        }
    }
    
  3. Instead of using the ItemViewModel class, we’re going to add our own Model, Note. This requires us to make changes in MainPage.xaml, MainViewModel.cs, DetailsPage.xaml and MainViewModelSampleData.xaml as well, to reflect the new properties. So, create a new folder title Models, and add the Note class below, to it. Also, change all references from ItemViewModel to Note, as this will be the Model we’ll be using going forward (I just did a find and replace on the entire project).

    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Runtime.Serialization;
    
    namespace MyNotes
    {
        [DataContract]
        public class Note : INotifyPropertyChanged
        {
            private string title;
            [DataMember]
            public string Title
            {
                get
                {
                    return title;
                }
                set
                {
                    if (value != title)
                    {
                        title = value;
                        NotifyPropertyChanged("Title");
                    }
                }
            }
    
            private string noteText;
            [DataMember]
            public string NoteText
            {
                get
                {
                    return noteText;
                }
                set
                {
                    if (value != noteText)
                    {
                        noteText = value;
                        NotifyPropertyChanged("NoteText");
                    }
                }
            }
    
            private DateTime createDate;
            [DataMember]
            public DateTime CreateDate
            {
                get
                {
                    return createDate;
                }
                set
                {
                    if (value != createDate)
                    {
                        createDate = value;
                        NotifyPropertyChanged("CreateDate");
                    }
                }
            }
    
            public void Save()
            {
                ObservableCollection<Note> currentNotes = StorageHelper.Load<ObservableCollection<Note>>(App.NotesFileName);
                currentNotes.Add(this);
                StorageHelper.Save<ObservableCollection<Note>>(App.NotesFileName, currentNotes);
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged(String propertyName)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (null != handler)
                {
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
    }
    

    For xaml files, such as MainViewModelSampleData.xaml you’ll need to change the properties that are bound, for example

    <local:MainViewModel.Items>
    	<local:Note Title="design one" NoteText="Maecenas praesent accumsan bibendum" CreateDate="7/22/2010" />
    	<local:Note Title="design two" NoteText="Dictumst eleifend facilisi faucibus" CreateDate="7/22/2010" />
    </local:MainViewModel.Items>
    
  4. Modify your App.xaml.cs file to add the following property. This is just the name of the notes file that will be stored in isolated storage.

    	public static string NotesFileName
    	{
    		get { return "notes.dat"; }
    	}
    

So now we have a fairly simple starting point. We have a main page, a details page, a class to help us manage isolated storage, and our base model class, Note. Next up, adding a note…

Part 2 is now up and can be read here
Windows Phone 7 Tutorial – Creating a simple notes app with Silverlight Part 2

Comments

Tell me what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!