6th Anniversary
407 articles ago, I started writing on this website. I’ve gone through several site rewrites, and numerous writing experiments, but I’m still just writing whatever comes to mind.
To celebrate, I thought I’d dig up some of my older, but most popular posts of the past. Some of them make me chuckle even to read the title. Here you go…the top 10 articles this site has ever posted.
10. How Technical Recruiters Get It Wrong (5/19/2011)
9. Are We Being Scammed on Our Displays? (6/6/2011)
8. Be A Creator, Not a Consumer (1/3/2012)
7. 31 Days of Mango: Day 1 – The New Windows Phone Emulator Tools (11/1/2011)
6. Source Control Software Is Too Intrusive (7/21/2011)
5. Why Is Everyone Getting Hacked? (6/30/2011)
4. 31 Days of Silverlight (6/9/2009)
3. 10 Reasons Zune Beats the iPod. Seriously. (11/5/2008)
2. 31 Days of Mango (10/31/2011)
1. 31 Days of Windows Phone (9/30/2010)
A sincere thank you to all of you who read my articles. Without readers, writing wouldn’t be nearly as much fun. Thank you, sincerely, and here’s to another big year of writing.
Be A Creator, Not a Consumer
Things you’re not allowed to think as you read this article:
- I don’t have enough time.
- I’m not smart enough.
- I don’t solve problems every day.
Many years ago, I created a talk called “7 Steps to Shameless Self-Promotion.” The idea was to explain how to get famous (or at least well-known) in your career field. As I’ve grown, both personally and professionally, I’ve realized that it really comes down to one simple idea:
Be A Creator.
Write a book. Start a blog. Build a website. Publish some software. Contribute to an open-source project. Participate in forums. Leave an indelible mark on your community. These are creation.
As I look around our societal landscape, I’m noticing a trend where more and more people are specifically focused on consuming content. Mobile phones, tablets, laptops, television, books, and magazines are all great things, and I even contend that without some consumption, creation would be incredibly difficult. Everything you consume, whether it’s an interesting blog article or even an episode of Jersey Shore (please don’t), it shapes you as a person.
That being said, you’re currently looking for some ways to change or improve your life. It’s the New Year, after all…why not make some impactful changes in what and how you live it?
I have spoken with thousands of developers, and I pose the same question to each of them:
When you solve a coding problem, where do you publicly share that information with others? A blog? A wiki? StackOverflow?
The answer, almost always, is this: Why would anyone read what I write? I pose a similar question to you, my dear defeatist: Why do you read anyone else’s blog? Is it their incredible use of iambic pentameter? Maybe they rhyme the last word of every line. Or maybe, it’s because you find solutions to your problems in their ramblings.
So in this year 2012, I want all of you to create something. Maybe it’s a piece of art. Maybe it’s a new presentation. Maybe it’s a Windows Phone application. Perhaps you’ve found the motivation to write a short story. Whatever it is, DO IT. The easiest way to get started? Start a blog and write about your hobbies. Go to WordPress and set it up. Once a week, write down the new thing that you learned. Maybe it’s that you finally solved a cool coding problem, or realized that bacon really makes your Cinnamon Toast Crunch taste better. Write it down! Someone will enjoy what you have to say, and at a bare minimum, you’ve now documented your solution, so you’ll remember how you did it the next time.
Let me know when you’ve done it. I need some stuff to consume. ![]()
What’s On Your Phone?
I’ve seen many people posting app recommendations for their phones, and I thought I should participate. (Specifically Brian Jackett and Brian Graham.) I tend to prune the apps on my phone quite often, so while this is an alphabetical list of the apps and games on my phone, consider them a recommendation as well. They wouldn’t be on this list if I didn’t use them regularly.
Apps
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
Games
There are many, many more games on my phone than are in this list, but I’ve only included those that I’ve played more than once. Most of the games on my phone were downloaded for (or by) my kids.
My 2011 Wrapup
Time for a quick wrapup of my 2011...
January - Started the year with a successful new session at Codemash. Here's hoping this year's version is even better.
February - Participated in the Microsoft MVP Summit in Redmond, WA. As a Microsoft employee who works in Ohio, I don't get many opportunities to interact with the folks at headquarters. Every trip out there is a rewarding experience.
March - Got to attend South by Southwest (SxSW) in Austin, TX, where I met a ton of passionate mobile developers who I still have relationships with today. Also got to take my wife and children to Hocking Hills State Park, where we did 5 days of "cabining." It was excellent.
April – Participated in the Microsoft MIX conference in Las Vegas, NV. Met a ton of developers that were excited about Windows Phone, and gave many phones away. I also had an opportunity to visit the headquarters of Zappos, which left a lasting impression on me. They have a very unique way they look at their business, and I only hope that when I start a company, that I have the kind of vision they have.
May – May rang in the 2011 edition of the Stir Trek conference, and it was another grand success, with over 700 attendees. 2012 is poised to be even bigger. I also had the good fortune to be asked to travel to Dublin, Ireland to speak with developers all over the island about Windows Phone. Sara and I made the trip a few days early, and toured the Emerald Isle. It was a wonderful, whirlwind trip, and I hope we get more opportunities like that in the future. Almost immediately upon my return however, I tore the ACL and meniscus in my right knee playing volleyball. I’m still doing physical therapy today. To close this busy month, my little sister got married in May. I couldn’t be happier for her and her husband.
June – June kicked off my first ever bookwriting experience, and it didn’t disappoint. I spent the remainder of the summer writing, editing, and re-editing a book on Windows Phone development. I also had my injured knee surgically repaired, and I have someone else’s ligaments in my leg. I am thankful that someone was willing to be a organ donor, even if it was for something like a knee ligament. I also took a week-long vacation to the beaches of North Carolina with some good friends. It was a great trip, and I ‘m looking forward to hanging out with everyone again this year.
July – I turned 35, and my little brother got married. I wish them both the brightest future. Also, I spent most of this month writing the book.
August & September – August and September were probably my busiest travel months. I visited St. Louis, Cleveland x 4, Chattanooga, San Antonio, Los Angeles, Austin, Tulsa, and Terra Alta, WV.
October – In October, I was introduced to the staff at Chagrin Falls High School. I helped them start an “App Club” and they have about 20 students actively building apps for Windows Phone. They’re learning invaluable lessons through this experience about software development, marketing, design, and analytics. I continue to look forward to working with them every month.
November – I got to help kick off the inaugural M3 conference, which is dedicated to all walks of the world of mobile development. Android, iPhone, Windows Phone, design, and business were all represented. It was an eye-opening experience, and a great conference for Columbus to hang its technology hat on.
December – After a week-long trip to Chicago early in the month (I really love that city, btw), I got to take the last half of the month on vacation. Now, I still had work to do, but I did my best to at least do 1/2 days when I could. It’s been a relaxing end to the year, where we will have some neighborhood friends over for board games, Kinect, and some pizza.
I’m looking forward to an exciting 2012. Resolutions will be forthcoming in the next few days.
(This was my 53rd article of the year. Next year, expect the bar to be raised.)
Want to change your Windows Phone emulator?
Today, I discovered that Pedro Lamas had released a skin for the Windows Phone emulator that allowed it to look like the Nokia Lumia 800. (You can see it here.)
This inspired me to create another new skin for my current phone, the HTC Arrive. (Click here to download the HTC Arrive Windows Phone Emulator skin.) To use either of them, you simply need to copy the contents of the zip file to a specific folder on your computer (make sure to save a copy of the original files):
C:\Program Files (x86)\Microsoft XDE\1.0\
Once you’ve done that, your emulator can look like one of the images below!

