31 Days of Windows Phone | Day #31: Charting Data

Today is Day #31, the final day of the series 31 Days of Windows Phone.  Can you believe it’s over?

Yesterday, I discussed gestures, and how we can easily capture our user’s touch input in a variety of ways.  Today, in my final article in this series, I’ll be covering charting, as promised.  I will show you how simple it is to add pie, bar, and other charts to our applications.

Get the Silverlight Toolkit

You may recall that on Day #21, I covered the Silverlight Toolkit for Windows Phone.  In that article, I also mentioned that there is another giant set of controls available in the form of the standard Silverlight Toolkit.  You need to go download this set of controls, and install them on your machine.  You can get the Silverlight Toolkit on Codeplex.  What I’m going to recommend, however, is to use the specific assemblies that I am packaging with my sample code (unless you’d prefer to beat your head on your desk like I have been this evening).  Once you’ve installed it, you’ll have an abundance of additional controls available to you.  We’re specifically going to cover the PieSeries and BarSeries.

Using the PieSeries control

Make sure you add both  the System.Windows.Controls and the System.Windows.Controls.DataVisualization.Toolkit assemblies to your project (and again, use the ones I provide in my sample code, to avoid confusion.)

We also need to make sure we add that namespace to our page.  I am creating a separate page in my sample application for each of these controls, but you certainly don’t need to.  Add this xmlns statement to the top of your XAML file:

xmlns:chart="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"

Once we’ve done this, we have the ability to add charts to our application.  Let’s add a Chart that contains a PieSeries control:

<chart:Chart>
	<chart:PieSeries />
</chart:Chart>

The above XAML is about as simple as it comes, and you haven’t really done anything with ANYTHING yet.  In this example, I’m actually going to bind this Chart to actual data in my code-behind, and even change the formatting of the PieSeries chart a little.

To bind data to this control, I’m going to do it exactly the same way that I did it on Day #25, when we got data from the Twitter API.  It’s really as simple as setting the ItemsSource property of the PieSeries control.  Here’s how my entire PieSeriesControl.xaml.cs file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Controls.DataVisualization.Charting;

namespace Day31_ChartingControls
{
	public partial class PieSeriesControl : PhoneApplicationPage
	{
		VideoGameCharacter[] pacman = new VideoGameCharacter[2] { new VideoGameCharacter("Resembles", 8), new VideoGameCharacter("Doesn't resemble", 2)};

		public PieSeriesControl()
		{
			InitializeComponent();
			PieSeries pieSeries = PieChart.Series[0] as PieSeries;
			pieSeries.ItemsSource = pacman;
		}
	}

	public class VideoGameCharacter
	{
		public string Label { get; set; }
		public int Value { get; set; }

		public VideoGameCharacter(string label, int value)
		{
			Label = label;
			Value = value;
		}
	}
}

You’ll notice that I don’t actually refer directly to the PieSeries control, but instead its parent Chart control, and then the series at position 0 in its Series collection.  I’m not entirely clear on why this works, and referring directly to the PieSeries control doesn’t work, but in nearly every other example I’ve found, this is also how others have bound their data, so I’m going to go with it.

We also need to specify some binding information in our PieSeries control back in our XAML file.  On its own, this is the minimum you need to specify: the DependentValueBinding and the IndependentValueBinding.  As you may guess, the DependentValueBinding is the value that actually gets used in the Pie Chart, and the IndependentValueBinding is generally the “label” for that data.

<chart:Chart x:Name="PieChart">
	<chart:PieSeries
		IndependentValueBinding="{Binding Label}"
		DependentValueBinding="{Binding Value}"/>
</chart:Chart>

pie

If you crack open my sample code, there’s more code about how I changed the template of the PieSeries control, and rotated it to make my joke data more relevant.  The best part about the above example is that every type of chart functions almost identically.  Let’s look at the BarSeries control to see the similarities.

Using the BarSeries control

In nearly an identical way, we can use the BarSeries control.  Creating the control, binding data…it’s all the same.  In this example, though, I want to show you how you can specify the specific data on your chart’s axes (not the weapons, but the plural of axis).  In this example, I’m creating the same master Chart control, and adding my BarSeries control to it.  Here’s a whole pile of XAML to look at:

<chart:Chart x:Name="BarChart" Foreground="Gray" Title="Midwest City Populations">
	<chart:BarSeries
		Title="Population"
		IndependentValueBinding="{Binding Name}"
		DependentValueBinding="{Binding Population}"/>
	<chart:Chart.Axes>
		<chart:CategoryAxis Title="City" Orientation="Y" FontStyle="Italic"/>
		<chart:LinearAxis Title="Population" Orientation="X" Minimum="0" Maximum="2500000" Interval="500000" ShowGridLines="True"  FontStyle="Italic"/>
	</chart:Chart.Axes>
</chart:Chart>

In this case, you can see that I’m specifically calling out the Category and Linear axes, and defining their Titles (labels), Orientations, and even maximum and minimum values if I desire.  Incredibly powerful if you’d like to control the labels it would have otherwise created for you.

Here’s a look at the entirety of my BarSeriesControl.xaml.cs file, so that you can see that the binding system works exactly the same (though I used different data).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Controls.DataVisualization.Charting;

namespace Day31_ChartingControls
{
	public partial class BarSeriesControl : PhoneApplicationPage
	{
		List<City> cities = new List<City> {
			new City { Name = "CLE", Population = 2250871 },
			new City { Name = "CMH", Population = 1773120 },
			new City { Name = "CVG", Population = 2155137 },
			new City { Name = "DET", Population = 4425110 } };

		public BarSeriesControl()
		{
			InitializeComponent();
			BarSeries bs = BarChart.Series[0] as BarSeries;
			bs.ItemsSource = cities;
		}
	}
}

bar

That’s about it!  You can of course see all of the Silverlight Toolkit at http://silverlight.codeplex.com.  Build a simple charting application for your manager, and you’ll be amazed how quickly Windows Phone becomes a platform he/she needs to to talk with the executives about. 🙂  It’s all about business needs, right?

Download the Code

This downloadable code contains examples of the PieSeries, BarSeries, and ColumnSeries chart controls.  You may use this code for any of your projects.

download

31 Days of Windows Phone | Day #30: Gestures

This post is Day #30 in a series called the 31 Days of Windows Phone.  It’s hard to believe that we’ve made it this far, but tomorrow is the last article in this entire series.

Yesterday, I wrote about the Advertising SDK, and how you can simply add advertisements to your applications to generate extra revenue.  Today, we’re going to focus on Gestures, and how we can use an XNA assembly in our Silverlight applications to simply recognize our user’s touch input.

What is XNA?

This entire series has focused on Silverlight, but there’s a sister technology called XNA that is also available for writing applications for Windows Phone 7.  You’ll generally find game developers using this technology, as it has been the platform for the Zune and the Xbox 360 for several years.  If you want to learn more about XNA, check out this great list of tutorials: http://create.msdn.com/en-us/education/roadmap

