Adding Code
This first Windows Phone application is not going to do much, but we should get started and make something happen with the phone. Since this is your first Windows Phone application, let's not pretend it is a desktop application but instead show off some of the touch capabilities.
First, if you look at the text of the XAML you should see that the first line of text shows the root element of the XAML to be a PhoneApplicationPage. This is the basic class from which each page you create will derive. The x:Class declaration is the name of the class that represents the class. If you open the code file, you will see this code was created for you.
<phone:PhoneApplicationPage x:Class="HelloWorldPhone.MainPage" ...
You will want to open the code file for the XAML file. You can do this by right-clicking the XAML page and picking View Code or you can simply press F7 to open the code file. The initial code file is pretty simple, but you should see what the basics are. The namespace and class name match the x:Class definition we see in the XAML. This is how the two files are related to each other. If you change one, you will need to change the other. You should also note that the base class for the MainPage class is the same as the root element of the XAML. They are all related to each other.
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 HelloWorldPhone { public partial class MainPage : PhoneApplicationPage { // Constructor public MainPage() { InitializeComponent(); } } }
These two files (the .xaml and the code files) are closely tied to each other. In fact, you can see that if you find an element in the XAML that has a name it will be available in the code file. If you switch back to the .xaml file, click on the TextBlock that you created in Blend. You will notice in the Properties window that it does not have a name (as shown in Figure 2.24).
Figure 2.24 Naming an element in the Properties window
If you click where it says "<no name>" you can enter a name. Name the TextBlock "theStatus". If you then switch over to the code file, you will be able to use that name as a member of the class:
... public partial class MainPage : PhoneApplicationPage { // Constructor public MainPage() { InitializeComponent(); theStatus.Text = "Hello from Code"; } } ...
At this point, if you run the application (pressing F5 will do this) you will see that this line of code is being executed as the theStatus TextBlock is changed to show the new text (as seen in Figure 2.25).
Figure 2.25 Running the application
There is an important fact you should derive from knowing that named elements in the XAML become part of the class: The job of the XAML is to build an object graph. The hierarchy of the XAML is just about creating the hierarchy of objects. At runtime, you can modify these objects in whatever way you want.
When you stop your application the emulator will continue to run. You can leave the emulator running across multiple invocations of your application. You should not close the emulator after debugging your application.
Working with Events
Since you are building a phone application, let's show how basic events work. You can wire up events just as easily using standard language (e.g., C#) semantics.2 For example, you could handle the MouseLeftButtonUp event on theStatus to run code when the text is tapped:
... public partial class MainPage : PhoneApplicationPage { // Constructor public MainPage() { InitializeComponent(); theStatus.Text = "Hello from Code"; theStatus.MouseLeftButtonUp += new MouseButtonEventHandler(theStatus_MouseLeftButtonUp); } void theStatus_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { theStatus.Text = "Status was Tapped"; } } ...
When you tap on theStatus the MouseLeftButtonUp event will be fired (which is what causes the code in the event handler to be called). All events work in this simple fashion, but the number and type of events in Silverlight for Windows Phone vary widely.
Debugging in the Emulator
If clicking the user interface was not working the way we would like, it might help if we could stop the operation during an event to see what was happening during execution. We can do this by debugging our operation. We can use the debugger to set breakpoints and break in code while using the emulator. Place the text cursor inside the event handler and press F9 to create a breakpoint. When you run the application (again, press F5) you can see that when you click on the theStatus TextBlock the debugger stops inside the event handler. You can hover your mouse over specific code elements (e.g., theStatus.Text) to see the value in a pop up (as shown in Figure 2.26).
Figure 2.26 Using the Visual Studio debugger
Pressing the F5 key while stopped at a breakpoint will cause the application to continue running. There are other ways to walk through the code, but for now that should be sufficient to get you started. Using the emulator is the most common way you will develop your applications, but there are some interactions that are difficult to do with the emulator (e.g., multitouch, using phone sensors, etc.) for which debugging directly on a device would be very useful. Luckily, debugging on the device is supported and works pretty easily.
Debugging with a Device
If you have a phone with which you want to do your development, you will want to be able to deploy and debug directly on the phone itself. First you need to connect your phone to your development machine. All communication with the phone is routed through the Zune software. By connecting your device to your computer, the Zune software should start automatically. If it does not start up, you can run it manually. Although the device will continue to operate normally when connected to Zune, several functions are disabled to allow Zune to synchronize media (music, photos, and videos) to the device. Consequently, these functions are using your media on the phone. Once connected, the device looks like it would normally (as seen in Figure 2.27).
Figure 2.27 Connected device
All the communication that you will do to your phone (e.g., debugging, deploying, and registration) is done while Zune is running. Once you've connected your phone to your computer and run Zune, you should be able to see the phone attached, as shown in Figure 2.28.
Figure 2.28 Your phone connected to the Zune software
Now that your device is connected, you can use it to sync your music, videos, and photos to the phone. However, before you can use a phone as a development device, you will need to register the phone for development. This lifts the requirements that applications be signed by Microsoft, and allows you to deploy your applications directly to the phone so that you can debug applications.
Before you can enable your phone as a developer phone, you will need to have an account at the Windows Phone developer portal (http://developer.windowsphone.com). Once you have done that, you can enable your phone to be used for development. To do this you will need the Windows Phone Developer Registration tool, which is installed when you install the Windows Phone SDK 7.1. When you run this application it will ask you for your Windows Live ID that you used to register with the developer portal, as shown in Figure 2.29.
Figure 2.29 Registering your device
If your phone is successfully attached to your computer, the Status area will tell you that it is ready to register your device for development. At this point, just click the Register button to register with the developer portal. Once it registers the phone, it changes the status to show you that the phone is ready (as shown in Figure 2.30).
Figure 2.30 Successfully registered developer phone
Now that you've registered your device, you can deploy and debug your applications using Visual Studio. The key to using the device instead of the emulator is to change the deployment using the drop-down list of deployment options. There are only two:
- Windows Phone Emulator
- Windows Phone Device
The drop down is located in the toolbar of Visual Studio, as shown in Figure 2.31.
Figure 2.31 Changing the deployment to use a development phone
Once you change the deployment target you can debug just like you did with the emulator. When you run the application, it will deploy your application to the device and run it so that you can debug it in the same way as you did with the emulator. Figure 2.32 shows the application running on a device.
Figure 2.32 Running on a device
Using Touch
Even though the touch interactions do fire mouse events, there are other events that allow you to design your application for touch. Since touch is so important to how applications on the phone work, this first application should give you a taste of that experience. To show touch working, let's add an ellipse to the application that the user can move around by dragging it with her finger. To get started, you should open the MainPage.xaml file and add a new ellipse in the center of the page. To do this find the TextBlock called theStatus and place a new Ellipse element after it, like so:
... <Grid x:Name="ContentGrid" Grid.Row="1"> <Rectangle Fill="#FF7E0505" Margin="8" RadiusY="24" RadiusX="24" /> <TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="Status" VerticalAlignment="Bottom" FontSize="48" FontWeight="Bold" Name="theStatus" /> <Ellipse x:Name="theEllipse" Fill="White" Width="200" Height="200"> </Ellipse> </Grid> ...
We want to be able to move the ellipse (named theEllipse) as the user drags it. To allow us to do this we will need to use something called a transform. In Silverlight, a transform is used to change the way an object is rendered without having to change properties of the ellipse. While we could change the margins and/or alignments to move it around the screen, using a transform is much simpler. You should use a TranslateTransform to allow this movement. A TranslateTransform provides X and Y properties, which specify where to draw the element (as a delta between where it originally exists and where you want it). You can specify this transform by setting the RenderTransform property with a TranslateTransform (naming it in the process):
... <Ellipse x:Name="theEllipse" Fill="White" Width="200" Height="200"> <Ellipse.RenderTransform> <TranslateTransform x:Name="theMover" /> </Ellipse.RenderTransform> </Ellipse> ...
Now that we have a way to move our ellipse around the page, let's look at dealing with touch. In Silverlight, there are two specific types of touch interactions that are meant to allow the user to change on-screen objects. These are when the user drags her finger on the screen and when she uses a pinch move to resize objects. These types of interactions are called manipulations. Silverlight has three events to allow you to use this touch information:
- ManipulationStarted
- ManipulationDelta
- ManipulationCompleted
These events let you get information about the manipulation as it happens. For example, let's handle the ManipulationDelta event to get information about when the user drags on the screen. This event is called as the manipulation happens, and it includes information about the difference between the start of the manipulation and the current state (e.g., how far the user has dragged her finger):
... public partial class MainPage : PhoneApplicationPage { // Constructor public MainPage() { InitializeComponent(); theStatus.Text = "Hello from Code"; theStatus.MouseLeftButtonUp += new MouseButtonEventHandler(theStatus_MouseLeftButtonUp); theEllipse.ManipulationDelta += new EventHandler<ManipulationDeltaEventArgs>( theEllipse_ManipulationDelta); } void theEllipse_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) { // As a manipulation is executed (drag or resize), this is called theMover.X = e.CumulativeManipulation.Translation.X; theMover.Y = e.CumulativeManipulation.Translation.Y; } ... } ...
The event is fired while the user either pinches or drags within the theEllipse element. In this case the code is only concerned with the dragging. In the event handler for ManipulationDelta, the ManipulationDeltaEventArgs object contains information about the extent of the manipulation. In the CumulativeManipulation property of the event args, there is a property called Translation, which contains the extent of the drag operation (the complete delta). We are just changing theMover's properties to match the manipulation. This means we can now drag the theEllipse element around and see it change position under our dragging, as seen in Figure 2.33.
Figure 2.33 Dragging the ellipse