I recently started writing my first Windows Phone 7 Application.  I was shocked at how easy it was to get started although I’ll admit that has a lot to do with my existing knowledge of Silverlight.  If you don’t know Silverlight, now is a great time to learn it.  You can write apps for the web, desktop, and Windows Phone 7 too! 

As I wrote my application, I compiled a list of tips to share.  I spent a bunch of time tracking some of these down or figuring them out.  I hope this will be helpful to other people.  Plus, I’ll use this as a reference for myself when I create my next app!

Here you go.  The first two are pretty basic, but worth mentioning.

Tip:  Go For It!

The best advice is to install the tools and try it out for yourself.  If you create an application from one of the templates (you’ll get them after you install the tools for Visual Studio) you find that the templates themselves are a great learning tool.  Some include samples for styling, data binding, design time data binding, navigation, and more!  I recommend trying each of the templates out.

Tip: Install the Free Tools

This isn’t really a tip.  You can’t create apps without doing this!  Visit the App Hub to download the free tools.  You get all this for free: VS 2010 Express, the Windows Phone Emulator, Expression Blend for Windows Phone, and more!  Also, don’t forget to install Silverlight for Windows Phone Toolkit from the CodePlex site.  It includes some additional controls that are great like AutoCompleteBox, ContextMenu, GestureListener and more!  By the way, when you are at the App Hub, check out all the great learning resources.  By the way, you should keep in mind that Windows Phone 7 is a subset of Silverlight 3!  That means that most features of 3 are there but not all.  And Silverlight 4 features are obviously not included.

Tip: Using the Software Input Panel

The Software Input Panel (SIP) is the “on screen” keyboard that users use to key in data.  It’s pretty cool and has some great features.  First, you don’t need to turn it on.  If you include a TextBox in your app, when it gets focus the SIP will appear.  But there are many versions of the SIP and you can easily configure which one appears by setting the InputScope property of your TextBox.  You can get a full list of the options here.  If you want users to enter numbers, set InputScope to Digits.  For email address entry, try EmailNameOrAddress and the keyboard will include the @ sign.  Some choices are more subtle.  Choosing AddressCountryName may seem like the typical keyboard but the first letter typed will be capitalized, remaining character will be lower case.  There are many cool and smart features like that.  Also, options like Text or Chat will include word suggestions!  Here are some code samples and screen shots:

<TextBox InputScope="EmailNameOrAddress" Height="75" />
<TextBox InputScope="Text" Height="75" />

image     image

The first screenshot is the SIP when the EmailNameOrAddress version has focus.  In the second screen shot (TextBox InputScope set to Text), I typed a few letters and you can see the word suggestions!

Tip:  Orientation

If you want your application to support both portrait and landscape mode (when the user tilts the phone over), you need to set up each page’s SupportedOrientations property to do so as follows.  Set the default value in the Orientation property.

<phone:PhoneApplicationPage 
    x:Class="WindowsPhoneApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    SupportedOrientations="PortraitOrLandscape"  Orientation="Portrait"

Tip: UI Design

First, you should check out the UI Design and Interaction Guide for tips on how to properly design and style the look and feel of your application.  Also, you should try to use the standard styles provided when you create an application.  Setting the style in this way will give your application a consistent look.  Here are a few samples:

<TextBlock x:Name="ApplicationTitle" Text="Demo" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="first page" Style="{StaticResource PhoneTextTitle1Style}"/>

Tip: Using Isolated Storage

For simple values, you can easily get in and out of IsolatedStorageSettings.ApplicationSettings (Dictionary). For more complex data, you can put it into IsolatedStorage.  Since there is no database available in Wp7, one common approach to saving data is to simple serialize your model and save it as a file.  To do so, make sure you mark all of your Model’s classes with the attribute DataContract and make sure the properties have the DataMember attribute.  Here’s a sample class called ListOfStuff as well as the methods I use to read/write it to/from IsolatedStorage:

[DataContract]
public class ListOfStuff : Observable
{
    [DataMember]
    public string Title
    {
        get { return _title; }
        set
        {
            if (_title != value)
            {
                _title = value;
                NotifyPropertyChanged("Title");
            }
        }
    }
    private string _title;

    [DataMember]
    public ObservableCollection<ListCategory> Categories
    {
        get { return _categories; }
        set
        {
            if (_categories != value)
            {
                _categories = value;
                NotifyPropertyChanged("Categories");
            }
        }
    }
    private ObservableCollection<ListCategory> _categories = new ObservableCollection<ListCategory>();
}
public static void SaveToFile(ListOfStuff listOfStuff)
{
    using (IsolatedStorageFile isolatedStorageFile =
    IsolatedStorageFile.GetUserStoreForApplication())
    {
        using (IsolatedStorageFileStream stream =
        new IsolatedStorageFileStream(string.Format("{0}.dat", listOfStuff.Title), FileMode.Create, isolatedStorageFile))
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(ListOfStuff));
            serializer.WriteObject(stream, listOfStuff);
        }
    }
}