Getting the XNA assembly in our project

The first thing we need to do is get the Microsoft.Xna.Framework.Input.Touch assembly reference in our project.  Right click on your project name, and choose this assembly from the list.

addreference

Accessing the TouchPanel

Part of the XNA world revolves around the idea of a TouchPanel, or the entire surface of the screen.  By accessing this TouchPanel, we can tie directly into its Gesture library, and even enable only the specific gestures we’re interested in.

To do this, we just need to add a USING statement at the top of our code-behind.

using Microsoft.Xna.Framework.Input.Touch;

Once this is added to our page, we can enable the specific gestures we want to capture:

TouchPanel.EnabledGestures = GestureType.Hold | GestureType.Tap | GestureType.DoubleTap | GestureType.Flick | GestureType.Pinch;

I would generally do this directly in the startup method for my application, but this can be done in code at any time.  The next step is where we diverge from XNA.  In an XNA application, you have a standard game loop that executes 30 times every second.  There are two methods that recursively call each other, Draw() and Update().  These two methods ping-pong between each other, constantly updating the data, and then rendering it on the screen.

In Silverlight, we don’t have this.  Silverlight is event driven, and until an event fires, there’s not a very efficient mechanism for us to be checking for gestures.  Enter Manipulation events.

Leveraging Manipulation Events with Gestures

If we wanted to do a ton of math, or create our own Silverlight gestures, the Manipulation events are exactly where we’d want to start.  But for standard gestures, like Pinch, Flick, Tap, DoubleTap, Hold, etc., there’s not a single reason for us to write the math (or code) to figure those out.

So, we’ve accessed the TouchPanel, and enabled the gestures we care about…now it’s time to start recognizing them. There is a ManipulationCompleted event that we can attach to any control, but for my purposes, I’m going to apply to my LayoutRoot control, so that no matter where the gesture takes place, I can capture it.

LayoutRoot.ManipulationCompleted += new EventHandler<ManipulationCompletedEventArgs>(LayoutRoot_ManipulationCompleted);

In the event handler that follows, I can just check the TouchPanel to see IF a gesture has happened, and use a switch statement to handle each case when one does.

void LayoutRoot_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
	while (TouchPanel.IsGestureAvailable)
	{
		GestureSample gesture = TouchPanel.ReadGesture();

		switch (gesture.GestureType)
		{
			case GestureType.Tap:
				GestureText.Text = "Tap";
				break;
			case GestureType.DoubleTap:
				GestureText.Text = "Double Tap";
				break;
			case GestureType.Hold:
				GestureText.Text = "Hold";
				break;
			case GestureType.Flick:
				GestureText.Text = "Flick";
				break;
			case GestureType.Pinch:
				GestureText.Text = "Pinch";
				break;
		}
	}
}

This trivial amount of code is all we need to enable gestures in our applications.  Of course, you might want to do something more significant than writing text to a TextBlock, but that’s for you to decide.  Now you know how to capture these events in a simple, straightforward manner.

Download the Code

This example uses the code shown above to write the name of the gesture recognized to a textbox on the page.  Feel free to use it as the basis for your next application, however.  In addition, don’t forget about the GestureListener available in the Silverlight Toolkit for Windows Phone.  I covered this control on Day #21.

download

31 Days of Windows Phone | Day #29: Animations

This post is Day #29 in a series called the 31 Days of Windows Phone.

Yesterday, I wrote about how to monetize your applications through advertising.  Today I’m going to show you how to add some movement and flair to your application by using animations.

That Awesome Door Open Animation

If you’ve ever opened an application in the emulator, you get this really nice “door open” animation that happens before your application loads.  I’m going to show you how to add that type of animation to your pages.  (It’s actually surprisingly simple.)

Get yourself a new project (use the Windows Phone Application template if you want to follow along), and add a rectangle to the Grid named ContentPanel.  Here’s what mine looks like:

rectanglescreenshot

For creating the animation, we’re going to do the rest of this work in Expression Blend 4.  To open your project in Blend, right click on it in Visual Studio 2010, and choose the “Open in Expression Blend” option.

openinexpressionblend

Once you’ve gotten your project open in Expression Blend, find the “Objects and Timeline” tab.  There is a little “+” symbol on this tab, and it’s for creating new animations, or “storyboards”.

objectsandtimeline

When you click that “+” symbol, you’ll get a dialog that looks like this.  Give your animation a name:

createstoryboard

You’ll get returned to your Objects and Timeline tab, but now there’s an actual timeline to the right of your page objects.  To see the timeline better, press the F6 key on your keyboard.  It will re-arrange the tabs in Expression, moving the Objects and Timeline tab to the entire bottom of the application.

For our “DoorOpen” animation, we’re going to be manipulating ALL of the content on our page.  Thankfully, due to the hierarchical nature of Silverlight, we just need to target the LayoutRoot element.  Click on LayoutRoot in the Objects and Timeline tab, and look for an egg-shaped icon above the Zero seconds line.

recordkeyframe

That icon indicates a Keyframe.  Keyframes are those pivotal times in your animation when something changes.  Silverlight is smart enough to be able to figure out the rest of the animation for you.  So, in our example, we’re going to define the beginning and ending of our animation, and Silverlight will take care of the rest.  Click the Keyframe button if you haven’t already.

The reason we create a Keyframe at Zero seconds is because we want a baseline.  We’re basically saying that our element is currently in the “starting” position, and we want you to record that data.  We have one other thing we need to change in our “starting” position, and that’s what the rotational center of our object should be.  By default, the center of rotation is the center of the object, but we want our animation to basically rotate from the left edge of the screen.

Making sure that LayoutRoot is selected, and that there is a little “egg” icon on Zero seconds, take a look at the Properties tab.  Inside the “Transform” category, there is another tab labeled Center of Rotation (it’s under the Projection section).  You should see that the X and Y values are both set to 0.5 (the middle of the element.)  We want to change our X value to 0, or the left edge of the element.

 properties

Next, head back to Object and Timeline.  Move the yellow line that indicates time about halfway between the 0 and 1.  As you move it, you’ll see the time change next to the Keyframe button.

This time, we’re going to modify the Projection.Rotation property.  Open that part of the Properties tab up (it was just to the left of the Center of Rotation), and change the Y value to 90.  This will have our content rotate 90 degrees to the left in a 3D rotation.

rotation

If you hit the “Play” button above the timeline, you should be able to see this animation happening now.  But we still have one more step to take before this animation will happen in our app.  We need to call it from code.  If you’d like to see the XAML that we have created by taking all of the above steps, here it is (I’ve included my entire MainPage.xaml so that you can see all of the modifications):