31 Days of Mango | Now In eBook Format!
The entire series, 31 Days of Mango, is now available in e-book format for Kindle and Nook! If you would like to read all of these articles on-the-go, while supporting the developers that wrote them, they are now available for in the Nook and Kindle stores!
The proceeds of this book will be distributed amongst all of the amazing authors that contributed to this series of articles: Jeff Blankenburg, Jared Bienz, Samidip Basu, Jerrel Blankenship, Dave Bost, Michael Collier, Matt Eland, Jeff Fansler, Gary Johnson, Parag Joshi, Chris Koenig, Doug Mair, and Chris Woodruff.
I also spent the summer writing a physical, printed book with Jesse Liberty, titled Migrating to Windows Phone. If you would like to check it out, you can find it at your favorite bookseller. [It will also be available as an e-book, but won’t be available until later this month.]
31 Days of Mango | Day #31: Promoting Your App
This article is Day #31 in a series called 31 Days of Mango.
Getting users to find your application might seem like something that’s out of your hands, but you’re wrong. There are plenty of things you can do to drive awareness of your application. This section focuses on a few best practices you should utilize for every application that you create.
The First Week Is Vital
Unless your app becomes a runaway sensation, it’s highly likely that your app’s first week in the marketplace will also see your highest number of daily downloads. Getting exposure in the New category is a one time opportunity, and you need to make sure that you leverage this in a way that will make your app shine for much longer than a few days. Ultimately, your goal is to catapault from the New category to the Top Apps category. The 4-5 days that you will wait for your application to be approved should be spent executing a specific strategy for making the public aware of your application.
Linking To Your Application
When you first submit your application to the Marketplace, even before the app is approved, you are assigned a deep link that you can use to direct people to your app using a standard web URL. Here’s an example of the deep link to one of my applications, MathMaster:
http://windowsphone.com/s?appid=f08521cd-1cff-df11-9264-00237de2db9e
This link takes you to a webpage that will attempt to launch the Zune software on the user’s machine, and then direct them to the page for your app in the Marketplace. This link will not work until your application is approved. We recommend using this link everywhere you can, especially on the custom website you created for your apps. You were planning on doing that, right?
Creating a Web Portal for Your Apps
An important thing that you should have learned from the Marketplace walkthrough in Day #27 of the original 31 Days of Windows Phone was that your ability to discuss your apps is pretty limited. A few screenshots, and approximately 2,000 characters is all you have. By creating a website for your applications, you create several new opportunities for yourself.
1. You can create real connections with your users. The Windows Phone marketplace doesn’t give you any indication who your users are. A website allows you to interact with your fans.
2. You can provide a rich amount of information about your app, including videos and other promotional content that might make your app more appealing.
3. You can cross-sell your applications. The Marketplace doesn’t always do a great job at promoting your other applications to potential customers, so leverage your website to make that happen.
4. Your app is now discoverable by people that aren’t actively looking for it in the Marketplace.
5. This website doesn’t have to be a website at all. There’s nothing wrong with creating a page on Facebook or another social network that you can customize. The ultimate goal of this process is to provide a destination for your fans, so that they can spread the word about your awesome app.
If you would like an awesome template for building a custom web page for your application, check out the Windows Phone 7 App Site template on CodePlex. It’s a customizable page that looks great, uses your application screen shots, allows your users to provide feedback, and gives them plenty of ways to learn more about your application. Here’s a screenshot of the template:
Create A Walkthrough Video of Your App
One of the important features your website should include is a video walkthrough of your app. Screenshots in the marketplace are good, but allowing a user to see the actual experience in a controlled way will always provide them with more information. Our recommendation is to use a video screen capture tool like TechSmith’s Camtasia. Camtasia makes it easy to not only capture the video feed from the emulator, but to edit the results, add background music, and introduction information before and after the video. There are probably plenty of tools that will do this for you, but in our experience, Camtasia is the perfect tool for the job. You can see an example of my MathMaster video on YouTube here:
Have fun with it. Your video can add a level of excitement to your app that screenshots can never provide. Now that we’ve focused on websites and videos, let’s discuss the things you can do inside your application to help promote it.
Generating Reviews of Your Application
Reviews can be the deciding factor as to whether or not your application gets the downloads you’re looking for. Unfortunately, there’s not a built-in mechanism for reminding users to review your app. You need to do this yourself. We recommend making it a fun addition to your application rather than an annoyance to your user.
One idea we recommend is to make it an achievement within your app. Litter fun little surprises throughout your application, and you’ll hook an otherwise passive user. Give points for reading the credits of the app. Give more for using the app 10 times. By adding achievements to any application, you’ll find that your users will find themselves coming back again and again. You might also unlock a specific piece of functionality that would otherwise be unavailable when they review your app.
A second idea is to count the number of times your user has launched your application, and prompt them at the 2nd, 5th, and 10th times to review your application. Ask gently. You don’t want to annoy the user, but you do want their review. You can even use the MarketplaceReviewTask to take them directly to the review page for your application.
Great reviews generate more traffic. Oftentimes, a star review can be just as valuable as a written one. The average star rating (1-5) is displayed everywhere your application is, so a high rating often generates more traffic. Encouraging your users to leave a review will have a positive effect on your application’s download rates.
Cross-Selling Your Applications from Each Other
Within your app, you should provide a place where the user can find information about your company, support contacts, and other data like version number. In this place, or certainly in a more prominent location, you have an opportunity to promote the other applications you’ve created. Use your icons. Use the deep links or the MarketplaceDetailTask launcher. Provide a simple way for your user to find and download your other application offerings.
If you really want to get fancy, create an XML file on your webserver that contains all of the information about your apps, and consume this in your apps to create the list of your applications. This way, when you add a new app to your catalog, you won’t have to update all of your apps just to do this cross-promotion.
Summary
There are plenty of things you need to do in order to get your application ready, after you’ve finished your application. Make sure that you’ve considered your promotion strategy before you push the final Submit button on your app. Building a community around your application will only help to make your audience grow, because enthusiastic users are also powerful evangelists of your efforts.
If you’ve taken the time to create an amazing new application for Windows Phone, you need to be certain that it’s going to have the potential impact you’re hoping for. Focusing on monetizing, promotion, and reviews is almost as important your app.
This is the final post in this series. I hope you’ve enjoyed it as much as my guest authors and I did writing it. Thank you for reading all of the posts, and if you haven’t already…
31 Days of Mango | Day #30: Local Database
This article is Day #30 in a series called 31 Days of Mango, and was written by guest author Chris Woodruff. Chris can be reached on Twitter at @cwoodruff.
What is a Local Database?
In the original version of Windows Phone 7, we could save data but it took either custom code or using third party databases like SterlingDB to have the relational data repository that some applications need. This limited the types of applications some developers could produce for users.
In Windows Phone 7 Mango, developers still have isolated storage to keep data and information stored for their applications but now have SQL CE as a relational storage feature to created even better applications for Windows Phone.
Like other database solutions for the original Windows Phone 7, the native SQL CE database built into Mango has it data stored in the device’s Isolated Storage. You can learn more about Isolated Storage here. Microsoft also did not create new ways to work with the data on the phone and instead implemented LINQ to SQL for all database operations. LINQ to SQL is used to do all functions for the application when dealing with data including creating the data, populating data into the database, getting data and finally saving and deleting data.
A good tutorial for LINQ to SQL is here on MSDN.
Setting up a Local Database for your Mango Application
Like all starting points for Windows Phone 7, we will start with creating the Windows Phone Databound Application project within Visual Studio 2010.
We could have started with just the Windows Phone Application project but I like the additional features that the Databound project gives you to allow your application to have better design patterns like Model-View-ViewModel (MVVM).
Next we will update the MainPage of the project to allow for the data to be added to the database. Our data example will be collecting ideas that we all have and need to remember. We will not go into much detail about the design of the MainPage but here is the XAML to get the look and feel for our Idea collector.
x:Class="_31DaysMangoStorage.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"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed.-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title.-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="31 Days of Mango" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="Idea Tracker" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here.-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Bind the list box to the observable collection. -->
<ListBox x:Name="toDoItemsListBox" ItemsSource="{Binding IdeaItems}"
Grid.Row="0" Margin="12, 0, 12, 0" Width="440">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" Width="440">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<CheckBox
IsChecked="{Binding IsComplete, Mode=TwoWay}"
Grid.Column="0"
VerticalAlignment="Center"/>
<TextBlock
Text="{Binding ItemName}"
FontSize="{StaticResource PhoneFontSizeLarge}"
Grid.Column="1"
VerticalAlignment="Center"/>
<Button
Grid.Column="2"
x:Name="deleteTaskButton"
BorderThickness="0"
Margin="0"
Click="deleteTaskButton_Click">
<Image Source="appbar.delete.rest.png"/>
</Button>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox
x:Name="newIdeaTextBox"
Grid.Column="0"
Text="add new idea"
FontFamily="{StaticResource PhoneFontFamilyLight}"
GotFocus="newIdeaTextBox_GotFocus"/>
<Button
Content="add"
Grid.Column="1"
x:Name="newIdeaAddButton"
Click="newIdeaAddButton_Click"/>
</Grid>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
Also to allow for your application to compile and run without doing anything the code below will be added to the MainPage.xaml.cs file inside the MainPage class implementation and after the constructor.
{
// Clear the text box when it gets focus.
newIdeaTextBox.Text = String.Empty;
}
private void newIdeaAddButton_Click(object sender, RoutedEventArgs e)
{
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
// Call the base method.
base.OnNavigatedFrom(e);
}
Working with the Data Context
The Data Context is the point that will allow us to work with the database and also the proxy classes that represent our database tables. The data context is also a class and works against a number of “plain old CLR object” (POCO) classes that we will create for this project. The table objects that represent our database tables will contain a collection of entities for each table record stored in the database. Other details about our database are also given to us through the data context such as table keys and association mappings between tables.
Just a reminder that this local database has no connection with SQL Server 2008 R2 that is running locally on your PC or a server in your company or hosting provider and is only to hold data on your device.
There is not much to the DataContext class besides the connection string we are familiar in development and properties to each table that will exist in our database. Think of the DataContext as the “Hub” for your application’s data. The code for the sample application’s DataContext is below.
{
// Specify the connection string as a static, used in main page and app.xaml.
public static string DBConnectionString = "Data Source=isostore:/Ideas.sdf";
// Pass the connection string to the base class.
public IdeaDataContext(string connectionString)
: base(connectionString)
{ }
// Specify a single table for the to-do items.
public Table<IdeaItem> IdeaItems;
}
Note that IdeaItem type will be detailed in the next section covering creating the Database.
Creating the Database
Unlike applications that are run from your PC or on IIS 7, databases in Windows Phone 7 Mango must be created and initialized on the first instance your app runs on the phone. We will first look at creating the classes that will represent our database tables and then look at database initialization.
For each table that we need to be built and exposed through the database on our phone for the application a new POCO needs to be created. Since these classes represent the entities that will be stored in the database let’s call them Entity classes. To begin the Entity class must adhere to the following two interfaces:
· INotifyPropertyChanged -- The INotifyPropertyChanged interface is used to notify clients, typically binding clients that a property value has changed.
· INotifyPropertyChanging -- The INotifyPropertyChanging interface is used to notify clients, typically binding clients that a property value is changing.
These two interfaces will allow each entity to notify the DataContext that is in the process of changing or has changed. This will then be reflected to the XAML views of our application through the binding we have set up.
The Enity class must be annotated as a Table to allow the DataContext to know how to work with it. An Entity classes must also have private and public properties for each Entity property as well as having the private property annotated to give valuable metadata about the Entity property (aka the database column). Remember to have primary key properties for each of your Entity classes.
Below is the IdeaItem Entity class that will be located in the IdeaItems table referenced in the DataContext we created before.
public class IdeaItem : INotifyPropertyChanged, INotifyPropertyChanging
{
private int _ideaItemId;
[Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
public int IdeaItemId
{
get
{
return _ideaItemId;
}
set
{
if (_ideaItemId != value)
{
NotifyPropertyChanging("IdeaItemId");
_ideaItemId = value;
NotifyPropertyChanged("IdeaItemId");
}
}
}
private string _itemName;
[Column]
public string ItemName
{
get
{
return _itemName;
}
set
{
if (_itemName != value)
{
NotifyPropertyChanging("ItemName");
_itemName = value;
NotifyPropertyChanged("ItemName");
}
}
}
private bool _isComplete;
[Column]
public bool IsComplete
{
get
{
return _isComplete;
}
set
{
if (_isComplete != value)
{
NotifyPropertyChanging("IsComplete");
_isComplete = value;
NotifyPropertyChanged("IsComplete");
}
}
}
[Column(IsVersion = true)]
private Binary _version;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangingEventHandler PropertyChanging;
private void NotifyPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
}
Finally we must create the database is it does not exist. This will be done in the Application class’s constructor. You will find this in the App.xaml.cs file. The code that will be added to the end of the constructor method is as followed.
{
if (db.DatabaseExists() == false)
{
db.CreateDatabase();
}
}
We now have a database that has been created and initialized in application’s Isolated Storage. One more thing to remember is that local databases in Windows Phone 7 mango cannot be shared directly between apps on the phone due to the sandboxing security set up in the Windows Phone 7 Mango operating system.
LINQ to SQL Support for Windows Phone Mango
Windows Phone 7.1 SDK allows for some but not all features of LINQ to SQL inside the Windows Phone. The following are just a few things to remember when working with data and LINQ to SQL in Windows Phone 7 Mango.
· ExecuteCommand is not supported
· ADO.NET Objects (such as DataReader) are not supported
· Only Microsoft SQL Server Compact Edition (SQL CE) data types are supported
To get more limitations and features of using LINQ to SQL on Mango please read the MSDN page here.
Retrieving Data from a Local Database
To retrieve data or any data related work with the local database, we must first create the DataContext and connect to the database. This will happen in MainPage.xaml.cs through a private variable for the DataContext, an observable collection property for the ideas in the database table and in the MainPage constructor as followed.
private ObservableCollection<IdeaItem> _ideaItems;
public ObservableCollection<IdeaItem> IdeaItems
{
get
{
return _ideaItems;
}
set
{
if (_ideaItems != value)
{
_ideaItems = value;
NotifyPropertyChanged("IdeaItems");
}
}
}
public MainPage()
{
InitializeComponent();
ideaDB = new IdeaDataContext(IdeaDataContext.DBConnectionString);
this.DataContext = this;
}
To get our ideas located in the local database we will use LINQ to SQL to query and get the collection back from the database via the DataContext.
{
var ideaItemsInDB = from IdeaItem todo in ideaDB.IdeaItems
select todo;
IdeaItems = new ObservableCollection<IdeaItem>(ideaItemsInDB);
base.OnNavigatedTo(e);
}
The ideas are now bound and reflected in the MainPage.xaml.

Storing Data to a Local Database
Finally we will build the saving of our idea data to the local database. We will not send the ideas to the database until we need to increase performance. We will keep all of the ideas in the local observable collection we created as a MainPage property (IdeaItems). The addition of new ideas to the local database will take place on the button click when the new idea is added to the IdeaItems collection.
{
IdeaItem newIdea = new IdeaItem { ItemName = newIdeaTextBox.Text };
IdeaItems.Add(newIdea);
ideaDB.IdeaItems.InsertOnSubmit(newIdea);
}
As mentioned before the ideas collected from the user will not be stored in the database until the application has transitioned from the MainPage either when the user exits the application or the application moves to a new page in the application. The code for the OnNavigateFrom event for the MainPage is below.
{
base.OnNavigatedFrom(e);
ideaDB.SubmitChanges();
}
Summary
So that’s pretty much it! You now have a simple way to create, store, and retrieve relational data in your Windows Phone applications. How are you going to use this?
To download a full Windows Phone project that includes all of the code and concepts from this article, click the Download Code button below.
Tomorrow, in the final article of this series, we will cover the best practices for promoting your Windows Phone applications. See you then!
31 Days of Mango | Day #29: Globalization
This article is Day #29 in a series called 31 Days of Mango, and was written by guest author Matt Eland. Matt can be reached on Twitter at @integerman.
Globalization versus Localization
People often get confused when discussing globalization and localization. Both deal with presenting content in a user-friendly manner across the world, but the distinction is that globalization deals with formatting elements such as times, dates, currencies and numbers in the way that the user is familiar with whereas localization involves displaying the user’s native language in the user interface. This article will cover using both techniques to build applications that can reach a large audience in the most user-friendly way possible.
We will be building a simple application over the course of this article that supports both globalization and localization. This application quickly generates an e-mail message that lets a contact know you’re running late to an appointment.
Configuring Localization Support
After creating a new C# Windows Phone project, we’ll need to do a few things to configure the application to support localization.
Defining a neutral language for the assembly
Because we’re localizing our application, we need to tell the project what the default locale is. To do this, we’ll go into the properties dialog for the project and click on “Assembly Information…” and then specify the neutral language for our assembly – that is, the language that will be used if no locale-specific resources are defined that matches the user’s locale. For this example, we’ll set our neutral language to English (United States).

Indicating supported culture
Next we need to tell the project what languages are supported. Visual Studio doesn’t currently expose this part of the project information, but we can easily edit it. Make sure you save all changes so any changes to the .csproj file are saved to disk before we edit the file. Next go to the project’s folder on the disk drive by right clicking on the project and selecting “Open folder in Windows Explorer”. Select the .csproj file for your application (be careful not to select the .csproj.user file) and open it with Notepad or your favorite text editor.
Look for the <SupportedCultures></SupportedCultures> element and add the culture codes of the cultures you wish to support separating each culture with a semicolon. This list should not include the neutral language of the assembly. See http://msdn.microsoft.com/en-us/library/hh202918(v=VS.92).aspx for a list of cultures supported by various versions of Windows Phone. For the purposes of this example, we’ll be supporting Spanish, simplified Chinese and French in addition to the default culture of English (United States) so our SupportedCultures node looks like:
<SupportedCultures>es-ES;zh-CN;fr-FR</SupportedCultures>
After making your changes, save the .csproj file and go back to Visual Studio. Click reload when Visual Studio prompts you that the project has changed so the changes to the project file can take effect.
Create a base resource file
Now that we have a default culture and a list of other supported cultures, we can start defining culture-specific resources. We’ll start by adding a file for default resources and move on to adding resources for specific cultures. As a localization best-practice, any user-facing string should be included in these files instead of hard-coded in XAML or a code file.
We need to add a resource file to the project that defines the default language strings for the application. To do this, we’ll right click on our project in the solution explorer and choose “Add -> New Item”. From here, we’ll add a resource file. This file can be called whatever you like, but for this example we will call it Strings.
Adding the file takes us into the resource editor for this resource. The resource editor contains a table with three columns: Name, Value and Comment. Name is the auto-generated code-behind name for the resource and serves as a unique key for identifying a resource. Value is the culture-specific value for this resource and is what we’ll use to store user-facing text. Comment is not used by the application but is helpful for noting what each resource means and where it’s used and can help greatly during translation to other languages. You’ll also see an access modifier at the top of the resource editor. This is internal by default but we need to change this to public so we can bind to these values in XAML later.
Here is our example after adding the appropriate strings and changing the access modifier to public:
Create culture specific resource files
Now that we have our default resources defined, we can begin creating customized resources for the project. We’ll start by defining the Spanish resources for this application. Control-click and drag Strings.resx in solution explorer to create a copy of String.resx then rename “Copy of Strings.resx” to “Strings.es-ES.resx” (es-ES is the culture code for Spanish). It’s important that this new file start with the same name as your previous resource file but have the matching locale at the end of it or this file will not properly map to the intended locale. Once you’ve renamed that file, open up the Strings.es-ES.resx file and modify the Value column for each resource. A good source for translations is Bing Translator, though you should verify translations with someone who understands the language before deploying. It’s important that the Name column matches between resource files so that resources can be appropriately mapped.
Once you’ve finished with this, follow the same procedure for any additional locales you wish to support being careful that all resource files have an access modifier of Public, keep the same name, and contain the appropriate culture code. It’s also important to note that the resource editor may not display certain foreign character sets correctly when copying and pasting from Bing Translator to the resource editor, but these characters should look fine on the actual device and the emulator.
Building the non-localized user interface
Now that we have a set of localized strings, we’d better build a user interface that can use them. Our sample application will have a few fields, an application bar and a standard header. Because we want to include dates in this example to demonstrate globalization, we will be referencing the Silverlight Toolkit for Windows Phone and using the TimePicker control contained in that assembly. This article won’t go into detail on downloading, installing and referencing the toolkit, but the toolkit is freely available and help is available online.

Our non-localized MainPage.xaml looks like:
x:Class="PhoneApp1.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" xmlns:Controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="696"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsMenuEnabled="False">
<shell:ApplicationBarIconButton IconUri="/icons/appbar.feature.email.rest.png"
IsEnabled="True"
Text="send"
Click="HandleSendClick" />
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot"
Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel"
Grid.Row="0"
Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle"
Text="I'm Running Late"
Style="{StaticResource PhoneTextNormalStyle}" />
<TextBlock x:Name="PageTitle"
Text="Send Message"
Margin="9,-7,0,0"
Style="{StaticResource PhoneTextTitle1Style}"
TextWrapping="Wrap" />
</StackPanel>
<ScrollViewer Margin="12,0,12,0"
Grid.Row="1">
<StackPanel x:Name="ContentPanel">
<TextBlock TextWrapping="Wrap"
Text="To"
Style="{StaticResource PhoneTextSubtleStyle}" />
<TextBox x:Name="txtTo"
TextWrapping="Wrap"
InputScope="EmailUserName" />
<HyperlinkButton Content="Choose a contact"
HorizontalContentAlignment="Left"
Foreground="{StaticResource PhoneAccentBrush}"
Click="HandleChooseContactClick"
Margin="{StaticResource PhoneVerticalMargin}" />
<TextBlock TextWrapping="Wrap"
Text="Subject"
Style="{StaticResource PhoneTextSubtleStyle}" />
<TextBox x:Name="txtSubject"
TextWrapping="Wrap"
Text="I'm Running Late"
InputScope="Text" />
<CheckBox x:Name="checkIncludeReason"
Content="Include a reason" />
<TextBox x:Name="txtReason"
TextWrapping="Wrap"
Text="Traffic"
InputScope="Text"
IsEnabled="{Binding IsChecked, ElementName=checkIncludeReason}" />
<CheckBox x:Name="checkIncludeETA"
Content="I should arrive by" />
<Controls:TimePicker x:Name="timeArrival"
IsEnabled="{Binding IsChecked, ElementName=checkIncludeETA}"
Margin="0,-12,0,0" />
<CheckBox x:Name="checkIncludeDiagnosticData"
Content="Include extra data" />
</StackPanel>
</ScrollViewer>
</Grid>
</phone:PhoneApplicationPage>
Obviously this XAML contains a number of hardcoded strings which is not what we want for a localizable application. We need to get the user interface to take advantage of our resource strings.
Retrieving Resource Strings in XAML
Luckily, the resource designer we’ve been working with has already automatically generated classes for accessing these resources. Unfortunately, we can’t easily bind to these in XAML because the auto-generated Strings class has an internal constructor and static properties so we’ll need to create a resources wrapper object that exposes these in a way we can bind to.
Add a new code file to the solution called StringProvider.cs and include the following code:
{
public class StringProvider
{
private readonly Strings _resources = new Strings();
public Strings Resources
{
get { return _resources; }
}
}
}
Now go into your App.xaml file and add a new resource to the application with an appropriate xmlns qualifier. This resource will be available across the entire application and will provide easy access to string localization. When done, our App.xaml will look like:
x:Class="PhoneApp1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:local="clr-namespace:PhoneApp1">
<!--Application Resources-->
<Application.Resources>
<local:StringProvider x:Key="Strings" />
</Application.Resources>
<Application.ApplicationLifetimeObjects>
<!--Required object that handles lifetime events for the application-->
<shell:PhoneApplicationService
Launching="Application_Launching" Closing="Application_Closing"
Activated="Application_Activated" Deactivated="Application_Deactivated"/>
</Application.ApplicationLifetimeObjects>
</Application>
Now that we’ve defined our StringProvider as a resource, we can bind to it in the main page. In this case we’re binding to a sub-property on the Resources property representing the name of the resource as we defined it earlier in the resources collection and using the application StringProvider object as a binding source. For example, our page title TextBlock becomes:
Both Blend and Visual Studio’s design surfaces should recognize this binding and display the neutral language string (the value in Strings.resx) in the designer if the project has been rebuilt since the resource was added.
When building localizable applications, be aware that in many languages resource strings will be longer than in the default locale. Because of this, it’s important that you set TextWrapping="Wrap" where applicable and use flexible layout structures such as ScrollViewers and StackPanels that can adapt to multi-line content when needed. Due to potentially long resource strings, setting SupportedOrientations="PortraitOrLandscape" on the page element is recommended where appropriate.
It’s also important to be aware that not all locales support different fonts. Your best bet for application localization is to avoid manually specifying fonts or font weights and instead relying on the built-in styles. See http://msdn.microsoft.com/en-us/library/hh202920(v=VS.92).aspx for more information.
Referring to localized strings in code behind
This approach will work for most of the strings, but Metro design guidelines require the application title at the top of the page to be in all caps and our string in the resource file uses initial caps. We could define a new resource just for the title label or write a custom to uppercase value converter for the binding, but instead we’ll just set the title in the code behind so we can demonstrate accessing localized resources from code by adding the following line to the MainPage’s constructor:
ApplicationTitle.Text = Strings.AppTitle.ToUpper(CultureInfo.CurrentCulture);
Localizing application bars
Application bar elements do not presently support binding since they’re not truly customizable Silverlight content. Instead, we’ll have to manually set the text of our ApplicationBarIconButton in the code behind by referring to the auto-generated property for our resource name on the Strings resource as follows:
{
InitializeComponent();
// Ensure that the app title uses all caps
ApplicationTitle.Text = Strings.AppTitle.ToUpper(CultureInfo.CurrentCulture);
// Specify the text explicitly on the app bar using our resource string.
var button = (ApplicationBarIconButton)ApplicationBar.Buttons[0];
button.Text = Strings.ButtonSend;
// By default, we're going to be 15 minutes later than now
timeArrival.Value = DateTime.Now.AddMinutes(15);
}
We now have a localized application. Testing the application in the emulator using French language settings results in the following:

Supporting Globalization
Now that we have a localizable application, let’s get into the globalization side of things. Since globalization deals with respecting a user’s cultural settings, it’s important to provide the correct IFormatProvider to various string formatting methods whenever appropriate. Thankfully, .NET provides CultureInfo.CurrentCulture which represents the user’s current cultural settings and can be used for formatting strings for the user interface. When doing standard comparisons or dealing with serialization or other non-user-facing operations, it’s important to use CultureInfo.InvariantCulture to ensure your app works properly in all culture settings.
Unlike localization, you don’t have to do anything to support a particular culture and the .NET framework will take care of most culture formatting operations for you. It is still a best practice to provide the appropriate format strings and specify CultureInfo.CurrentCulture as an IFormatProvider where appropriate.
For example, the code our application uses to generate an e-mail makes explicit use of the CurrentCulture and format strings:
{
// Build the E-Mail body from the user's selections
var body = new StringBuilder();
body.AppendLine(Strings.EmailHeader);
// Include reason if applicable
var culture = CultureInfo.CurrentCulture;
if (checkIncludeReason.IsChecked == true)
{
body.AppendLine();
body.AppendLine(string.Format(culture, "{0}: {1}", Strings.EmailReason, txtReason.Text));
}
// Include eta if applicable
if (checkIncludeETA.IsChecked == true)
{
body.AppendLine();
// Since we've specified our ValueFormatString for the Time Picker, we can just rely on the ValueString here.
body.AppendLine(string.Format(culture, "{0}: {1}", Strings.CheckShouldArriveBy, timeArrival.ValueString));
}
// Include extra globalization examples if applicable
if (checkIncludeDiagnosticData.IsChecked == true)
{
body.AppendLine();
// this is the standardized culture name such as en-US or zh-CH
body.AppendLine(culture.Name);
body.AppendLine(string.Format(culture, "pi: {0}", Math.PI));
body.AppendLine(string.Format(culture, "number: {0}", -1));
body.AppendLine(string.Format(culture, "currency: {0:c}", 4200.00));
body.AppendLine(string.Format(culture, "date: {0:D}", DateTime.Today));
body.AppendLine(string.Format(culture, "time: {0:t}", DateTime.Now));
}
// Now that we have our message body, do something with it. What we do depends on what we're running on.
if (Microsoft.Devices.Environment.DeviceType == DeviceType.Emulator)
{
// The emulator doesn't currently support sending E-Mails so we'll just output the text to a message box
MessageBox.Show(body.ToString());
}
else
{
// Compose the E-Mail and show it to the user to preview before sending
var task = new EmailComposeTask {Subject = txtSubject.Text, To = txtTo.Text, Body = body.ToString()};
task.Show();
}
}
Since globalization is separate from localization, running the app in a language without locale-specific strings will result in properly globalized values such as these German settings in the image below:

Specifying format strings in XAML
Occasionally you’ll want to be able to specify a format string in XAML either as a parameter to a value converter or as a property on a built in control. In our example we’ll explicitly set the format string of our TimePicker to the short time format for the current culture (“t”). To do this, we prefix our format string with a pair of braces as shown here:
It’s also possible to set this in code behind either as
timeArrival.ValueStringFormat = "{0:" + info.ShortTimePattern + "}";
or, more concisely:
Testing for different cultures
By this point we’ve built a fully functional app that supports globalization and localization. You may be wondering how to test applications for different locales. Actual Windows Phone devices may not allow you to change your phone’s display language, but thankfully Microsoft provided this capability in the emulator.
To access these settings, go into the emulator’s applications menu on the start screen and choose the settings app. From there click on region+language on the system pivot item. 
The region & language screen allows you to customize the display language on the phone by setting the Display language picker box to the language you want to test and then clicking on the “tap here to accept changes” hyperlink. Doing so will reboot the emulator’s image of the Windows Phone operating system and apply the language and globalization settings you’ve chosen. It can be confusing to use the settings pages in a language you don’t know to change regional settings so it’s a good idea to study the layout of the screen before applying your changes. Once the emulator reboots, launching your application in the emulator will allow you to verify that the app respects the user’s language and cultural settings.
Deployment Considerations
When deploying an application that supports different languages and cultures, be sure to opt-in to distribution in the markets you support either by selecting worldwide distribution when publishing your app and setting the prices or by selecting the individual locales that you explicitly intend to support.
Summary
You now know how to create an application from start to finish that will offer the best experience by providing a properly globalized and localized application to the global audience that uses Windows Phone.
To download a full Windows Phone project that uses all of the code and examples from above, click the Download Code button below.
Tomorrow, we are going back to data, and we’re going to cover how to use a local database in your application. See you then!
31 Days of Mango | Day #28: Media Library
This article is Day #28 in a series called 31 Days of Mango, and was written by guest author Jeff Fansler. Jeff can be reached on Twitter at @fanzoo.
Today we are going to take a look at the MediaLibrary class that is part of the Microsoft.Xna.Framework.Media namespace. As the name suggests, this class gives us access into the users Media Library. A Media Library on Windows Phone stores pictures and music. By using the Media Library you can integrate this content into your own applications. There are several reasons a developer may want to do this. Here are a few ideas:
- To show the user a list of songs and let them select the background music while using your app.
- To allow the user to download their images from a service (i.e. Flickr) and add them to the Media Library.
- To use music artist or genre data from the Media Library to make suggestions on other similar content the user may be interested in.
In order to show how to use the Media Library I’ve created a sample application. This app will list all the songs that are in the user’s Media Library, play a song when the user selects a song, and allow the user to select an image from the Media Library to use as the background. The app uses the Media Library to get a list of songs and it also saves an image to the Media Library for the user.
![clip_image002[7] clip_image002[7]](http://www.jeffblankenburg.com/wp-content/uploads/2011/11/clip_image0027.jpg)
Saving an Image to the Media Library
In the sample app I have added image1.jpg as a resource. It’s an awesome image and I’m sure all of the users are going to want it so we are going to save this image to the Media Library. The sample app saves this image in the Application_Launching method in the App.xaml.cs. Here is the code that does this work:
var image = library.Pictures.Where(p => p.Name == imageName).SingleOrDefault();
if (image == null)
{
var resource =
Application
.GetResourceStream(new Uri(string.Format("/31DaysMediaLibrary;component/Images/{0}",
imageName),
UriKind.Relative));
var bitmap = new BitmapImage();
bitmap.SetSource(resource.Stream);
// Save the image to the camera roll or saved pictures album.
library.SavePicture(imageName, bitmap.ToStream());
}
Most of this code is simply working with loading the image. There are a few important lines here that are using the Media Library. Let’s take a closer look at a few of these lines.
This line creates a new MediaLibrary class. This is what will give you access to the Media Library properties and methods.
This line searches the library for any pictures that are saved with the imageName. If that image exists already, the code does not save it again.
This line saves the BitmapImage to the library. You may notice that a BitmapImage doesn’t normally have a ToStream method. I think it should so I’ve used an extension method to add it. The extension class doesn’t have anything to do with the Media Library but here it is so you know how it works:
{
public static Stream ToStream(this BitmapImage bitmap)
{
var writeableBitmap = new WriteableBitmap(bitmap);
var stream = new MemoryStream();
writeableBitmap.SaveJpeg(stream, bitmap.PixelWidth, bitmap.PixelHeight, 0, 100);
stream.Position = 0;
return stream;
}
}
After that code is executed, the image will be accessible in the Media Library. To show this in our sample app you can click the gear icon in the app tray and the new image will be available to be selected using a PhotoChooserTask.
![clip_image004[6] clip_image004[6]](http://www.jeffblankenburg.com/wp-content/uploads/2011/11/clip_image0046.jpg)
Getting a List of Songs
In the sample app the screen shows a list of the songs that are in the user’s Media Library. The list is a ListBox. A DataTemplate is defined that binds the Text property of two TextBlock’s. One displays the song title and the other displays the artist. Here is what the XAML looks like for the ListBox:
x:Name="lstSongs"
SelectionChanged="SongSelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel
Margin="0,0,0,17"
Width="432"
Height="78">
<TextBlock
Text="{Binding Name}"
TextWrapping="Wrap"
Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock
Text="{Binding Artist.Name}"
TextWrapping="Wrap"
Margin="12,-6,12,0"
Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Setting the ItemsSource to the list of songs is quite simple:
lstSongs.ItemsSource = library.Songs;
What Else Is There?
There are a few other properties off of the MediaLibrary class to take a look at:
Albums - This is similar to the Songs collection but lists albums instead.
Artists - Just like the Albums collection, this collection lists the artists of the songs.
Genres – This collection lists the genres of the songs.
Playlists – This collection lists the playlists that the user has added to their library.
Summary
As you can see, using the Media Library is quite easy. Most of the code in the sample app is written to use the content, not to access it from the library. I talked about how to access the Songs collection and how to save an image to the library. I discussed a few ways to use the library in your own apps. I’m sure there are many other ways to use this content. Have fun and I can’t wait to see your apps.
To download a full Windows Phone project that includes all of the code and concepts from this article, click the Download Code button below.
Tomorrow, we will cover globalization/localization in the article, and show you how easy it is to include this in your Windows Phone project. See you then!






