public static ListOfStuff LoadFromFile(string listName)
{
    ListOfStuff listOfStuff = null;
    using (IsolatedStorageFile isf =
    IsolatedStorageFile.GetUserStoreForApplication())
    {
        using (IsolatedStorageFileStream stream = 
        new IsolatedStorageFileStream(string.Format("{0}.dat", listName), FileMode.OpenOrCreate, isf))
        {
            if (stream.Length > 0)
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(ListOfStuff));
                listOfStuff = serializer.ReadObject(stream) as ListOfStuff;
            }
        }
    }
    return listOfStuff;
}

Tip: Using the Phone’s Camera

Using the phone couldn’t be simpler, just use the CameraCaptureTask as follows:

**NOTE: As reader Andy Wilkinson pointed out in a comment to this post, I’m not following best practices here.  The way I declare my CameraCaptureTask could lead to problems with tombstoning.  He points out a nice article on MSDN that explains the proper use, please read it here.  Thanks, Andy, for the assistance!

**Another Note:  Another user asked about saving the results of the CameraCaptureTask.  So I’ve written another post that you may find useful.  Please check it out here.

private void Camera_Click(object sender, RoutedEventArgs e)
{
    CameraCaptureTask cameraCaptureTask = new CameraCaptureTask();
    cameraCaptureTask.Completed += cameraCaptureTask_Completed;
    cameraCaptureTask.Show();
}
After the picture is taken, you can access it later, as a Stream.  You can assign it to an Image, save it, or do whatever you want.
void cameraCaptureTask_Completed(object sender, PhotoResult e)
{
    var photoStream = e.ChosenPhoto;
}

Tip: Using Gestures

Of course, you want your application to react when users use common phone Gestures such as Flick, Pinch, Hold, etc.  Doing so is easy too!  The Silverlight Toolkit for Windows Phone (mentioned in second tip above) provides the GestureListener that you will need.  You can see how simple it is to wire up in the following example. In this case, I want the user to be able to hold their finger down on an image to go to “edit mode” where a description TextBox will appear.  In the NoteHold() method (not shown), you can imaging all I need to do is set the description TextBox to be visible.

<Image Source="{Binding Image}">
    <ToolkitControls:GestureService.GestureListener>
        <ToolkitControls:GestureListener Hold="NoteHold" />
    </< span>ToolkitControls:GestureService.GestureListener>
</< span>Image>

Now go start creating apps!

With a day off and nothing to do, I was excited to migrate my home PC to Windows 7.  I’ve used the beta and RC for a while on my laptop but my home PC is a different story.  This is my “main” computer in the house and I need it for lots of stuff. I wasn’t worried about Windows 7 but I also decided to go 64 bit!  Plus I have a lot of software to install and licenses to find, so that always makes me nervous.  All (hopefully) of my data is on different drives than my OS so that makes life easy.

Anyway, I installed Windows 7 64 bit with no issues, so I thought.  Afterwards I even started installing additional software.  It wasn’t until I rebooted my PC without the Windows 7 install DVD in the drive that I realized I had a problem!  On boot up, I got the following doosy of an error:

Disk Boot Failure, Insert System Disk and Press Enter

That is one of those errors that really makes you pause.  It really makes you feel like you are in big trouble.  Figuring maybe there was some piece of installation that wasn’t yet complete, I put the Windows 7 install DVD back in and it booted just fine!  But of course, I still couldn’t boot without the DVD.  This had me bewildered for a while, I tried various combinations of rebooting, and then searched the internet for answers.  All the while, this seemed strangely familiar – I’ve had this happen to me before, but I can’t remember when and why (don’t you hate that?).  I did a reinstallation of Windows 7 but that didn’t fix anything.  I was reading articles about bootmgr and active drives and all kinds of stuff.  From my research, I started to figure out that (I may explain this wrong) when you install Windows, some information about how to boot up goes on your hard drive but it isn’t necessarily the same hard drive (or partition) that Windows gets installed on.  I mentioned early that I had a separate data drive.  As a matter of fact, I have 4 hard drives in my PC.  So now I had an idea of the problem (just an idea at this point) – my PC was probably reading hard drives in the wrong order and couldn’t figure out how to boot up.  I wasn’t sure how to fix it.  Then the answer came to me, it was really quite simple.  Here is how to solve the problem:

When installing Windows 7 (or any Windows version, I’d guess), disconnect all additional hard drives except for the C drive!  Then you know all of the right information goes on the drive that you want to boot off of.

I did just that.  I left just the one HDD connected in my pc and reinstalled Windows 7.  I’m sure there are exceptions to this and reasons why you shouldn’t do this.  I’m not an IT Pro, just a software developer who’s done installations more than a few times.  But this worked for me!  After installation, I just hooked up my additional drives and everything worked perfectly! 

I hope this helps and good luck.  By the way, if you have additional questions related to installation problems, I am probably NOT the guy to ask.  I just got lucky on this one.