<phone:PhoneApplicationPage 
    x:Class="Day29_Animations.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"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">
	<phone:PhoneApplicationPage.Resources>
		
		<Storyboard x:Name="DoorOpen">
			<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)" Storyboard.TargetName="LayoutRoot" d:IsOptimized="True"/>
			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="LayoutRoot">
				<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
			</DoubleAnimationUsingKeyFrames>
			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="LayoutRoot">
				<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="90"/>
			</DoubleAnimationUsingKeyFrames>
		</Storyboard>
		
	</phone:PhoneApplicationPage.Resources>

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
    	<Grid.Projection>
    		<PlaneProjection/>
    	</Grid.Projection>
        <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="BLANKENSOFT" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="animations" 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">
	<Rectangle Height="326" HorizontalAlignment="Left" Margin="83,100,0,0" Name="rectangle1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="289" Fill="Red" />
        </Grid>
    </Grid>
</phone:PhoneApplicationPage>

Calling Animations From Code

Once we’ve created our animation, we can save everything, and close Expression Blend.  Go back to Visual Studio 2010, and open the code-behind file: MainPage.xaml.cs.  We’re going to launch our animation when someone clicks on our rectangle (the one we added at the beginning, remember?)

Our first step is to create an event handler for the click of the rectangle, and the second is to execute the Begin() method on our storyboard.  Here’s what my MainPage.xaml.cs file looks like now:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

namespace Day29_Animations
{
	public partial class MainPage : PhoneApplicationPage
	{
		// Constructor
		public MainPage()
		{
			InitializeComponent();
			rectangle1.MouseLeftButtonDown +=new MouseButtonEventHandler(rectangle1_MouseLeftButtonDown);
		}

		private void rectangle1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
		{
			DoorOpen.Begin();
		}
	}
}

So that’s it!  Feel free to use this animation in your applications, so that you can have that same “open door” animation that you see all over the operating system.

Download the Code

This sample code includes all the code shown above in a full working project.  Please download it and take it apart, so that you can start using animations in your application.

download

31 Days of Windows Phone | Day #28: Advertising in Your Apps

This post is Day #28 in a series called the 31 Days of Windows Phone.

Yesterday, I wrote about how to get your application into the marketplace.  Today, I’m going to cover how to monetize your trial versions, or your free applications through the use of the advertising control.

Where Do I Get Started?

The place you’re going to want to get started is the Microsoft Advertising pubCenter.  They will walk you through getting the SDK, registering your application, and implementing the ads in your application.  But, because this is a series on development, I’m going to show you the implementation here, as well.

Adding the Ad Control To Your App

First, you need to GET the control.  If you completely skipped the link from my previous paragraph, you haven’t downloaded it.  You can get it here: 

http://www.microsoft.com/downloads/en/details.aspx?FamilyID=b0f00afc-9709-4cc2-ba2c-57728db6cbd6

