Using Isolated Storage on Windows Phone 7

by brad 3. September 2010 16:34

Introduction

To store local data a on a Windows Phone 7 phone, the tool of choice is isolated storage.  There are several efforts to create Windows Phone 7 databases, but in the end, these all run on top of isolated storage.

Isolated Storage is not new to Windows Phone, but  has been around a while in the Silverlight world.  And while it might sound fancy, isolated storage is just a clever way of saying “Write your data to text files.” 

Isolated

Well, writing to text files covers the “storage” part of it at least.  The “isolated” part of it just means that your application can’t see other application’s data and other applications can’t see your data.  The data is isolated per application.  If you need two applications that work with the same data, then that data can’t be local to either application.  Instead, it should be in the cloud, which is a fancy way of saying “on the internet”.  Once your data is shared through the cloud, as many applications as you want can all access the same data and even keep their own local copy in isolated storage if it makes sense.

How it’s done – writing to a file

Note: For a complete working reference, check out the source code for Gas Mileage for Windows Phone 7 on Codeplex.

To write to isolated storage, the first thing you’ll need is an instance of IsolatedStorageFile.  This class represents the file system that you’ll be working with on the phone.  It implements IDisposable, so be sure to wrap its usage in a “using” statement.

   1: using (var store = IsolatedStorageFile.GetUserStoreForApplication())

The next step is to get a stream to write to.  For example, to write to a file called “data.txt”, this code would get us started.

   1: using (var store = IsolatedStorageFile.GetUserStoreForApplication())
   2: using (var stream = new IsolatedStorageFileStream("data.txt", 
   3:                                                   FileMode.Create, 
   4:                                                   FileAccess.Write, 
   5:                                                   store))
   6: {
   7:     // Write to our file
   8: }

This creates a file stream that can be used for writing to the file “data.txt”.  Setting the FileMode to Create means that the file will be created for us, even if it already exists.  For all of the FileMode options, check out this MSDN page.

The final step is to serialize the data that we want to save.  For this example, I’m using the XmlSerializer that you’ll find in the System.Xml.Serialization namespace.  If you’re just saving text, then there is no need to bother with serialization – just write the text.

   1: using (var store = IsolatedStorageFile.GetUserStoreForApplication())
   2: using (var stream = new IsolatedStorageFileStream("data.txt", 
   3:                                                   FileMode.Create, 
   4:                                                   FileAccess.Write, 
   5:                                                   store))
   6: {
   7:     var serializer = new XmlSerializer(typeof(Notebook));
   8:     serializer.Serialize(stream, notebook);
   9: }

Reading from a file

Reading from a file is very similar. 

   1: using (var store = IsolatedStorageFile.GetUserStoreForApplication())
   2: using (var stream = new IsolatedStorageFileStream("data.txt", 
   3:                                                     FileMode.OpenOrCreate, 
   4:                                                     FileAccess.Read, 
   5:                                                     store))
   6: using (var reader = new StreamReader(stream))
   7: {
   8:     return reader.EndOfStream 
   9:         ? new Notebook() 
  10:         : (Notebook) _serializer.Deserialize(reader);
  11: }

This time, I set the FileMode to OpenOrCreate so that if the file does not exist it will be created for me.  I also check to see if the reader is at the end of its stream before reading.  If it is, this indicates the file is empty and has just been created.  In this case, I return a new notebook rather than trying to deserialize an empty string of data.

Again, for the complete source code these examples are pulled from, check out Gas Mileage for Windows Phone 7 on Codeplex.

Best Practices & Quotas

Microsoft has published isolated storage best practices for the phone on MSDN.  Here are some of the highlights.

  • If you change your isolated storage format between versions of your application, it is up to you to upgrade or modify your files.  In practical terms, this means that the newer version of your app will have to upgrade your isolated storage files the first time it runs since you have no control of the upgrade process.
  • There is no limit to how much disk space a Windows Phone application can take up.  Just like desktop development, if you want to be a jerk and take up all of the available disk space, you can.  But this will not please your users, so don’t use more of their phone than you need to use.

Isolated Storage on the Emulator

The Windows Phone 7 emulator does not remember isolated storage data between runs.  This means that your application will start with nothing in isolated storage when the emulator first fires up.  If you want your isolated storage data around between deployments to the emulator, then just leave the emulator open.  Visual Studio can easily re-deploy your application to the already-running emulator.

More Information

Tags: ,

Silverlight | Windows Phone

Day of .NET Code Demos

by brad 23. August 2010 10:46