Once you have added the .DLL to your project, you’ll be able to start adding ad controls to your app.  (If you need help getting this assembly into your project, there’s a walkthrough on Day #16: Panorama Control.

Once you’ve got the control available to your project, it’s as simple as any other control.  Here’s what it looks like on a XAML page:

<ad:AdControl AdUnitId="Image480_80" ApplicationId="test_client" />

As you can see above, there are two required values for an AdControl.  AdUnitId, and ApplicationId.  You get both of these values by registering your application in the Microsoft Advertising pubCenter, and creating a new Ad Unit. 

Using Test Values In Your AdControl

While we’re testing, we shouldn’t use our ACTUAL AdUnitId values, because that would be like illegally clicking on our banner ads on a web page.  The AdControl is smart enough to recognize when it’s running in the emulator, and won’t show ads in that case.  Instead, you should use the values in my example above.  There’s actually 3 different types of test values, depending on what size/shape of ads you want to show.  Here’s the whole list:

Ad Type Ad Model Size (W x H) Test ApplicationId Test AdUnitId
Text Ad Contextual 480 x 80 test_client TextAd
XXL Image Banner Contextual 480 x 80 test_client Image480_80
XL Image Banner Contextual 300 x 50 test_client Image300_50

For my purposes, as you saw above, I am using the 480 x 80 XXL Image Banner.  This will take up the bottom 80 pixels of my application’s screen, showing ads from my specific ad unit.

What Is An Ad Unit?

Ad Units are specific “campaigns” that you might want to run.  For example, I have an application called “Toothbrush Timer”.”  It’s meant to show kids how long to brush each region of their mouths.  Because I’m expecting parents to put it on the counter, and watch it with their kids as they brush, advertising seems like a perfect way to catch their eye.

The best part about the Ad Units is the ability to define Categories of advertisements to be shown.  In my example, I want to show ads that are relevant to parents and their children.  Thankfully, there are tons of different ad categories to choose from (there’s 385!), and you can even have multiple categories (up to 3) in one Ad Unit.  Here’s a look at the list:

Law, Gov’t & Politics – All Law, Gov’t & Politics – Commentary Law, Gov’t & Politics – Politics Law, Gov’t & Politics – U.S. Government Resources Law, Gov’t & Politics – Legal Issues Law, Gov’t & Politics – Immigration Shopping – All Shopping – Coupons Shopping – Contests & Freebies Shopping – Engines Shopping – Comparison Real Estate – All Real Estate – Buying/Selling Homes Real Estate – Architects Real Estate – Apartments Hobbies & Interests – All Hobbies & Interests – Woodworking Hobbies & Interests – Video & Computer Games Hobbies & Interests – Stamps & Coins Hobbies & Interests – Screenwriting Hobbies & Interests – Scrapbooking Hobbies & Interests – Sci-Fi & Fantasy Hobbies & Interests – Roleplaying Games Hobbies & Interests – Radio Hobbies & Interests – Photography Hobbies & Interests – Painting Hobbies & Interests – Needlework Hobbies & Interests – Home Recording Hobbies & Interests – Guitar Hobbies & Interests – Comic Books Hobbies & Interests – Collecting Hobbies & Interests – Cigars Hobbies & Interests – Chess Hobbies & Interests – Card Games Hobbies & Interests – Candle & Soap Making Hobbies & Interests – Boardgames/Puzzles Hobbies & Interests – Birdwatching Hobbies & Interests – Beadwork Hobbies & Interests – Arts & Crafts Hobbies & Interests – Art/Technology Hobbies & Interests – Magic & Illusion Hobbies & Interests – Jewelry Making Hobbies & Interests – Investors & Patents Hobbies & Interests – Getting Published Hobbies & Interests – Genealogy Hobbies & Interests – Freelance Writing Hobbies & Interests – Drawing/Sketching Travel – All Travel – South America Travel – National Parks Travel – Mexico & Central America Travel – Hotels Travel – Honeymoons/Getaways Travel – Greece Travel – France Travel – Africa Travel – Adventure Travel Travel – United Kingdom Travel – Traveling with Kids Travel – Theme Parks Travel – Spas Travel – Japan Travel – Italy Travel – Europe Travel – Eastern Europe Travel – Cruises Travel – Caribbean Travel – Canada Travel – Camping Travel – By US Locale Travel – Business Travel Travel – Budget Travel Travel – Bed & Breakfasts Travel – Australia & New Zealand Travel – Air Travel Food & Drink – All Food & Drink – Wine Food & Drink – Vegetarian Food & Drink – Vegan Food & Drink – Mexican Cuisine Food & Drink – Japanese Cuisine Food & Drink – Italian Cuisine Food & Drink – Health/Low Fat Cooking Food & Drink – French Cuisine Food & Drink – Food Allergies Food & Drink – Dining Out Food & Drink – Desserts & Baking Food & Drink – Cuisine Specific Food & Drink – Coffee/Tea Food & Drink – Cocktails/Beer Food & Drink – Chinese Cuisine Food & Drink – Cajuns/Creole Food & Drink – Barbecues & Grilling Food & Drink – American Cuisine Technology & Computing – All Technology & Computing – Windows Technology & Computing – Web Search Technology & Computing – Web Design/HTML Technology & Computing – Web Clip Art Technology & Computing – Visual Basic Technology & Computing – Unix Technology & Computing – Shareware/Freeware Technology & Computing – Entertainment Technology & Computing – Portable Technology & Computing – PC Support Technology & Computing – Palmtops/PDAs Technology & Computing – Network Security Technology & Computing – Net for Beginners Technology & Computing – Net Conferencing Technology & Computing – MP3/MIDI Technology & Computing – Mac Support Technology & Computing – Mac OS Technology & Computing – Linux Technology & Computing – Animation Technology & Computing – 3-D Graphics Technology & Computing – JavaScript Technology & Computing – Java Technology & Computing – Internet Technology Technology & Computing – Home Video/DVD Technology & Computing – Graphics Software Technology & Computing – Email Technology & Computing – Desktop Video Technology & Computing – Desktop Publishing Technology & Computing – Databases Technology & Computing – Data Centers Technology & Computing – Computer Reviews Technology & Computing – Computer Peripherals Technology & Computing – Computer Networking Technology & Computing – Computer Certification Technology & Computing – Cell Phones Technology & Computing – Camcorders Technology & Computing – Cameras Technology & Computing – C/C++ Technology & Computing – Antivirus Software Health & Fitness – ALL Health & Fitness – AIDS/HIV Health & Fitness – Women’s Health Health & Fitness – Weight Loss Health & Fitness – Thyroid Disease Health & Fitness – Substance Abuse Health & Fitness – Smoking Cessation Health & Fitness – Sleep Disorders Health & Fitness – Sexuality Health & Fitness – Senior Health Health & Fitness – Psychology/Psychiatry Health & Fitness – Physical Therapy Health & Fitness – Pediatrics Health & Fitness – Disorders Health & Fitness – Panic/Anxiety Health & Fitness – Orthopedics Health & Fitness – Nutrition Health & Fitness – Men’s Health Health & Fitness – Infertility Health & Fitness – Incontinence Health & Fitness – Incest/Abuse Support Health & Fitness – IBS/Crohn’s Disease Health & Fitness – Holistic Healing Health & Fitness – Herbs for Health Health & Fitness – Heart Disease Health & Fitness – Headaches/Migraines Health & Fitness – GERD/Acid Reflux Health & Fitness – Epilepsy Health & Fitness – Diabetes Health & Fitness – Dermatology Health & Fitness – Depression Health & Fitness – Dental Care Health & Fitness – Deafness Health & Fitness – Cold & Flu Health & Fitness – Chronic Pain Health & Fitness – Syndrome Health & Fitness – Chronic Fatigue Health & Fitness – Cholesterol Health & Fitness – Cancer Health & Fitness – Brain Tumor Health & Fitness – Bipolar Disorder Health & Fitness – Autism/PDD Health & Fitness – Asthma Health & Fitness – Arthritis Health & Fitness – Alternative Medicine Health & Fitness – Allergies Health & Fitness – A.D.D. Health & Fitness – Exercise Style & Fashion – All Health & Fitness – Clothing Health & Fitness – Jewelry Health & Fitness – Fashion Health & Fitness – Accessories Health & Fitness – Body Art Health & Fitness – Beauty Family Planning – All Family Planning – Eldercare Family Planning – Special Need Kids Family Planning – Pregnancy Family Planning – Parenting Teens Family Planning – Parenting-K-6 Kids Family Planning – Family Internet Family Planning – Daycare/Pre-School Family Planning – Babies & Toddlers Family Planning – Adoption Sports – All Sports – Football Sports – Fly Fishing Sports – Figure Skating Sports – Cricket Sports – Climbing Sports – Cheerleading Sports – Canoeing/Kayaking Sports – Boxing Sports – Bodybuilding Sports – Bicycling Sports – World Soccer Sports – Waterski/Wakeboarding Sports – Walking Sports – Volleyball Sports – Tennis Sports – Table Tennis/Ping Pong Sports – Swimming Sports – Surfing/Bodyboarding Sports – Snowboarding Sports – Skiing Sports – Skateboarding Sports – Scuba Diving Sports – Saltwater Fishing Sports – Sailing Sports – Running/Jogging Sports – Rugby Sports – Rodeo Sports – Pro Ice Hockey Sports – Pro Basketball Sports – Power & Motorcycles Sports – Paintball Sports – Olympics Sports – NASCAR Racing Sports – Mountain Biking Sports – Martial Arts Sports – Inline Skating Sports – Hunting/Shooting Sports – Horses Sports – Horse Racing Sports – Golf Sports – Game & Fish Sports – Freshwater Fishing Sports – Baseball Sports – Auto Racing Uncategorized – All Uncategorized – Blind/no site list Pets – All Pets – Veterinary Medicine Pets – Reptiles Pets – Large Animals Pets – Dogs Pets – Cats Pets – Birds Pets – Aquariums Careers – All Careers – Career Advice Careers – U.S. Military Careers – Telecommuting Careers – Scholarships Careers – Nursing Careers – Resume Writing/Advice Careers – Job Search Careers – Job Fairs Careers – Financial Aid Careers – College Careers – Career Planning Science – All Science – Weather Science – Botany Science – Geography Science – Space/Astronomy Science – Physics Science – Paranormal Phenomena Science – Geology Science – Chemistry Science – Biology Science – Astrology Business – All Business – Metals Business – Marketing Business – Logistics Business – Human Resources Business – Green Solutions Business – Government Business – Forestry Business – Construction Business – Business Software Business – Biotech/Biomedical Business – Agriculture Business – Advertising Society – All Society – Ethnic Specific Society – Weddings Society – Teens Society – Senior Living Society – Marriage Society – Gay Life Society – Divorce Support Society – Dating Home & Garden – All Home & Garden – Remodeling & Construction Home & Garden – Landscaping Home & Garden – Interior Decorating Home & Garden – Home Theater Home & Garden – Home Repair Home & Garden – Gardening Home & Garden – Environmental Safety Home & Garden – Entertaining Home & Garden – Appliances Automotive – All Automotive – Wagon Automotive – Vintage Cars Automotive – Trucks & Accessories Automotive – Sedan Automotive – Road Side Assistance Automotive – Pickup Automotive – Performance Vehicles Automotive – Off-Road Vehicles Automotive – Motorcycles Automotive – MiniVan Automotive – Luxury Automotive – Hybrid Automotive – Hatchback Automotive – Electric Vehicle Automotive – Diesel Automotive – Crossover Automotive – Coupe Automotive – Convertible Automotive – Certified Pre-Owned Automotive – Car Culture Automotive – Buying/Selling Cars Automotive – Auto Repair Automotive – Auto Parts Personal Finance – All Personal Finance – Tax Planning Personal Finance – Stocks Personal Finance – Retirement Planning Personal Finance – Options Personal Finance – Mutual Funds Personal Finance – Investing Personal Finance – Insurance Personal Finance – Hedge Fund Personal Finance – Financial Planning Personal Finance – Financial News Personal Finance – Credit/Debit & Loans Personal Finance – Beginning Investing Arts & Entertainment – All Arts & Entertainment – Television Arts & Entertainment – Music Arts & Entertainment – Movies Arts & Entertainment – Humor Arts & Entertainment – Fine Art Arts & Entertainment – Celebrity Fan/Gossip Arts & Entertainment – Books & Literature News – All News – Local News News – National News News – International News Religion & Spirituality – All Religion & Spirituality – Pagan/Wiccan Religion & Spirituality – Latter-Day Saints Religion & Spirituality – Judaism Religion & Spirituality – Islam Religion & Spirituality – Hinduism Religion & Spirituality – Christianity Religion & Spirituality – Catholicism Religion & Spirituality – Buddhism Religion & Spirituality – Atheism/Agnosticism Religion & Spirituality – Alternative Religions Education – All Education – Studying Business Education – Special Education Education – Private School Education – K-6 Educators Education – Homework/Study Tips Education – Homeschooling Education – Graduate School Education – Language Learning Education – English as a 2nd Language Education – Distance Learning Education – College Life Education – College Administration Education – Art History Education – Adult Education Education – 7-12 Education

So, once you’ve created some Ad Units in the pubCenter, grab those AdUnitId and ApplicationId values, and plug them into your AdControl.  Then your code, fully formatted, should look more like this:

<ad:AdControl x:Name="AdBox" AdUnitId="10018171" ApplicationId="350b8257-d92a-4978-a218-f3650bd485df" Margin="-12,528,-12,0" Width="480" Height="80" />

And here’s what the ad looks like in my application:

screenshot

 

Finally, Profit.

Just by adding this control to your application (assuming your application is actually downloaded by users), you should start seeing activity in the pubCenter.  It will show impressions, click-throughs, and other reporting metrics.  The most important number shows up right as you enter the site, though: revenue.

So get started showing ads in your application.  This is especially handy when you use ads in conjunction with the IsTrial mode that we talked about on Day #23.  Show ads before they’ve paid, and hide them afterwards.

Only 3 more days of this series to go…what’s been your favorite day so far?

Download the Code

This simple example just shows an AdControl on a XAML page.  But if you need to see how it’s done, this is definitely the example for you.

download

31 Days of Windows Phone | Day #27: Windows Phone Marketplace

This post is Day #27 in a series called the 31 Days of Windows Phone.

Yesterday, I shared with you a way to share your application with other Windows Phone developers.  Today is going to be a discussion about sharing your application with the world: through the marketplace.

There’s plenty to cover, so let’s get started.

1. Read the Documentation

Before doing anything else, you’re going to want to read the documentation about submitting your application to the Windows Phone Marketplace (also known as the App Hub.)

There are three documents you specifically should focus on:

  1. App Hub Developer Registration Walkthrough – a great introduction to getting registered as a developer.  You need to do this in order to submit applications to the marketplace, as well as deploy your applications to actual devices when you’re testing your app.
  2. Windows Phone 7 Application Submission Walkthrough – this walkthrough almost trumped the entire purpose of today’s article.  It walks you through each step of uploading your application, and what kinds of resources you’ll need along the way.  You’ll want to gather all of your resources (icons, descriptions, XAP, etc.) before starting the submission process.
  3. Windows Phone 7 Application Certification Requirements – a 27-page PDF that outlines what you can and can’t do in a Windows Phone application.  Most of it is pretty common sense, but it’s a quick read, so make sure your application qualifies before you even start building it.  You’ve got no reason to be upset if your application is denied for going against this document.

2. Know How Your App Will Be Tested

Each segment of the PDF above (Application Certification Requirements) is a test case for your application.  Hopefully, you’ve already read the entire document.  If you haven’t, go open it up.  This section outlines some of the “gotchas” you might encounter.

Test Case 4.5 – Windows Phone Marketplace Iconography
Avoid using the default Windows Mobile icons.  This is a new platform.  Treat it that way.

Test Case 4.6 – Application Screenshot
Screen shots should encompass the full 480  x 800 dimension, must be a direct capture of the phone screen or emulator and needs to represent the correct aspect ratio. DO NOT “enhance” your screenshots.  Show your application as-is.

Test Case 5.1.1 – Multiple Devices Support
Avoid controls and text “washing-out” by testing applications with the Theme Background set to “light”. We covered this on Day #5: System Theming.

Test Case 5.2.4 – Use of Back Button
Back button behavior is one of the most typical failures.  A common failure is pressing the back button during application runtime exits the application, instead of returning the application to a previous page or closing the presented menu or dialog.

Test Case 5.6 – Technical Support Information
Until 10/31/2010, it is recommended that applications include the version number or support information (for example a URL or email), which is easily discoverable by end-users.  Modify your applications now to help plan for 11/1/2010 when this test case will be enforced.

Test Case 6.2 – Push Notifications Application
There must be the ability for the user to disable toast notification.  Also, on first use of HttpNotificationChannel.BindtoShellToast method, the application must ask the user for explicit permission to receive a toast notification.

Test Case 6.3 – Applications Running Under a Locked Screen
This only applies to applications that continue to execute when running under the locked screen and does not apply to applications in a suspended state.   You MUST prompt the user for explicit permission to run under a locked screen upon first use of ApplicationIdleDetectionMode.

Some Other Tips Not Associated With A Specific Test

Including a Panorama background image is optional, but recommended. This will enable Microsoft to potentially feature your panorama image on the Marketplace catalog to help improve your application’s visibility with the likely result of more downloads.

Be sure that the application description and the text the application displays to end users is localized appropriately in the target language.

Be sure to use the RTM version of the Windows Phone Developer Tools as applications built on previous tool versions will fail testing.

3. Icons Are Probably the Most Important Thing

Here’s two quick screenshots from my Zune software.  You’ll notice that as I am browsing new applications for my phone, all I get is a name, an icon, and a price.  (Click it to see them enlarged).

zunesoftware

 marketplace2

Even though the apps are ordered by “top selling”, you might find a similar order if you sorted them by icon quality.  Your icon is that storied “first impression,” and if you don’t make a good one, you’re also not going to make a sale.

Take some time (or some money), and really make sure that your icon looks professional.  A bad icon brings up a host of other questions about your application:

  1. “If the icon is ugly, what does the application look like?”
  2. “If they didn’t care to make their icon look nice, how well could their application work?”
  3. “This icon looks like a child made it.  A child probably made the app too.”

As it turns out, the Expression team has put together a great tutorial on creating your own icons for the Marketplace.  Check it out here:

http://expression.microsoft.com/en-us/gg317447.aspx?ocid=msexp-fb

4. Build Yourself a Presence Outside the Marketplace

Sure, you’ve followed the rules, created a great icon, and gotten approved in the marketplace.  To make yourself look like a legitimate software company, you should put together a small website above and beyond what you’ve done for your application.  It should provide ways for your users to contact you, and should DEFINITELY let users know what other applications you’ve created as well.  Here’s my example site (though none of my applications have even been submitted to the marketplace yet):

http://blankensoft.com

You can put together just a simple page, but you should have a web presence.  You can get incredibly cheap hosting just about anywhere, and a domain name will run you about $10 a year.  (If you’re looking for hosting, I can’t recommend CrystalTechenough.  I’ve been hosting with them for almost 10 years now.)

If you’re looking for a place where you can get hosting and a domain name on the cheap, check out GoDaddy.com.  Your $10/year will get you email addresses, simple web hosting, and your domain name.

5. Look For Design Resources

There are tons of great websites that you can find fonts, icons, color schemes, etc. for your applications.  I’ve compiled a solid list of them here on this site, but look around.  The appearance of your application and icons is going to have a HUGE impact on your application’s success.  Here’s a link to my list of Windows Phone Developer Resources:

http://jeffblankenburg.com/wp7

 

Well, that’s it!  Get your application ready, and get it in the App Hub.  It’s time to start making money!

Tomorrow, I’m going to show you another way to make money, through ads on your application.  Until then, make sure you read those documents I linked to at the beginning of this article.

31 Days of Windows Phone | Day #26: Sharing Your App With Other Developers (For Free)

This post is Day #26 in a series called the 31 Days of Windows Phone.

Yesterday, I wrote about how you could easily consume data from an external web service.  Today, I’m going to talk about how you can share your app (especially as it’s being developed) with other Windows Phone developers.

What do you mean “share?”

If you’ve poked around at what was installed when you got the Windows Phone 7 Developer Tools, you might have noticed an interesting little program called “Application Deployment.”  What this application does is opens a XAP file, and deploys it to either the emulator or to an actual phone, if you have one.

startmenu

The reason I’m telling you about this is because it’s a great way to show someone what you’re working on, get their feedback, or just demonstrate specific functionality without sharing your screen.  The best part is…it’s free.  Think of it like a limited beta program of people you trust (this will be key later in this article.)

How is it free, exactly?

If you recall, downloading and installing the tools and SDK for Windows Phone is free.  It costs nothing.  You can go download the tools and SDK right here.  Using these tools, and the Application Deployment app that comes with it, you can build and share your applications with others who have done the same.

How does the app work?

It’s really about as simple as they come.  You open the app, choose a XAP file from your computer, and tell it to deploy, either to the emulator (still free), or to an actual device (if you have one.)  Here’s what it looks like:

applicationdeployment

Where is my XAP file located?

Once you’ve built and tested your application, you will find your application’s XAP file in the Debug/bin folder of your project.  Here’s a screenshot of one of my projects, for example:

xaplocation

Sure, you can share it, but be careful

Keep in mind that in order for someone else to run your application (without buying it from the marketplace, of course), is to give them the XAP file, and have them use this tool.  What this means, however, is that you are giving them the file that you will ultimately upload into the App Hub, and sell.  DON’T give this file to people you don’t trust.  You don’t want to find yourself in an argument about who created the application, and why you weren’t the one that submitted it to the marketplace.

This was a short article, but I think it’s an important thing to mention.  Being able to get your friends to test your application is a huge leap in making sure that your application will appeal to a broad audience, and that you’ve handled for the errors you might not have anticipated.

Tomorrow, we’re going to talk in depth about the marketplace specifically, what you need to do to get your app in there, and some of the pitfalls you might encounter along the way.  See you then!

31 Days of Windows Phone | Day #25: Talking To External APIs

This post is Day #25 in a series called the 31 Days of Windows Phone.

Yesterday, I wrote about embedding fonts, videos, and images into your Windows Phone application.  Today, we’re going to talk about retrieving data from a web service, and populating your application with it.

Introducing the Twitter API

If you haven’t played with this before, you’ll often hear me refer to a Twitter application as the new “Hello, world!”  The reason is simple:  nearly every application needs to connect to a web service anymore, and Twitter’s API is easy to use, available for free, and doesn’t even require registration.  In other words, there’s nearly no barrier to entry, and it’s a great way to learn a new technology.

The core of Twitter’s API can be found here: http://dev.twitter.com/

We’re specifically going to be looking at the user timeline elements of the API, leveraging this specific URL template:  http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=jeffblankenburg  where my username, jeffblankenburg, can be substituted with any Twitter username.

If you click on the URL I just provided you, you should see a pretty lengthy XML document.  This document contains the most recent messages I have posted to Twitter, with all of the wonderful metadata to go with them.  Here’s one node of that document:

<status>
  <created_at>Sun Oct 24 13:30:04 +0000 2010</created_at>
  <id>28594986565</id>
  <text>Day #24: Embedding Fonts in Windows Phone 7 http://bit.ly/wp7day24 #wp7 #wp7dev #31daysofwp7</text>
  <source>
    <a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>
  </source>
  <truncated>false</truncated>
  <favorited>false</favorited>
  <in_reply_to_status_id />
  <in_reply_to_user_id />
  <in_reply_to_screen_name />
  <retweet_count />
  <retweeted>false</retweeted>
  <user>
    <id>5688882</id>
    <name>Jeff Blankenburg</name>
    <screen_name>jeffblankenburg</screen_name>
    <location>Columbus, OH</location>
    <description>I'm a passionate technologist, husband, and father in Columbus, OH. I work for a small software company located in Redmond, WA. #wp7 http://blankensoft.com</description>
    <profile_image_url>http://a3.twimg.com/profile_images/396764567/jeffblankenburgheadshot_normal.jpg</profile_image_url>
    <url>http://www.jeffblankenburg.com</url>
    <protected>false</protected>
    <followers_count>1962</followers_count>
    <profile_background_color>131516</profile_background_color>
    <profile_text_color>333333</profile_text_color>
    <profile_link_color>994700</profile_link_color>
    <profile_sidebar_fill_color>cccccc</profile_sidebar_fill_color>
    <profile_sidebar_border_color>999999</profile_sidebar_border_color>
    <friends_count>652</friends_count>
    <created_at>Tue May 01 15:54:53 +0000 2007</created_at>
    <favourites_count>201</favourites_count>
    <utc_offset>-18000</utc_offset>
    <time_zone>Eastern Time (US & Canada)</time_zone>
    <profile_background_image_url>http://s.twimg.com/a/1287010001/images/themes/theme14/bg.gif</profile_background_image_url>
    <profile_background_tile>true</profile_background_tile>
    <profile_use_background_image>true</profile_use_background_image>
    <notifications>false</notifications>
    <geo_enabled>true</geo_enabled>
    <verified>false</verified>
    <following>true</following>
    <statuses_count>5664</statuses_count>
    <lang>en</lang>
    <contributors_enabled>false</contributors_enabled>
    <follow_request_sent>false</follow_request_sent>
    <listed_count>151</listed_count>
    <show_all_inline_media>false</show_all_inline_media>
  </user>
  <geo />
  <coordinates />
  <place />
  <contributors />
</status>

The important thing to remember about this content above is that it’s just XML.  Nothing fancy, nothing different.  Most web services available on the web provide an XML feed, and we can treat them all the same way, for the most part.

Getting XML Data From the Web to our App

It’s very simple (3 lines!) to get XML data from an online data feed to our application running on a phone.  One important thing to remember is that it’s up to you to check and see if the user even had a data connection.  There’s a simple way to do this, using the Microsoft.Phone.Net.NetworkInformation assembly:

if (NetworkInterface.GetIsNetworkAvailable())

Inside that for loop, we’re going to create a new WebClient object, and make an asynchronous call out to that Twitter API that I gave you the address before.  First, I create a new event handler for when our data retrieval is complete, and second I make that asynchronous call.  (In my example, you’ll see that I retrieve the username from a textbox that the user can type into.

if (NetworkInterface.GetIsNetworkAvailable())
{
    WebClient twitter = new WebClient();

    twitter.DownloadStringCompleted += new DownloadStringCompletedEventHandler(twitter_DownloadStringCompleted);
    twitter.DownloadStringAsync(new Uri("http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=" + TwitterNameBox.Text));
}

When the data returns, our event handler fires, and we need to do something with it.  Let’s take a look at that next.

Using XML in our Application

ONce we’ve got that data returned to our application, we want to actually display it on the screen.  In many of my other examples, I’ve shown how to databind a value to a XAML control.  We’re not going to focus on that in this post (though the code sample in the bottom certainly includes it), and instead, we’re going to look at parsing our XML data using LINQ.

To do this, we’ll need yet another namespace, System.Xml.Linq.  Once we’ve got this included, it’s a pretty simple process.  We need a new XElement object that holds our XML data.

XElement xmlTweets = XElement.Parse(e.Result);

Once our data is held in xmlTweets, all we have to do is bind it to our LIstBox, and use LINQ to create custom TwitterItem objects on the fly from the data.

TwitterList.ItemsSource = from tweet in xmlTweets.Descendants("status")
                            select new TwitterItem{
                                message = tweet.Element("text").Value
                            };

You’ll see in my code sample below that I have a custom TwitterItem class that has a “message” property. 

That’s it, though!  We’ve grabbed live data from an XML feed, processed it into our application, and displayed it in a ListBox.  For a full working example, check out the code below:

Download the Code

This is a fully working (but certainly not fully-featured) Twitter client.  You can type a username into a textbox, and the application will reach out to the Twitter API, grab the data, and then parse and display it in the application.

image

31 Days of Windows Phone | Day #24: Embedding Fonts

This post is Day #24 in a series called the 31 Days of Windows Phone.

Yesterday, I wrote about how you can add trial versions to your applications.  It’s an incredibly valuable feature that will ultimately help you sell more apps.  Today, we’re going to cover embedding fonts in our applications.

First, Be Smart

With all applications that are built for mobile devices, you have remember that data is not necessarily “free.”  Your user has a data plan that might only include 5GB of data transfer a month.  Secondly, there’s a limitation to how big an application can be and still be gotten over a data plan: 20MB.  If your application is larger than 20MB, your user will have to use Wi-Fi or sync with their computer.  Neither of those are optimal for selling tons of copies of your app.

Having said that, do not start filling your applications with every possible piece of data, fonts, images, videos, etc. that you “might” need.  Strip it down to its bare minimum, and if you can get that extra content over the air at a later time, think about doing it.

Embedding Fonts in Windows Phone 7

One of the most common questions I get asked about building WP7 apps is how to use a custom font that is not already included. Here’s a list of what IS included by default (Segoe WP) is what is used if you don’t specify a FontFamily:

 fontlist

To add another font to your application, it’s pretty simple, but not terribly obvious.  The first thing you need to do is find a font you want to use.  I recommend DaFont.com or 1001FreeFonts.com, but there are plenty of places that offer free, re-distributable fonts.

That’s an important key word, however.  REDISTRIBUTABLE.  Please make sure that you are only including fonts that are allowed to be redistributed.  In some cases, you might need to pay for these rights.  Make sure you’re covering yourself before you just start adding fonts to your application.

</soapbox>

OK, so now that we HAVE a font we can package up and distribute, here’s how we get it embedded in our application.  The first step is to add it to our project.  I generally like to create a “fonts” folder that I keep my fonts in, but it’s not required.  Here’s a screenshot of my Solution Explorer.

 solutionexplorer

The catchy part to using this file appropriately is the Build Action we assign to this file. If you’re not familiar with Build Actions, click on your font in Solution Explorer, and look at the Properties pane.

 propertiespane

There are two values we need to change manually, or we’ll never see any success with our font.  The first is the Build Action.  You want to change that to be “Content.”  The second is Copy To Output Directory.  That needs to be “Copy if newer.”  Now my properties look like this:

 propertiespanefinal

Now, to actually USE the font, right?  There’s some simple XAML syntax to make this happen on the FontFamily property.  Here’s what it looks like:

<TextBlock Text="12:02 AM" FontFamily="fonts/DigitalDream.ttf#Digital Dream" FontSize="60"/>

As you can see, I need to specify the font file itself, and following a pound sign/hash mark (#), the actual name of the font.  In my example, they’re the same.  If you want to be sure you’re right, open the font file on your computer, and you should see a window that looks like this:

font

The actual font name is listed right at the top.  You’ll know when you get the syntax right, because the font will immediately change on your design surface in Visual Studio 2010.

Download the Code

If you’d like to see a working example of embedded fonts, download this solution and open it up for yourself.  It’s amazingly simple, but also a great way to give your application a distinct look.

download

31 Days of Windows Phone | Day #23: Providing Trial Versions of Your App

This post is Day #23 in a series called the 31 Days of Windows Phone.

Yesterday, I wrote about how you could add your game to the Games hub on a Windows Phone.  Today, I’m going to show you how simple it is to set up your application to have Trial sections.  For example, let’s say you create a game that has 50 levels.  Perhaps you want the user to be able to play the first 5 levels for free, but to play the rest, they need to buy the game.  This article will show you how to do that.

Using the LicenseInformation Class

By adding the Microsoft.Phone.Marketplace assembly to our page, we have access to the LicenseInformation class, which is directly related to the “paid” status of our application.

using Microsoft.Phone.Marketplace;

Our next step is to actually use the LicenseInformation class, so let’s create an instance of it:

LicenseInformation li = new LicenseInformation();

Finally, LicenseInformation has a very nice Boolean property called IsTrial(), not surprisingly, that allows us to check if we’re in a Trial state or not.  You can use it in a simple if statement, like this:

if (!li.IsTrial())
{
	//Do something that only paid users can do.
}
else
{
	//Do something that all users, trial or paid, can do.
}

Testing Trial Mode

Unfortunately, there’s not a built-in mechanism to just swap between Trial and Paid states.  How I am handling this is pretty simple.  I’m using the same IF statement that you find in your App.xaml.cs file.  It checks to see if you’re debugging, and if you are, sets an IsolatedStorageSetting that I call “trialMode”.

Here’s the entire App() method, including the default code that is in our App.xaml.cs file.  In my example below, I am setting my trialMode variable to TRUE.  Turn this off when you want to test “paid” mode.

IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;

public App()
{
	// Global handler for uncaught exceptions. 
	UnhandledException += Application_UnhandledException;

	settings["trialMode"] = false;

	// Show graphics profiling information while debugging.
	if (System.Diagnostics.Debugger.IsAttached)
	{
		settings["trialMode"] = true;
				
		// Display the current frame rate counters.
		Application.Current.Host.Settings.EnableFrameRateCounter = true;

		// Show the areas of the app that are being redrawn in each frame.
		//Application.Current.Host.Settings.EnableRedrawRegions = true;

		// Enable non-production analysis visualization mode, 
		// which shows areas of a page that are being GPU accelerated with a colored overlay.
		//Application.Current.Host.Settings.EnableCacheVisualization = true;
	}

	// Standard Silverlight initialization
	InitializeComponent();

	// Phone-specific initialization
	InitializePhoneApplication();
}

Revisiting my code from earlier, I need to modify my IF statement to handle this new IsolatedStorageSettings value.  I am including my entire MainPage.xaml.cs file this time, so you can see everything in context.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Marketplace;
using System.IO.IsolatedStorage;

namespace Day23_UsingTrial
{
	public partial class MainPage : PhoneApplicationPage
	{
		LicenseInformation li = new LicenseInformation();
		IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
		
		// Constructor
		public MainPage()
		{
			InitializeComponent();

			if (!li.IsTrial()||(bool)settings["trialMode"] == false)
			{
				//Do something that only paid users can do.
			}
			else if (li.IsTrial() || (bool)settings["trialMode"] == true)
			{
				//Do something that all users, trial or paid, can do.
			}
		}
	}
}

That’s about all you need to do, though, and this is not necessarily the “best” way to handle this situation, but it’s been working for me.  If someone has a better way, I’d love to start using that instead.

Download the Code

To see all of this in a working example, download this solution file and play with it.  That’s always the best way to learn how stuff works.

download

31 Days of Windows Phone | Day #22: Apps vs. Games

This post is Day #22 in a series called the 31 Days of Windows Phone.

Yesterday, I posted an epic-length article on the Silverlight Toolkit for Windows Phone.  Today will be a bit shorter, but just as valuable.  We’re going to cover a subtle but important designation in your application’s settings:  the Genre.

If you have created a default Windows Phone application (or a default XNA application), and deployed it to the emulator, you’ve probably noticed that it resides in the primary list of applications. (The list you see when you tap on the arrow on the home screen.)

If you’ve used an actual WP7 device, however, you’ve probably noticed that all of the games show up in the Games hub.  There’s a very simple way to make this happen, though your application will seem to “disappear” in the emulator when you do this.  Keep in mind that you should ONLY do this if your application is ACTUALLY a game.  You might get denied from the App Hub if you aren’t honest about what your application is.

Remember Day #1?

On Day #1 of this series, I walked through each file of a default Silverlight application for Windows Phone.  To make this little switch, all we need to do is open the WMAppManifest.xml document.  Take a look at your Solution Explorer in Visual Studio 2010 to find it.  It’s in the Properties folder.

 solutionexplorer

Inside this file, you’ll find a bunch of metadata about your application.  Specific things like the name/path of your Application icons, application names, default page to load, etc.

As an aside, changing the DefaultTask’s NavigationPage property is a great way to speed up the manual testing of your UI.  Change the name of the page in that node, and your app will load on the new page instead.  Here’s an example:

<Tasks>
    <DefaultTask  Name ="_default" NavigationPage="ProductPage.xaml?id=42"/>
</Tasks>

OK, back to the task at hand…getting our application to reside in the Games hub instead of being treated like every other application on the phone.  To do this, we need to modify the Genre property of the App node of this document.  Here’s what it looks like by default (I’ve moved things around so that you can see the Genre value without scrolling):

<App xmlns="" Genre="apps.normal" ProductID="{8743bc4b-a909-4512-aab9-8633d93a5b04}" Title="Day22_AppsVsGames" RuntimeType="Silverlight" Version="1.0.0.0" Author="Jeff Blankenburg" Description="An amazing demo on how to change your app's location." Publisher="Blankensoft">

You can see that the default value for Genre is “apps.normal.”  Change that value to “apps.games” and you’ll notice that your application vanishes from the emulator.  (It’s not actually gone, you just don’t see the Games hub in the emulator.  Here’s my example, modified with this change:

<App xmlns="" Genre="apps.games" ProductID="{8743bc4b-a909-4512-aab9-8633d93a5b04}" Title="Day22_AppsVsGames" RuntimeType="Silverlight" Version="1.0.0.0" Author="Jeff Blankenburg" Description="An amazing demo on how to change your app's location." Publisher="Blankensoft">

If you get an opportunity to deploy your application to an actual device, however, you’ll find your game in the Games hub.  In the United States, that means you can try this as soon as November 8th.  If you’re in New Zealand, however, you can already acquire one.

In order to make this happen, however, make sure to also get registered in the App Hub.  Until you have a developer account there, you won’t be able to push your code to your own phone.

Download the Code

There’s really not much more to this sample code than I wrote about above, but you can download it nonetheless.  Enjoy!

download