Here are the code demos from my two presentations at this year’s Day of .NET.  Thanks to everyone that came out – especially those of you that attended the final session of the day on Saturday afternoon.

Also, the slides from my Windows Phone 7 talk are available at slideshare.

Tags: , ,

Presentations | Silverlight | Windows Phone

Use EscapeUriString instead of UrlEncode for Silverlight

by brad 10. August 2010 13:26

If your first experience escaping a URL in Silverlight is anything like mine, the first tool you will reach for might be HttpUtility.UrlEncode.

HttpUtility.UrlEncode(“http://www.google.com/m8/feeds/contacts/example@gmail.com/full”)

But wait! HttpUtility is in System.Web, which is definitely NOT part of the standard Silverlight reference pack.  So the question now is “Do I want to include System.Web in my Silverlight application for one line of code?”  And the answer is “Nope”.

Instead, you can use EscapeUriString which comes in the System assembly.

Uri.EscapeUriString(“http://www.google.com/m8/feeds/contacts/example@gmail.com/full”)

Same result, without adding a unnecessary assembly to your Silverlight application.

Tags:

Silverlight

Materials from “The Power of Silverlight: Building a Google Contacts Explorer”

by brad 6. August 2010 10:35

Several people asked about the source code from my devLink presentation “The Power of Silverlight: Building a Google Contacts Explorer”.  If that was you, then here you go!

Download source code

Tags:

Presentations | Silverlight

Speaking at 2010 St Louis Day of .NET

by brad 21. July 2010 09:11

The 2010 St Louis Day of .NET is fast approaching, and if you have yet to register, you better get on it.  This years event is shaping up to be fantastic, with 90 confirmed sessions so far.  Visit the website to check out all the sessions, learn more about the conference, and register to attend!

I’ll be presenting these sessions

The Power of Silverlight: Building a Google Contacts Client
This presentation will showcase two of Silverlight's most powerful assets: the ability to create rich user interfaces and the ability to consume data from the web.   We'll walk through building a rich Google Contacts client that consumes Google's RESTful AtomPub Data API.

Writing Your First App for Windows Phone 7
This presentation will provide everything you need to know to develop your first working application for the upcoming Windows Phone 7 Series.  We’ll cover the application architecture, tools, phone-specific features and APIS, and use Visual Studio 2010 and Expression Blend 4 to write a fully functioning application for Windows Phone.

See you there!

Tags:

Windows Phone | Presentations | Silverlight

Cross-domain access for trusted Silverlight 4 applications (With XBOX Live Avatars!)

by brad 2. June 2010 16:56

Background

To foil evil Silverlight developers, there are several restrictions on the way Silverlight can access resources from domains other than the one they originate from.  These restrictions are meant to prevent the use of Silverlight for denial-of-service attacks and the like.  Read more at MSDN.

In practical terms, these restrictions mean that your Silverlight application cannot access resources (such as images, html content, etc.) from other domains unless those other domains have said it is okay for Silverlight (and/or Flash) applications to do so.  But there is a nice handy exception to this rule: If your application is running installed, out-of-the-browser, with elevated trust, then it is not restricted in this way.

The Application

As an example, let’s consider an application that can take an XBOX Live gamer tag and fetch the associated Avatar for that gamer tag.  Avatars can be retrieved from XBOX using this URL structure:

http://avatar.xboxlive.com/avatar/{GAMER-TAG}/avatar-body.png

So, all our app needs to do is construct this URL, make an HTTP GET to get the image, and then display that image.  Nothing to it – the code looks like this (you can download the whole app below):

   1: private void Button_Click(object sender, RoutedEventArgs e)
   2: {
   3:     var gamerTag = GamerTagTextBox.Text;
   4:     var url = string.Format(UrlTemplate, Uri.EscapeUriString(gamerTag));
   5:     var request = WebRequest.Create(url);
   6:     request.BeginGetResponse(GetResponseCallback, request);
   7: }
   8:  
   9: private void GetResponseCallback(IAsyncResult ar)
  10: {
  11:     Dispatcher.BeginInvoke(() =>
  12:     {
  13:         var request = ar.AsyncState as HttpWebRequest;
  14:         var response = request.EndGetResponse(ar);
  15:         var image = new BitmapImage();
  16:         image.SetSource(response.GetResponseStream());
  17:         AvatarImage.Source = image;
  18:     });
  19: }

It’s worth noting that an easier way to pull this off is just to set the image’s source directly to the URL instead of doing an HTTP GET, but if you do it that way, you don’t get the SecurityException error that I want to highlight.

The important code is Lines 14 through 17.  This is where the response from the HTTP GET is processed and the source of the image is set.

What WON’T Work

If you run this code in a default Silverlight application running in a browser, here’s what happens.

image

Ouch!  We are not allowed to talk to XBOX.com since our Silverlight application did not originate from XBOX.com.

What WILL Work

To make this work we have a couple of choices

  1. Write a proxy service that lives on our server.  This service can then talk to XBOX.com.  While not the focus of this post, this is a reasonable solution.
  2. Set our app to run out of the browser with elevated security.  If out-of-browser is not an option for you, then look into Option #1.  If it is an option, here’s how it’s done.

Enable OOB

First, open up your project properties, go to the Silverlight tab, and enable out-of-browser.

image Next, open the Out-of-Browser settings, and check the box for elevated privileges.

image And finally, to make your debug experience a good one, open up the Debug tab of the Properties, and set your application to start as an out-of-browser app.

image The Finished Product

That’s it!  Now your app can talk to other domains, such as XBOX.com and retrieve resources from them.image

Finishing Up

So there you have it – accessing cross-domain resources with Silverlight 4.  It’s worth noting that if you require this sort of access for your application, then you should make it easy for users to install your app to their desktop and probably prevent it from running unless it’s out-of-browser.  You can read more on that at MSDN.

Special thanks to cdeweese for showing me the Avatar-fetching URL in the first place and for pair programming the Fetcher app with me.

Resources

Tags:

Silverlight

Developing with Windows Phone 7 Input Scopes

by brad 26. May 2010 16:09

Input scopes are what allow you to control what the onscreen keyboard looks like in Windows Phone 7.  There are loads of input scopes available, but generally you’re going to want a text-based input scope or a number-based input scope.

The default “Text” input scope looks like this:

image And the “Number” input scope looks like this:

image

Implementing Input Scopes

There are two ways to implement input scopes: declaratively with XAML or programmatically with C#.  If you have a textbox that will always have the same input scope, taking care of it with XAML will keep your C# code-behind a bit cleaner.  But if you need to change input scopes at run-time, then C# is the way to go.

With XAML:

   1: <TextBox InputScope="CurrencyAmount" />

With XAML (Verbose):

   1: <TextBox>
   2:     <TextBox.InputScope>
   3:         <InputScope>
   4:             <InputScopeName NameValue="EmailNameOrAddress" />
   5:         </InputScope>
   6:     </TextBox.InputScope>
   7: </TextBox>

The advantage of the verbose syntax is that you get intellisense for the choices for input scope.  This is super handy since there are ton of them.  One approach is to use the verbose syntax to make sure you get the name right, and then switch to the less-verbose approach.

With C#:

   1: var name = new InputScopeName {NameValue = InputScopeNameValue.TelephoneLocalNumber};
   2: PhoneNumberTextBox.InputScope = new InputScope() {Names = {name}};
Or, a slightly more verbose way:
   1: var name = new InputScopeName { NameValue = InputScopeNameValue.TelephoneLocalNumber };
   2: PhoneNumberTextBox.InputScope = new InputScope();
   3: PhoneNumberTextBox.InputScope.Names.Add(name);

Or, a really terse but almost unreadable way:

   1: var name = new InputScopeName {NameValue = InputScopeNameValue.TelephoneLocalNumber};
   2: PhoneNumberTextBox.InputScope = new InputScope() {Names = 
   3:     {new InputScopeName {NameValue = InputScopeNameValue.TelephoneLocalNumber}}};

More information:

Tags:

Windows Phone | Silverlight

Using the WrapPanel from the Silverlight Toolkit on Windows Phone 7

by brad 20. March 2010 21:21

Update: You can now download a version of the Silverlight Toolkit that is specifically targeted towards Phone development at http://silverlight.codeplex.com/

I never get too far on a Silverlight project before I find myself reaching for a WrapPanel.  Unlike WPF, Silverlight does not come with a WrapPanel when you open the box from the store.  BUT … the Silverlight Toolkit has a great WrapPanel, along with a plethora of other great controls.

When I found myself wanting a WrapPanel for a Windows Phone 7 app, I was a bit worried that the Silverlight Toolkit might not work on the phone.  But my fears were unfounded … the WrapPanel works just great on a phone!  Well, to be fair, it runs great on a phone emulator. 

Here are the simple steps to get your WrapPanel, and anything else you might want from the Silverlight Toolkit, into your Windows Phone 7 app.

First, download and install the Silverlight 3 Toolkit from CodePlex.  There’s also a beta for Silverlight 4, but the phone runs 3, not 4.

The next step is to add a reference to the Toolkit assembly

image

On my machine, the default install path for the toolkit was C:\Program Files (x86)\Microsoft SDKs\Silverlight\v3.0\Toolkit\Nov09\Bin.  I would imagine you’ll find it in much the same place.  For the WrapPanel, the assembly you want is System.Windows.Controls.Toolkit.

image

That’s it!  After adding the reference, the WrapPanel will be available in your assets list, in the Controls category.  If for some odd reason it’s not there, you can expand the “Locations” tree and search directly in the “System.Windows.Controls.Toolkit.dll”.

image

Hooray … all the fun of the Silverlight Toolkit on the phone!

Tags:

Silverlight | Windows Phone

Writing an app for Windows Phone 7 Series

by brad 17. March 2010 01:09

Yesterday at MIX10, Microsoft (specifically, Scott Guthrie) announced the general availability of all the tools that you’ll need to design and build “delightful” applications for Windows Phone 7.  Follow along with me as I build my very first Windows Phone 7 application!

Windows Phone

For future reference, the hub for all things Windows Phone developy is http://developer.windowsphone.com.

Tools and Documentation

First things first, we need some tools

  1. Download and install the Windows Phone Developer Tools CTP.This includes Visual Studio 2010 for Windows Phone, the emulator, Silverlight for Windows Phone, and XNA 4.0 Game Studio.  If you already have a copy of VS2010 installed, no worries – just install this right over the top of it.
  2. Download and install Expression Blend 4 Beta.  While we could do everything in Visual Studio, Expression Blend will give us way more power for laying out the content of our application.

While those are downloading and installing, we may as well read some documentation.

  1. Read the Application Platform Overview to get a big picture of how all the pieces fit together.
  2. Read the QuickStart Guide for creating your first Silverlight App for Windows Phone.
  3. If your tools are still downloading, start browsing the class library documentation.  This is the good stuff anyway.

The App

The app we’ll build is about as simple as it gets.  We’ll use tally marks to write a counting application.  If the user taps the screen, a mark is added to the tally.  To keep it extra simple, we’ll only support counting up to five … for now.

If you want to follow along, go ahead and download the full source code now.

Creating your Project

After our tools are installed, it’s goitime.  Fire up Visual Studio and select File, New Project.  From the left-hand menu, find Silverlight for Windows Phone and then select “Windows Phone Application” from the choices.

image

This will create a skeleton for your project and open up the main page.  Like Silverlight navigation applications, Windows Phone 7 applications are based on pages. 

image

Making it Yours

Using the XAML view on the right, find the two textblocks that are responsible for rendering the name of your application and the name of the current page.  I renamed my application to “TALLY MARKS” and my page to “count”.  Note that the app name is all caps and the page name is all lowercase to follow the style guidelines established by the skeleton application.

   1: <Grid x:Name="TitleGrid" Grid.Row="0">
   2:     <TextBlock Text="TALLY MARKS" 
   3:                x:Name="textBlockPageTitle" 
   4:                Style="{StaticResource PhoneTextPageTitle1Style}"/>
   5:     <TextBlock Text="count" 
   6:                x:Name="textBlockListTitle" 
   7:                Style="{StaticResource PhoneTextPageTitle2Style}"/>
   8: </Grid>

image

A UserControl for our Tally Marks

Next we’ll create a user control to handle the display of the tally marks.  To make things easy, you can download the full XAML for the user control right here.  Or if you downloaded the source (link above), you already have it. Just add a file to your project called “MarksUserControl.xaml” and paste the code right in.  You’ll probably have to update the class name to match your assembly name, though – it’s the fifth line in the file.

   1: x:Class="TallyMarks.MarksUserControl

Change “TallyMarks” to match the name of your project.

Visual States

Now, if you open up MarksUserControl.xaml in Expression Blend, you’ll see that it has six states.  Check out the Visual State Manager by selecting the “States” tab in the upper-left of the Expresssion Blend window.

image

The default state shows a message to tell the user how to use the program.

image

The rest of the states show the different possibilities for the tally marks, from one through five.  When we expand the app to count beyond five, we’ll be able to reuse this concept and count by creating multiple instances of the control.

image

image

Theming support

Notice that the user control uses the phone’s background and highlight colors.  If the user changes their phone theme, the app will change to match.

   1: <Rectangle.Stroke>
   2:     <SolidColorBrush 
   3:         Color="{StaticResource PhoneAccentColor}"/>
   4: </Rectangle.Stroke>
   5: <Rectangle.Fill>
   6:     <SolidColorBrush 
   7:         Color="{StaticResource PhoneBackgroundColor}"/>
   8: </Rectangle.Fill>

 

The Model

Next up is the model.  Since this is Silverlight, our app needs something to bind to or it won’t be happy.  Our model is pretty simple – it just needs to keep track of the current count.  Here it is:

   1: public class TallyModel : INotifyPropertyChanged
   2: {
   3:     private int _count;
   4:  
   5:     public int Count
   6:     {
   7:         get { return _count; }
   8:         set
   9:         {
  10:             _count = value;
  11:             if (PropertyChanged != null)
  12:             {
  13:                 PropertyChanged.Invoke(
  14:                     this, 
  15:                     new PropertyChangedEventArgs("Count"));
  16:             }
  17:         }
  18:     }
  19:  
  20:     public event PropertyChangedEventHandler PropertyChanged;
  21: }

Notice that we implement INotifyPropertyChanged so the app can keep up with changes to its model.

The Main Page

Now it’s just a matter of wiring things up.  On our main page, we need to do three things

  1. Display the user control and the current count
  2. Bind the model
  3. Increment the counter when the user control is tapped

Displaying the user control and the current count

To display the user control and the current count, we’ll drop an instance of our user control into the content grid and also add a textblock to display the current count.

   1: <Grid x:Name="ContentGrid" Grid.Row="1" >
   2:     <Grid.RowDefinitions>
   3:         <RowDefinition Height="Auto"/>
   4:         <RowDefinition Height="*"/>
   5:     </Grid.RowDefinitions>
   6:     <local:MarksUserControl x:Name="Marks"
   7:         MouseLeftButtonUp="MarksUserControl_MouseLeftButtonUp"/>
   8:     <TextBlock x:Name="CounterTextBlock" Grid.Row="1" 
   9:                Text="{Binding Count, Mode=OneWay}" 
  10:                FontSize="96" 
  11:                HorizontalAlignment="Center" 
  12:                VerticalAlignment="Center">
  13:         <TextBlock.Foreground>
  14:             <SolidColorBrush 
  15:                 Color="{StaticResource PhoneAccentColor}"/>
  16:         </TextBlock.Foreground>
  17:     </TextBlock>
  18: </Grid>

Binding the model

You’ll see in the XAML above that the TextBlock is already expecting to be bound to the TallyModel so it can pull out the Count to display.

To bind things up, we have to tell our page what its model is with a few lines of XAML.

   1: <phoneNavigation:PhoneApplicationPage.DataContext>
   2:     <model:TallyModel/>
   3: </phoneNavigation:PhoneApplicationPage.DataContext>

 

Incrementing the counter

You may have already noticed in the XAML for the main page that we have wired up a MouseLeftButtonUp event for the MarksUserControl.  This is where we’ll write our code to incremement the count and take care of the display of the user control.

   1: private void MarksUserControl_MouseLeftButtonUp(
   2:     object sender, 
   3:     MouseButtonEventArgs e)
   4: {
   5:     MyDataContext.Count++;
   6:     var state = "Tally" + MyDataContext.Count;
   7:     VisualStateManager.GoToState(Marks, state, false);
   8: }

In this example, MyDataContext is a private property that’s returning the model, already cast to the appropriate type.

   1: private TallyModel MyDataContext
   2: {
   3:     get
   4:     {
   5:         return this.DataContext as TallyModel;
   6:     }
   7: }

First, we increment the count.  Since we’re using binding and INotifyPropertyChanged, the text block that is displaying the current count will update automatically.

The visual states for the user control are slightly more complicated.  I tried at first to bind to a custom property on the user control, but couldn’t get this to work.  Blend didn’t even seem to want to allow it and when I did it anyway, I got XAML Parse errors. Oh well.

So, rather than get stuck, I changed it to just have the main page code behind manually change the visual state to match the current count.  Works just as well.

All done

That’s about it.  The finished product looks something like this.  The best part – aside from the model, the whole app is less than a dozen lines of code.  The rest is XAML.  Download all the code here.

image

Tags:

Silverlight | Mix | Windows Phone

About Brad

Brad Tutterow lives in Illinois and works in Missouri. He has 12 years of experience developing web sites and Windows applications using a variety of technologies and is most excited currently about Silverlight, Windows Phone 7, Halo Reach, and Visual Studio 2010.