IntroductionWelcome| 00:04 | Hi! I am Michael Lehman, and welcome
to Windows Phone SDK Essential Training.
| | 00:08 | In this course I'll be walking you through
app development and showing you how to make
| | 00:12 | the most of the Windows
Phone OS and Microsoft's toolkit.
| | 00:15 | We will start with the units converter
with algorithms for temperature and volume.
| | 00:19 | We will build an audio
recorder featuring a live VU meter.
| | 00:22 | That might be the basis for
your own billion-dollar idea.
| | 00:25 | and Finally, what mobile app course would be
complete without a monitor for Twitter feeds?
| | 00:29 | Ours features live title support and a
background agent to keep you up to date.
| | 00:33 | Along the way you'll see how to create compelling
user experiences using Metro Design Principles,
| | 00:39 | construct multipage navigation schemes, use the
built-in database engine, and access web-based
| | 00:44 | data in both active apps and background agents.
| | 00:47 | Windows phone is a unique and
exciting platform with unlimited potential.
| | 00:51 | So let's get started with
Windows Phone SDK Essential Training.
| | Collapse this transcript |
| What you need to know to take this course| 00:00 | In Windows Phone SDK Essential Training you
will learn about the capabilities of Windows
| | 00:04 | Phone and get the hands-on
experience making apps using the SDK.
| | 00:08 | The six apps we are going to build encompass
the techniques technologies and design elements
| | 00:13 | you need to know to build and debug using
Visual Studio, the Windows Phone Emulator,
| | 00:17 | and the Windows Phone handset. In a way
that will allow you to quickly internalize the
| | 00:22 | development cycle and learn how to accomplish
the kinds of things you already know like
| | 00:26 | page flow, file IO, and
network access the Windows Phone way.
| | 00:31 | How do you know you're ready to take this
course? Well, you are if you know how to use
| | 00:35 | Visual Studio, write code in C#, and
build simple user experiences in Silverlight.
| | 00:40 | Windows Phone has two distinct
programming models, Silverlight and XNA.
| | 00:45 | XNA is used primarily to develop game applications
while Silverlight is used for everything else.
| | 00:50 | We're going to focus on developing
Silverlight apps with a few selected XNA technologies
| | 00:56 | such as media recording and playback.
| | 00:58 | If you need a refresher on Visual Studio writing
code in C# or getting started with Silverlight,
| | 01:03 | lynda.com has essential
training courses for all three.
| | Collapse this transcript |
| Using the exercise files| 00:00 | If you are Premium Member of the lynda.com
online training library or if you're watching
| | 00:05 | this tutorial on the disk, you have access to
the exercise files used throughout this title.
| | 00:10 | Exercise file for this title are arranged
by chapter and within each chapter there is
| | 00:16 | a Start and an End stage for
each exercise arranged by movie.
| | 00:21 | Included in the exercise files are all the
sample code, the code snippets that we used,
| | 00:27 | and our Windows Phone SDK recipe sheet.
| | 00:30 | If you are monthly or annual subscriber to
lynda.com you don't have access to the full
| | 00:35 | exercise files, but there
are free exercise files.
| | 00:39 | You'll find some Microsoft style guidelines
and the document containing all the links
| | 00:43 | in the books, podcasts, and
other useful web sites chapter.
| | 00:47 | Let's get started.
| | Collapse this transcript |
|
|
1. Getting StartedDownloading and installing the Windows Phone tools| 00:00 | So let's get started
building Windows Phone apps.
| | 00:03 | First we have to install the tools.
| | 00:05 | If you've already worked your way through
Joe Marini's Windows Phone 7 First Look Course,
| | 00:09 | you can skip to the next chapter because we
will be covering the same ground here about
| | 00:13 | installing the development tools.
| | 00:15 | Building apps for Windows Phone 7 requires
installation of Visual Studio 2010 and the
| | 00:20 | Windows Phone Developer tools.
| | 00:22 | If you already have a Visual Studio Professional
or Ultimate, you just need to download the
| | 00:26 | tools and use the version you already have.
| | 00:29 | If you don't have Visual Studio, the
Developer tools include Visual Phone Developer Express
| | 00:34 | which is a free version
suitable for phone development in C#.
| | 00:37 | To get set up you go to the Microsoft Developer
Network or MSDN.Microsoft.com Windows Phone hub.
| | 00:44 | First we will review the system requirements,
including the hardware and software required
| | 00:47 | for the Windows Phone Emulator, downloading
and installing the tools, and installing the
| | 00:52 | Silverlight toolkit for Windows Phone.
| | 00:54 | The Windows Phone Developer tools
require either Windows Vista or Windows 7.
| | 00:59 | Windows XP is not supported.
| | 01:01 | One of the crucial things that you need to
know for Windows phone development is that
| | 01:04 | the Windows Phone Emulator requires a specific
base version of Microsoft DirectX and a special
| | 01:11 | Windows phone display driver in order to be able to use
the Emulator to develop your applications at full speed.
| | 01:19 | Most machines if they are 2009 and beyond
--and especially if you're running Windows 7--
| | 01:24 | have the appropriate hardware and drivers,
but that's something that you want to check
| | 01:28 | before you start developing. Because while
the Emulator will run without that particular
| | 01:32 | driver combination, it
will run much, much slower.
| | 01:36 | And if you're trying to do anything with
animation or video, it pretty much is unusable.
| | 01:41 | So make sure that you've got the
right video card and the right drivers.
| | 01:45 | Now we are going to switch over to looking
at the Microsoft Developer site and here's
| | 01:49 | where we go and get Developer tools.
| | 01:52 | We start out at the App Hub which has a big
button right here about downloading the free tools.
| | 01:56 | We will be coming back to the App Hub later
when we talk about how to submit your apps
| | 02:00 | to the marketplace and how
to register as a developer.
| | 02:02 | But for right now we'll just click Download the free tools,
and you can click right here to download the SDK.
| | 02:09 | One important thing to note is that the
operating system must be in the ENU or English United
| | 02:14 | States version unless you install one of the
localized versions of the Windows Phone SDK
| | 02:20 | for one of these other languages such as
English, Japanese, Chinese, and so forth.
| | 02:24 | You need 4 GB of free
disk space and 3 GB of RAM.
| | 02:29 | One very important thing is that again the Microsoft
Windows Phone Emulator is a virtual machine in itself.
| | 02:36 | So Windows Server is not supported and
virtual machines are not supported for development.
| | 02:42 | In addition, in some environments for some
applications, even using remote desktop to
| | 02:47 | connect to your machine for doing Windows Phone
development is an environment you don't want to use.
| | 02:52 | So pretty much if you're going to be doing
Windows Phone development you want to have
| | 02:56 | a dedicated machine that you're connected
up to with the dedicated display so that you
| | 03:01 | can get the full performance that you need.
| | 03:05 | Okay, once we've got the tools installed and
fired up and ready to go, in the next section we
| | 03:09 | will build the traditional Hello
World application for Windows Phone.
| | Collapse this transcript |
| Creating a Hello World application| 00:00 | Every programming journey traditionally begins
with a HelloWorld app to verify that the tools
| | 00:04 | are properly installed, and that you
can build and debug. So let's do it.
| | 00:08 | Here is a screenshot of the
app we are going to build.
| | 00:11 | We've got two labels right here Hello and
one that you can't see to display our result.
| | 00:15 | A text box in which the user is going to type
their name and a button which takes the value
| | 00:20 | from the text box, formats it, and
puts the result into the second label.
| | 00:24 | To start doing this let's launch Visual Studio.
| | 00:26 | Before we write any code, let's make a
couple of quick changes to Visual Studio settings
| | 00:30 | to make it easier to work with XAML files.
| | 00:33 | First we'll come up to the tools menu and
select Settings Expert Settings, and then
| | 00:37 | we'll come back to the tools menu and select
Options, scroll down here to the Text Editor,
| | 00:43 | select XAML, select Formatting, select Spacing,
and select Position each attribute on a separate
| | 00:49 | line and make sure the Position first
attribute on the same line as a start tag is selected,
| | 00:54 | and then we will click OK.
| | 00:56 | Now, to make a new project we come over here
and click on New Project, and the first thing
| | 01:00 | we see is the collection of
project templates for Windows Phone.
| | 01:04 | For our HelloWorld app, we are going to
select Windows Phone Application template from the
| | 01:08 | Silverlight for Windows Phone section under
Visual C#, and we'll call it HelloWorld and click OK.
| | 01:17 | The next thing you see is the new
Windows Phone Application dialog.
| | 01:22 | This allows you to select which target Windows
Phone version your application is designed for.
| | 01:27 | Only if you have an existing Windows Phone
application in the marketplace, and you know
| | 01:30 | you have customers that have the original
Windows Phone OS should you ever change this.
| | 01:35 | Windows Phone OS 7.1--which was also code-
named Mango--is the Windows Phone operating system
| | 01:40 | that is primarily out there
in the marketplace right now.
| | 01:43 | So every time we come through this
dialog we are simply going to click OK.
| | 01:47 | Once the project opens, you'll see the designer here
in the left pane and the XAML here in the right pane.
| | 01:53 | In order to make it more properly
formatted for our course, we've done two things.
| | 01:58 | First we've taken the Solution Explorer and clicked
this little pushpin so that it automatically hides itself.
| | 02:04 | And then each time we do it we are going
to come over here and shrink down the visual
| | 02:08 | of the phone in the designer surface and
move this over here to the side so that we can
| | 02:13 | more easily see the XAML section because that's
where we are going to be doing most of our work.
| | 02:17 | In order to make it easier to work with the
XAML, we are going to click here in the XAML
| | 02:21 | side of the designer, come up to the Edit
menu, select Advanced and Format Document.
| | 02:26 | That makes each one of these attributes show
up on a separate line, and it makes it much
| | 02:29 | easier for us to see all of the
attributes for each item in the screen.
| | 02:34 | So the first thing we always do in
creating a new app for Windows Phone is to set the
| | 02:37 | ApplicationTitle and the PageTitle.
| | 02:40 | Microsoft has a collection of rules about
what should be capitalized, how to punctuate
| | 02:43 | sentences and then format on-screen text.
| | 02:45 | We have included the full set of the
rules as a downloadable free exercise file.
| | 02:51 | As we build our application, the first thing
we are going to do is set our ApplicationTitle
| | 02:55 | and the rules for that it
should be always uppercase.
| | 02:57 | So here we are going to enter HELLO WORLD,
and then we come to our PageTitle, which should
| | 03:02 | always be lowercase for every page
and here we are going to enter welcome.
| | 03:05 | And that's actually enough for
us to try our first iteration.
| | 03:09 | So let's press F5 and launch the
app in the Windows Phone Emulator.
| | 03:12 | The Windows Phone Emulator is a
separate virtual machine unto itself.
| | 03:16 | So sometimes you'll see it says
Windows Phone Emulator doing a full boot.
| | 03:21 | In this case, it just fires it up, shows the
little splash screen and here's our application.
| | 03:27 | Once the Emulator boots up, you can see
also that Visual Studio switches into its debug
| | 03:31 | configuration and your app
appears in the Emulator on the screen.
| | 03:34 | When the app launches you'll see the app name
and the page name and the small line of numbers
| | 03:39 | running down the right-hand
side of the simulated screen.
| | 03:42 | These are diagnostic information which
will only be displayed to you on your emulator
| | 03:45 | or device while debugging, including frame
rates and some other things regarding memory,
| | 03:50 | which will help you optimize your
application before you submit it to the marketplace.
| | 03:55 | To exit your app you can either click the
Back button or you can click the Stop button
| | 03:59 | in the Visual Studio Debug toolbar, over here.
| | 04:03 | Right now, we'll click the Back
button and Visual Studio will stop.
| | 04:08 | And now it's time to make our app
actually do something meaningful.
| | 04:12 | We need to add the app equivalent of
reading text and writing it back out.
| | 04:15 | You know, what every HelloWorld
application you've ever written has done.
| | 04:18 | Now, we are going to do this by adding some
more stuff to the XAML, but we are going to
| | 04:22 | be using the designer to do this.
| | 04:25 | Microsoft started building XAML as an XML
based layout language nearly 10 years ago
| | 04:29 | as a successor to Windows Forms, with the
goal of creating universal and adaptable layout
| | 04:34 | tool for enterprise applications,
as well as browser-based tablets.
| | 04:37 | This was a big goal which eventually created the
large and complex tool with many knobs and dials.
| | 04:44 | In this course we are going to stick with
the essentials and use the visual layout tools
| | 04:47 | provided by Visual Studio.
| | 04:49 | When you're ready to dig deeper into XAML,
you can take the Silverlight 3 Essentials
| | 04:53 | Course and the Silverlight 4
What's New Courses here on lynda.com.
| | 04:58 | So the way we do that is we are going to
drag things from the Toolbox into our designer,
| | 05:02 | and we go on and open the Toolbox, and we
see, the Toolbox is overlaying our entire
| | 05:06 | designer, so we need to come back here and
move this divider a little bit to the right
| | 05:10 | so that the design surface is available to us.
| | 05:13 | And the first thing we are going to do is
we are going to drag a TextBlock which is
| | 05:17 | XAML's name for a static
label onto the design surface.
| | 05:20 | Now you can see we can only see a small
portion of the design surface, but that doesn't make
| | 05:23 | any difference, because no matter where
you drag things from the toolbar, it's simply
| | 05:27 | going to drop them where you let them down, and then
you use the mouse to position it where you want it.
| | 05:33 | Now you can see here that there are some
orange gridlines to show you essentially where is
| | 05:38 | the right spot to put your content.
| | 05:41 | You can't put your content all the way to
the edge of the screen, because there's a
| | 05:44 | minimum size area where
it detect finger touches.
| | 05:48 | And we are also going to zoom the designer a little
bit bigger so that we can see exactly what we are doing.
| | 05:53 | So now we are going to take this TextBlock
and make it the entire width of the screen.
| | 05:57 | And then we are going to come back over here to
the XAML side and adjust some of the properties.
| | 06:01 | In this particular case, we are going to
adjust the Text attribute, which is what controls
| | 06:06 | what text is being shown in there, and we
are going to put in Hello, what's your name?
| | 06:11 | And then we are going to add a TextBox where
your user can type in their name into the app.
| | 06:16 | So we are going to grab a TextBox, again
doesn't matter where we drop it, because the first
| | 06:20 | thing we are going to do
is put it where we want it.
| | 06:23 | Follow those design grids again here, and
you can see it automatically spreads to go
| | 06:27 | the entire width of the screen.
| | 06:28 | We are going to come down here on the XAML
side and edit the text attribute again of
| | 06:33 | the textbox here and make that empty,
because you don't want to prompt the user asking if
| | 06:38 | their name is TextBox.
| | 06:40 | Then we are going to add another TextBlock
which is where we are going to put our output,
| | 06:44 | the equivalent of our
console in the HelloWorld arena.
| | 06:47 | And again one more time come down here, set
the Text attribute to empty, and finally we
| | 06:53 | are going to drag a button, and position
that roughly in the middle of the screen.
| | 06:59 | And for buttons the caption in a button is
in the Content attribute and so here, in this
| | 07:05 | Content attribute we are
going to say, Say Hello.
| | 07:08 | Now, we've got all of the controls we need on
the screen, so now we need to write a little
| | 07:12 | code in order to make the
app actually do something.
| | 07:14 | So the easiest way to do that is to double-click on
the button in order to be able to enter the code behind.
| | 07:20 | So you will see the Visual Studio automatically
created a clickHandler, which is invoked when
| | 07:24 | the user taps your button.
| | 07:26 | So here we are going to enter textBlock2
which is the second label we put on the screen and
| | 07:32 | set this Text attribute to textBox1 which
is the place where we typed in the name and
| | 07:38 | its Text attribute, and we are going to put
a string Greetings at the front of it, and
| | 07:44 | we are going to put an exclamation point just to
be friendly at the end, and now we are ready to go.
| | 07:49 | So we are going to press F5.
| | 07:51 | When your app starts we are going to click
in the textbox and enter your name, and you
| | 07:56 | can see when you click here the software input
panel or touch keyboard shows up on the screen.
| | 08:01 | Now you can use this just like you would on
a real device and tap out your name, and that
| | 08:06 | can sometimes, especially if you're entering
in user IDs and passwords and things as your
| | 08:10 | debugging get somewhat time-consuming.
| | 08:12 | So there's a feature in Emulator that allows
you to use your hardware keyboard that's attached
| | 08:17 | to your development system, but there's a
couple caveats with that. The way you do that
| | 08:22 | is you press the Page Up key, and that engages
the hardware keyboard to work with the Emulator,
| | 08:26 | and you can see up here it shows that we
have an English United States keyboard attached.
| | 08:31 | That can make it a little bit difficult
to enter in letters with diacritical marks.
| | 08:34 | So there's a trade-off between using the
keyboard especially if you're dealing with foreign
| | 08:38 | language debugging and
using the software input panel.
| | 08:41 | But for most text that you have to enter,
the hardware keyboard is much more convenient.
| | 08:44 | Now in order to turn the hardware keyboard
off you press the Page Down key, and we could
| | 08:48 | click here and continue to start
entering things with our software keyboard.
| | 08:52 | In this case with touch Page Up, and I will
finish typing in my name, and now I am gong
| | 08:57 | to click the Say Hello button, and you can
see there we've taken the text from this text
| | 09:01 | box, combined it with our format strings,
and put it there into our second TextBlock
| | 09:07 | making our app do HelloWorld.
| | 09:08 | So now we have a clear example of being
able to get information in, run some code, and
| | 09:14 | get some information out. And that's it.
| | 09:16 | You've built and run your
first Windows Phone app.
| | 09:19 | Our next step is to see how this app
runs on actual Windows Phone device.
| | 09:23 | So we are going to then install the Zune
software so we can connect up to a hardware device
| | 09:27 | and see the same HelloWorld
application running on an actual device.
| | Collapse this transcript |
| Installing the Zune software| 00:00 | The Windows Phone developer tools are
sufficient for building apps and testing them in the
| | 00:04 | Windows Phone Emulator.
| | 00:06 | There are many good reasons why even though
this is very useful, it's not enough to complete
| | 00:10 | an app that's destined for the marketplace.
| | 00:12 | Before you ship you should--if at all
possible--test on an actual Windows Phone device.
| | 00:17 | For that you'll need to install the Zune software,
because it contains the drivers and associated
| | 00:22 | modules necessary for tethered debugging
and register your phone with Microsoft.
| | 00:27 | You also need to create a Live ID if you don't
already have one, and you need to be a registered
| | 00:32 | developer with Microsoft
before you can unlock the device.
| | 00:35 | To install the Zune software, go to zune.net
and click on the Download page and click on
| | 00:40 | this Download now button.
| | 00:42 | You don't have to sign up for the Zune
service in order to be able to use the Zune software
| | 00:47 | for developing Windows Phone.
| | 00:49 | Detailed instructions on how to register your
phone for development are found on this MSDN
| | 00:54 | page, you can search for
Register Your Phone for Development.
| | 00:58 | The way you do this is you come down to
the Start menu come down to the Windows Phone
| | 01:03 | SDK 7.1 section and click on the Windows
Phone Developer Registration which brings up this app.
| | 01:09 | In which case you can enter in the Windows Live
ID and password that you used to connect your phone.
| | 01:15 | As you can see here on this system we don't
have the Zune software running, you have to
| | 01:19 | have the Zune software running
before you can register your phone.
| | 01:22 | Well, the next step is to actually connect our
device to our development system--I recommend
| | 01:27 | using the USB cable that came with your device,
because not all micro USB cables are the same--
| | 01:32 | and that's the one you'll be able to know that
it's actually design to work with your device.
| | 01:36 | So the way we verify this connection is by
starting Zune, and we'll need to click the
| | 01:41 | SIGN IN button, I've already preconfigured
this one to sign in with my Live ID--this
| | 01:45 | is associated with my Nokia Lumia 900 phone--
and now we plug the USB cable into the phone.
| | 01:52 | The first time you do this you'll probably
see a little pop-up that says installing driver
| | 01:56 | software. And then once the phone is
connected you'll see it'll have a phone menu up here
| | 02:01 | at the top, and there will be something done
here that says, let me see the sync status.
| | 02:06 | Now, you can here on this particular phone
it says SYNC RELATIONSHIP: Guest. That's all
| | 02:10 | the Sync Relationship that's necessary to connect
up your Windows Phone device to your development system.
| | 02:16 | Your development system does not have to be
the primary synchronization partner for your
| | 02:20 | device, if that's not where your music and
your pictures and your movies are located.
| | 02:25 | But now we know we've got this connected let's go back
to Visual Studio and setup for debugging on the device.
| | 02:32 | And up here in the top toolbar where it says
Windows Phone Emulator, we can now drop this
| | 02:36 | down and select Windows Phone Device.
| | 02:39 | And you need to make sure when you do this
that you have the Zune software running and
| | 02:43 | your device plugged in.
| | 02:45 | And now when we press F5 or click on this
green button, Visual Studio is going to go
| | 02:49 | into debug mode, it's going to download the
application to the phone, and you'll interact
| | 02:54 | with Visual Studio in the same way that
you did before, but the interaction with your
| | 02:58 | application will actually
be on the device itself.
| | 03:00 | You see it's connecting to the
Windows Phone Device, launching the UI task.
| | 03:04 | Now Visual Studio is in debug mode and in a second
you'll see the app actually running on the device.
| | 03:10 | All right, well we've now got all
the development software installed.
| | 03:14 | Let's move on to building some apps that
will be ready to submit to the marketplace.
| | Collapse this transcript |
|
|
2. Navigating the Windows Phone EnvironmentExploring device capabilities| 00:00 | So now let's take a look at some of the capabilities
that only exist on the Phone and not in the Emulator.
| | 00:06 | First of all, there is the Phone, which is
obviously the one main functions of your device
| | 00:11 | shows the list of the history of the calls
you've made, and if we bring up the application
| | 00:15 | bar shows how you access your voicemail,
how you get a dialing keypad and shows how you
| | 00:21 | get access to the people hub.
| | 00:22 | This is one of the unique integration
features that only works on the phone.
| | 00:27 | The people hub is a place where all of your
contact information is kept where your friends'
| | 00:32 | Twitter handles are stored, how
you access Facebook information.
| | 00:38 | So you have access to that information from
inside the phone in order to get phone numbers,
| | 00:42 | and you can use the search feature, you can
also as you see delete your history and update
| | 00:48 | your call settings.
| | 00:50 | Now we'll go back to the main screen, and
you can see we can go into the people hub
| | 00:53 | if you click right here and then there
we'll see a list of all of your friends, and if
| | 00:58 | you swipe to the right, you be able to see
all of the Facebook status updates and twitter
| | 01:03 | status updates depending on how you have
your device configured if you have it connected
| | 01:07 | up to your Twitter account
and your Facebook account.
| | 01:09 | Next, we'll see the messaging application
this is where users can see and send text
| | 01:15 | messages as well as online chat.
| | 01:17 | There is also the mail application which
can connect up to Hotmail, Google, Pop3 mail,
| | 01:24 | your corporate exchange server, and it shows
all of the integrated email from all of your
| | 01:30 | inboxes or information from
just one particular inbox.
| | 01:35 | One of the things that interesting about
that is that from within your applications you
| | 01:39 | can invoke the mail composer so that users
can send mail, and you'll see that when we
| | 01:44 | get to the sample applications on the About
page there is button that says send a suggestion,
| | 01:50 | and you'll see the code necessary to launch
the mail composer so that the user can send
| | 01:55 | you a message making a suggestion for our app.
We've already seen Internet Explorer.
| | 02:00 | If we scroll up here, we can see the
integrated calendar, the Pictures hub.
| | 02:05 | The Pictures hub not only has the pictures
that are on your camera roll, but also has
| | 02:10 | all the pictures from your people hub so that
you'll be able to see the pictures from your
| | 02:14 | friends in Facebook pages and
the things they post on Twitter.
| | 02:18 | By default on the home screen you'll also see
live Music+Videos hub, a link to the Marketplace,
| | 02:24 | and you also see the Me tile, which allows
you to look at our own profile check into
| | 02:29 | Facebook, set your chat status, you swipe
over to the notification, you be able to see
| | 02:33 | any notification that have come in from other apps,
and you can also see the Twitter feeds or
| | 02:39 | Facebook feeds and see what's new from your friends.
All the ones that were directed directly to you.
| | 02:45 | All right, now that you've seen the full picture of
the Windows Phone environment in action, let's
| | 02:50 | pull back the curtain and see the structural
elements that are inside every one of these
| | 02:54 | Windows Phone apps, including the
ones they we are about to build.
| | Collapse this transcript |
| Understanding the Emulator| 00:00 | For all of the sample apps we're going to
build, we're going to use the Windows Phone Emulator.
| | 00:04 | This is part of the
Windows Phone Developer toolkit.
| | 00:08 | So let's take a little tour of the
Emulator and see what facilities we have available
| | 00:12 | to use in debugging our applications.
| | 00:14 | First, you can notice that the only built-
in app is Internet Explorer, there's no mail,
| | 00:21 | there's no simulated phone, there's no text
messaging, there's no picture hub, there is
| | 00:25 | no people hub, it's just limited to developing
the kind of apps that essentially stand alone.
| | 00:31 | If the app that you want to build requires
any of those kind of features, you're going
| | 00:35 | to have to get a Windows Phone device and
do your debugging directly on the device.
| | 00:39 | But the Emulator is really good, especially
when you want to test something really simple,
| | 00:43 | or you want to run in a completely
controlled environment that's free of any issues with
| | 00:49 | someone making a phone call to you or other kinds
of things which might interact with your application.
| | 00:55 | So we go and look at the applications list,
we see we have the Internet Explorer, and
| | 01:00 | we also have Settings.
| | 01:01 | Now, Settings is also quite limited. You can
simply change the theme, change the date and
| | 01:06 | time, decide which keyboard you want and
which language you want, and under application all
| | 01:11 | you have is background
tasks and Internet Explorer.
| | 01:15 | You can see that you have a way of looking
at background tasks so that you can decide
| | 01:19 | what's actually going on your phone.
| | 01:21 | Well, in this case, since we just fired up
the Emulator we don't have anything running.
| | 01:25 | Now, Windows Phones 7.5--a.k.a.
| | 01:28 | Mango--has a facility for multitasking.
| | 01:32 | And the way you see the apps that are currently
running is that you hold down the Back button,
| | 01:37 | and that shows you the apps you've got running.
| | 01:38 | So, for example, if we fire up Internet Explorer,
and then we go back to the homepage, and then
| | 01:45 | if we hold down the Back button, you're going
to see that we have three items, the homepage,
| | 01:50 | Internet Explorer, and Settings.
| | 01:54 | Additional features of the Emulator include:
the ability to rotate in all four directions,
| | 02:00 | either rotating left or rotating right, the
ability to click here to tell it to fit to
| | 02:05 | size, which shrinks the Emulator down to what
system thinks is a size that the entire image
| | 02:11 | comes on the screen.
| | 02:13 | You'll notice that before we could see the
entire Emulator, but the system thinks it's
| | 02:17 | a little bit smaller.
| | 02:18 | So you can manually adjust that by clicking
on this button here and change the size, for
| | 02:24 | example, to 66%, which is what we've been
using, and you can see you can fit all of it.
| | 02:28 | You could actually see the bottom and the top.
So you have a little bit of control over that.
| | 02:33 | The last three features of the Emulator are
accessed via this double chevron button here,
| | 02:38 | and they include a simulated Accelerometer, a
simulated GPS, and the ability to take screenshots.
| | 02:45 | So first, you can set the default Orientation
before you want to simulate Accelerometer
| | 02:52 | so that you can see, if I wanted Portrait
Standing up, or I want to have it Landscape,
| | 02:57 | or Laying Flat, and you see the Z axis when
we have Flat is -1, and the Y axis is -1 when
| | 03:06 | we're standing straight up.
| | 03:07 | You can adjust the tilt by simply grabbing
this little red dot here, and you can move
| | 03:13 | the Emulator as if you were holding the
actual phone in your hand, including doing shaking
| | 03:17 | operations or rotating around in a circle,
whatever your application actually needs.
| | 03:22 | And you can see down here, the X, Y, and Z
axis reports that your application will get back.
| | 03:28 | You can also use some prerecorded data, the
Emulator comes with prerecorded data for shaking,
| | 03:33 | so when we press Play, if your application
was looking for Accelerometer Events, those
| | 03:37 | numbers would have been fed into your application,
of course we can play it again, that way your
| | 03:42 | application can detect
essentially a shake event.
| | 03:45 | Then we can use the Location
simulator, which simulates the GPS.
| | 03:50 | You can either type in a particular
location in the Latitude/Longitude, or you can come
| | 03:56 | and tap on a place, here is one of my favorite
places in the world, it's called Useless Bay.
| | 04:01 | Finally, you have the ability to
capture and manipulate Screenshots.
| | 04:05 | So, for example, if we come back here to
our Settings page, and we look at the Internet
| | 04:12 | Explorer settings, they have lot
of controls there we could capture.
| | 04:16 | We now have a 480x800 pixel image.
| | 04:20 | Notice here it says you have the zoom level set
to 66%. If you want a better quality screenshot
| | 04:25 | you can set it to a 100%.
| | 04:26 | So we can actually come here, set this to 100
%, even though it doesn't fit on the screen,
| | 04:32 | and click Capture, and it will still capture
the entire image, but at a higher resolution.
| | 04:38 | And then you can click the Save button
to save it to a file on your file system.
| | 04:43 | And that's the Windows Phone Emulator that
we're going to be using throughout the course
| | 04:47 | to test and debug and run
our sample applications.
| | 04:51 | So let's dig into what's in the SDK
and then start building our first apps.
| | Collapse this transcript |
|
|
3. FoundationUnderstanding the SDK| 00:00 | As we get ready to dig in and write real
applications let's take a quick overview of the Windows
| | 00:06 | Phone environment from a code perspective.
| | 00:08 | We'll look a little bit at the
foundations that are provided by the SDK.
| | 00:13 | We'll look at some of the built-in
features from a code point of view.
| | 00:17 | We'll look at the options for
persistence for saving data on the device and off.
| | 00:21 | We'll look at some of the sensors that you can use to
create a multidimensional application for your users.
| | 00:27 | And we'll look at some of the latest
enhanced user experience features of Windows Phone.
| | 00:32 | First, every Windows Phone app has three
fundamental pieces: an application class which is what
| | 00:39 | the operating system actually starts up when
your app is launched, one or more pages where
| | 00:44 | the content of your app goes, and an optional
application bar as we saw when we were looking
| | 00:49 | at the device that allows you to have
icons and some additional menu items.
| | 00:54 | This diagram which came from Microsoft's Developer
Network shows the relationship of these things.
| | 01:00 | You'll see the Frame is the entire screen, the
Page is the piece where your content actually
| | 01:06 | goes, and the Content Area which is
inside that page is where your controls live.
| | 01:12 | The Frame contains the page and other elements
such as the system tray at the top which shows
| | 01:18 | your wireless connectivity and whether
you're connected by Wi-Fi and your battery status.
| | 01:23 | Of course, as we saw, the application bar
can contain up to four iconic menu items plus
| | 01:29 | up to five textual menu items.
| | 01:32 | Now let's move from the abstract to the concrete
by looking at the implementation of the Units
| | 01:37 | Converter app we're
going to be building shortly.
| | 01:39 | First, if we look at the Emulator, you can
see it doesn't quite fit the entire screen.
| | 01:44 | Even though we click the Fit to Screen,
sometimes you have to come down and select an absolute
| | 01:49 | size yourself to make it as
large as it can fit onto your screen.
| | 01:53 | So the text that's being rendered is as crisp
as possible so that you can see all the pixels.
| | 01:59 | In our application here,
| | 02:01 | The stuff that's inside this black box
that I'm showing with the mouse is the frame.
| | 02:06 | You've got your system tray up here
which doesn't show on the Emulator.
| | 02:09 | You've got your application bar down here.
| | 02:12 | And the page is everything that's sitting
inside here, which in this particular case
| | 02:16 | consists of our two text blocks for our
labels and our two text boxes for our application.
| | 02:23 | This application is built with two pages,
the conversion page we see here, and if we
| | 02:29 | click on the application bar to bring up the
menu, we'll see a caption underneath the icon,
| | 02:34 | and we can click the about menu item and
see the second page of our application.
| | 02:40 | In addition to the application class, and
whatever individual pages you have and the
| | 02:44 | application bar, you can build applications that
have multi-page controls such as the pivot or panorama.
| | 02:52 | You can see an example of the pivot control in the
Sonnets app which we're going to see in just a moment.
| | 02:58 | You can see an example of the panorama
control in the People Hub on your phone.
| | 03:04 | In addition, there's two kinds of message
boxes which you can use to interact with your
| | 03:08 | users, one that comes with the Silverlight
built-in API that allows you to have a message
| | 03:14 | and one or two buttons but the buttons will
have to be labeled OK or Cancel, and another
| | 03:19 | when that comes in the XNA GamerServices in
which case you can not only specify the message,
| | 03:25 | you can specify for the two buttons and
whether you want to have a sound played or not.
| | 03:30 | So let's take a look at these in the concrete.
| | 03:33 | In the Sonnets Plus application which we're
going to be building, we use the pivot control
| | 03:37 | to show two different views of the same list.
| | 03:40 | Here we have all 154 of Shakespeare's sonnets,
and here we have a list of the ones that we
| | 03:46 | think are our favorites.
Right now, that list is empty.
| | 03:50 | We'll select one of the sonnets, click
on the icon to say make that a favorite.
| | 03:54 | You can see how a little
gold star shows up there.
| | 03:56 | And when we go back to the list now of
favorites, there's our sonnet that we've chosen.
| | 04:04 | To demonstrate the two kinds of message boxes,
we're going to look at the Take-a-Note application
| | 04:09 | which we're going to be building in this course.
| | 04:12 | If you attempt, for example, to try to play
something before you've recorded anything,
| | 04:17 | we use the Silverlight MessageBox that simply says
No Sound Has Been Recorded Yet and has an ok button.
| | 04:23 | As I mentioned, this particular kind of MessageBox
can only have an OK or an OK and Cancel button.
| | 04:29 | If we record something, like this, and you
can see, the recording is happening, we've
| | 04:34 | got the time elapsing here in our little
meter bar, it plays back like this, and you can
| | 04:42 | see the recording is happening, we've got --
and then if we come to our list of recordings,
| | 04:47 | and we click on one of them and attempt to
delete it, you see we use the GamerServices
| | 04:54 | message box in which we're able to use yes and no
as our captions, add a title, and add the sound.
| | 05:01 | As a final step in our exploration of foundations
let's build an empty sample application and
| | 05:07 | look at the code in the code behind for the
App.xaml that Microsoft provides where you'll
| | 05:13 | find methods that you're going to interact
with as you flesh out your application from
| | 05:18 | a sample into an actual app so that you can
handle things like interruptions by the user
| | 05:23 | getting a phone call.
| | 05:25 | So we'll just pick Windows Phone Application
template, once again, go through this dialog box.
| | 05:32 | In this case, we're not actually
going to look at the XAML there.
| | 05:34 | We're going to look at the App.xaml.
| | 05:36 | If we look at the XAML for App.xaml, it's
simply standardized templating things that
| | 05:41 | Microsoft provides that says which
class the application launches with.
| | 05:47 | But what's more interesting is to look at
the C# behind that and take a look at what
| | 05:52 | methods are being provided that
control your application lifecycle.
| | 05:57 | First, there's this root frame--and this is
what gets filled in by that information in
| | 06:02 | the XAML that says which is the root frame
which page does your applications start with.
| | 06:08 | There's some standard code here which initializes
Silverlight, initializes the phone environment.
| | 06:14 | This is interesting here this section because
when you're debugging, these things get executed
| | 06:19 | which is different than when your user is
running your application outside of the debugger.
| | 06:23 | This line here is what controls that frame
rate counter we saw on the right-hand side
| | 06:27 | of the Emulator, the vertical set of numbers.
| | 06:30 | If you're running your app in the Emulator,
and you want to take screenshots, and you
| | 06:34 | don't want to have the frame rate
counter, you can comment this out.
| | 06:38 | In addition, this line right here disables
the idle time lock because normally when you
| | 06:44 | have your phone connected via the USB cable
to your development environment, you don't
| | 06:48 | want the screen-locking when
you're in the middle of debugging.
| | 06:52 | But again, if you're trying to test what
happens with your application when screen lock comes
| | 06:56 | on, for example, in the Take-a-Note application,
we wanted to make sure that we could record
| | 07:01 | when the screen locks, you want to comment
this out so that you can use your own control
| | 07:06 | over whether the screen gets
locked or not even if you are debugging.
| | 07:10 | If you want to have some code that runs when your
application begins even before, everything else gets done.
| | 07:16 | You put it in here in Application_Launching,
you can put here if you want code that happens
| | 07:22 | when your application gets restored from
being suspended such as after a phone call.
| | 07:28 | Here this is the code that happens when your
application gets the phone call in the first
| | 07:32 | place so that you can store your state.
| | 07:35 | And here is what happens when the user clicks
back that takes you out of your application
| | 07:40 | but not because your
application was interrupted.
| | 07:44 | The RootFrame_NavigationFailed message here
is included so that when you're developing
| | 07:49 | your application, if you attempt to navigate
to a page that you haven't written yet, instead
| | 07:54 | of crashing in a way that you can't figure
out where it is because this back stack is gone.
| | 07:59 | Again, here it says if the debugger is
attached meaning you're running in the Visual Studio
| | 08:03 | environment, it will stop so you can go look
at the stack trace and figure out which page
| | 08:08 | you actually wanted to go to,
and you haven't implement yet.
| | 08:11 | And again finally, another thing here to
handle unhandled exceptions, by default, if you're
| | 08:17 | running in the debugger, it will simply break into
the debugger so that you can see what's going on.
| | 08:22 | In a production environment, you might
want to put something in here to format up the
| | 08:27 | exception information and send it off to a
server for QA so that you can figure out when
| | 08:32 | application crashes happen and see
what's going on in your application.
| | 08:37 | Now we've seen the basic nuts and bolts
that are in every single Windows Phone 7 app.
| | 08:42 | You've got an application class, you've got
one or more pages, you're potentially going
| | 08:47 | to have multipage controls,
and an optional application bar.
| | Collapse this transcript |
|
|
4. Building a Units ConverterIntroducing the converter| 00:00 | All right! It's time to roll up our sleeves
and build our first app. The Units Converter.
| | 00:05 | In this movie, I'm going to show you how to
build a basic Windows Phone application, including
| | 00:10 | building the basic user experience, including
building the visual/UX using XAML, and adding
| | 00:16 | code-behind in order to
respond to user taps on the screen.
| | 00:20 | We're also going to be incorporating the application
bar with an icon and some menu items and also
| | 00:25 | getting into working with application
settings because the final version of the apps that
| | 00:29 | we build is going to include multiple kinds
of units conversion, and you want to be able
| | 00:34 | to select one of the kinds and have the application
remember so that the next time you enter the
| | 00:39 | app, it starts out with that
particular type of conversion.
| | 00:42 | According to Wikipedia, German physicist, Daniel
Fahrenheit invented his temperature scale in 1724.
| | 00:48 | It's used in the United States, Belize,
Puerto Rico, Guam, and the U.S. Virgin Islands.
| | 00:54 | But scientists and pretty much the rest of
the world use the scale developed by Swedish
| | 00:57 | astronomer Anders Celsius in 1742.
| | 01:01 | Converting between the two is done using some
simple formulas most of us learned in science
| | 01:04 | class at the same time we
were studying fractions.
| | 01:07 | You can see on the screen, you get Celsius
by taking Fahrenheit -32 and multiplying times
| | 01:12 | 5/9, and you get Fahrenheit from Celsius
by adding 32 and multiplying times 9/5.
| | 01:18 | So let's take a look at the
Units Converter in action.
| | 01:20 | I've done the icon for this app to the homepage,
so let's tap that and open up the Units Converter
| | 01:24 | and take a look at what it does.
| | 01:25 | It's a very simple app that takes a value in
one set of units and converts it to a value
| | 01:31 | in another set of units.
| | 01:32 | By default, it converts Fahrenheit temperatures
into Celsius temperatures, so we can tap on
| | 01:38 | Fahrenheit, put in 212 which is the
boiling point of water in Fahrenheit and see that
| | 01:42 | in fact that is 100 degrees Celsius.
| | 01:45 | We can tap on Celsius and put it in 0,
the freezing point of water and see that
| | 01:52 | in fact, it's 32 degrees Fahrenheit.
| | 01:57 | Look at the application bar, we'll see first
of all that the button we use for converting
| | 02:02 | is an icon that comes from the standard
library provided with the Windows Phone tools.
| | 02:08 | All of these icons are always monochromatic
because the system automatically converts
| | 02:12 | them to light or dark, depending on the theme
you selected, and you can have a short label
| | 02:17 | underneath each one.
| | 02:18 | In addition to that, as I mentioned in the
earlier chapters, the application bar not
| | 02:23 | only can have four of those kind of icons, it
also can have up to five textual menu items.
| | 02:27 | In the case of this particular app, we
have temperature which is our default, we have
| | 02:32 | tablespoons/teaspoons, and we have an About box.
| | 02:35 | The tablespoons/teaspoons came to me because
I have a friend who is a really great cook,
| | 02:40 | but I always made the better popcorn and she
could never figure out why. And it's just good.
| | 02:44 | I said I just follow the
recipe on the back of the bag.
| | 02:47 | It says put in three tablespoons of oil, and
at that particular time I only had a teaspoon.
| | 02:53 | This was way before you had a phone you can pull
out of your pocket to get this at a moment's notice.
| | 02:58 | I couldn't figure out how many teaspoons
to the tablespoons, so now I can always pull
| | 03:02 | out my trusty Windows Phone, put in the fact
that I want three tablespoons as it says on
| | 03:08 | the back of the bag, I know that 9
teaspoons will do it, and we'll get perfect popcorn.
| | 03:13 | And we'll look at the about page which
we've added to every app that we're building in
| | 03:16 | this course and see we've got some
copyright information, a button which brings up the
| | 03:22 | Mail Composer which we'll show later, a button
that takes you to a list of all the apps that
| | 03:27 | we have in the marketplace, and a
button which will bring it to this course.
| | 03:32 | So let's actually open
Visual Studio and build this app.
| | Collapse this transcript |
| Creating the user experience (UX)| 00:00 | All right! So let's get
started building the Units Converter.
| | 00:03 | First we open Visual Studio, and then we
select New Project. We're going to use the Windows
| | 00:08 | Phone Application template, and
we're going to call it UnitsConverter.
| | 00:13 | Before we get into actually building the code
let's look at what is in the solution by default
| | 00:19 | from the template, because there's a number
of pieces here as we start to build a real
| | 00:23 | app that you will want to know about, and
you will want to potentially change for every
| | 00:27 | app that you build.
| | 00:29 | First of all, if we open the Properties folder,
we can first see the AppManifest.xml, which
| | 00:34 | is a file that's holdover from
desktop and web applet Silverlight.
| | 00:39 | There's nothing in there that we need to change.
| | 00:41 | The AssemblyInfo.cs is the familiar file that
allows you to put in your copyright information
| | 00:47 | and your version information
and so forth for your assemblies.
| | 00:50 | And WMAppManifest is the one that has most
of the data in it that we care about as phone
| | 00:55 | developers, and let's take a look at that.
| | 00:58 | First let's make sure that in the tools Options we
have the formatting set up as we did for XAML for XML.
| | 01:05 | Go to Text Editor XML Formatting and make
sure Align attributes on a separate line is
| | 01:10 | set, and then we'll reformat this so that
we can more easily see all the attributes.
| | 01:15 | Edit > Advanced > Format Document.
| | 01:17 | All right. This particular XML file is used,
not only by the build system and the Phone
| | 01:23 | Emulator and the phone when you're building
and testing your app, it's also used as part
| | 01:28 | of the test for marketplace application and
the marketplace certification and the marketplace
| | 01:34 | information that shows up for your
app when your app is actually shipping.
| | 01:38 | If we look down through it,
first off we have the ProductID.
| | 01:41 | This is a GUID, which is a unique
identifier that identifies this particular app.
| | 01:47 | If you ever decide that you want to take an
app and clone it and start doing another app,
| | 01:52 | this is the one thing that you have to
change here, that ProductID so that the phone can
| | 01:56 | uniquely identify that
you have two different apps.
| | 01:59 | Now, you've got the Title of your app and the
RuntimeType Silverlight, don't ever change that.
| | 02:04 | There's Version number, which is the
version number that is shown in the marketplace.
| | 02:08 | You can put in your name here, some description
for your application, and the identification
| | 02:13 | for your Publisher here.
| | 02:15 | If we look back over the Solution Explorer,
we'll see that there's three PNG files.
| | 02:20 | ApplicationIcon.png is a 62x62 pixel image,
which is the icon that shows up in the application
| | 02:28 | list when you click the arrow on the right-hand
side of the home screen to see the applications.
| | 02:34 | Background.png is a 173x173 image, which is
the same image, but scaled up to go on the
| | 02:42 | home screen so that when you pin your App
icon to the home screen, it's large enough
| | 02:47 | to see at a glance.
| | 02:48 | And SplashScreenImage, you've seen it many
times as you've gone through and watched the
| | 02:52 | movie so far, it's that full screen picture
with a little iconic image of a clock on there.
| | 02:58 | That's the default that are
provided in the templates.
| | 03:01 | You can either follow the train of thought
that says this should look like the first
| | 03:05 | screen of your application, but without all
the controls active to sort of imply to the
| | 03:09 | user your application is booting up, or you
can also use this for branding your application,
| | 03:14 | have your company logo, have your app logo,
and so forth on that particular screen.
| | 03:19 | So in this IconPath element here, it specifies
which PNG is to be used for the application list.
| | 03:27 | The Capabilities list here is something that
by default the list you get from the templates
| | 03:32 | includes almost everything that you're
ever going to need for building an app.
| | 03:37 | Before you submit to the marketplace, you're
going to want to delete everything here that
| | 03:41 | you don't actually need.
| | 03:42 | So, for example, in our UnitsConverter app,
we'd most definitely delete the Location,
| | 03:47 | we'd delete the media library, we'd would
delete Microphone, capabilities our application
| | 03:51 | doesn't need from the phone, because you know
when you select the application from the marketplace,
| | 03:56 | it shows you what capabilities that app is
going to use, and you don't want your user
| | 03:59 | deciding not to use your app because it says
it needs access to the appointments calendar
| | 04:04 | when in fact it doesn't actually need that.
| | 04:06 | Now, looking a little bit further down, we
see the name of the starting page, which is
| | 04:12 | in our case, always MainPage.xaml.
| | 04:14 | If you wanted to start with a
different page, you would change this.
| | 04:17 | And then finally, here's how Background.png
is referred to, and the title that comes out
| | 04:23 | underneath Background.png
when it's on the home screen.
| | 04:28 | So we'll save that.
| | 04:29 | References, this is standard Visual Studio
references, to assemblies that you need to
| | 04:33 | build your app, in our case, for UnitsConverter
we don't need any additional assemblies.
| | 04:37 | For some of the other apps that we're building
we'll be adding additional toolkits to that.
| | 04:42 | App.xaml, as we mentioned in the introduction
is basic information about the application
| | 04:48 | resources which is shared amongst all your
XAML pages and also some lifetime information
| | 04:54 | to describe which methods inside the App.xaml.
cs are called for the events, such as Launching
| | 05:00 | and Closing and Activated and Deactivated.
| | 05:03 | It contains all of these methods which are
called in order to allow you to know how to
| | 05:09 | handle interruptions such as a phone call
or when the user hits the Back button and
| | 05:13 | exits your application, and throughout the
whole full lifecycle of the mobile app that
| | 05:18 | Microsoft has specified for Windows Phone.
| | 05:22 | And finally, there's MainPage.xaml, which
we've seen in earlier movies, which contains
| | 05:26 | the XAML and the designer for your user experience,
as well as the MainPage.xaml.cs, which by
| | 05:34 | default just contains your constructor.
| | 05:36 | So let's close the code file and build the
user interface for our UnitsConverter app.
| | 05:43 | First thing we're going to do is to minimize the
Solution Explorer so we have more room to see the XAML.
| | 05:48 | I'm going to shrink down the visual for the
designer and open this up just a little bit
| | 05:52 | so we can see more of what we're doing.
| | 05:55 | And as we always do, we're going to
click in the XAML and go Edit > Advanced > Format
| | 05:59 | Document so we can see all the attributes.
| | 06:02 | First step in building any app, which
we're going to do as we always do is change the
| | 06:06 | name, UNITS CONVERTER, and we're going
to change the PageTitle to temperature.
| | 06:13 | As we build this app we're going to build
it so first it just converts temperature,
| | 06:17 | and then we're going to add some capability
of settings so we can remember which kind
| | 06:21 | of conversion we want to do, and then we'll
add another conversion to do the conversion
| | 06:24 | between teaspoons and tablespoons.
| | 06:26 | Now, as we go through and build all these
applications, we're using an external code
| | 06:33 | snippet tool called Breevy.
| | 06:35 | That's because, while code snippets are
available for you to create here in the tools Code
| | 06:43 | Snippets Manager, inside Visual Studio,
it's not easy to build them and to import them,
| | 06:50 | so we're supplying all of the code snippets
for premium subscribers in the exercise files.
| | 06:55 | And I'll be going through all of the code,
so if you don't have the code snippets you'll
| | 06:59 | be able to pause the movie and follow along.
| | 07:02 | So in this case, we're going to start here where it
says ContentPanel - place additional content here.
| | 07:07 | We're going to select all of that, plus
the commented out ApplicationBar, and replace
| | 07:12 | it with the user
experience XAML for UnitsConverter.
| | 07:15 | One other thing to remember when
you're using Breevy, there's two modes.
| | 07:18 | There's a mode that says paste in snippets
as if you were typing them on the keyboard,
| | 07:22 | and there's another mode that says paste them
in as if they were pasted from the clipboard.
| | 07:26 | Be sure to set Breevy up to be pasting from
the clipboard, because Visual Studio, as you're
| | 07:31 | typing XAML, automatically adds quotes when
you type the first quote, and if you try to
| | 07:36 | paste in the snippet from Breevy, you end
up with a whole bunch of extra quotes and
| | 07:39 | the formatting isn't right.
| | 07:41 | So first, we'll select all this stuff and delete
it, and then we'll get our first snippet in here.
| | 07:47 | And now let's take a look at XAML that
we used to create this user interface.
| | 07:52 | We'll scroll back up here to the Content Panel
where we were before and go down through each
| | 07:57 | one of the controls and take a look at it.
So first, we have a TextBox, which is,
| | 08:03 | as you can see, over here, this is the
place where the user types in the first value to
| | 08:07 | be converted, and it's called the textBox1.
And from the default we did two things.
| | 08:13 | We changed the value of the text attribute
from being TextBox to being the empty string,
| | 08:19 | and we added an event handler here for
GotFocus and pointed it at Value1_GotFocus.
| | 08:26 | When we get into the next movie, and we
look at what the code behind actually does, the
| | 08:30 | purpose of this is so that when you tap either
of the two textboxes, both textboxes get their
| | 08:36 | value cleared so that when you type in
Fahrenheit and start typing in a new number, the old
| | 08:41 | Celsius value isn't shown.
| | 08:43 | And more particularly, because of the way
the software keyboard works, when you tap
| | 08:47 | in Celsius, the old Fahrenheit value isn't shown.
| | 08:49 | Next up is this TextBlock, which is
where we put the Fahrenheit label.
| | 08:55 | After that, we've got the second TextBox
where you type in your value in Celsius.
| | 09:00 | And again, as you can see, as we did with
textBox1, we've got an event handler here
| | 09:04 | for GotFocus so that we can clear the values.
| | 09:07 | And finally, we have
TextBlock for the Celsius label.
| | 09:12 | Now, you might notice by looking over here
at the designer, there's no button to say
| | 09:17 | how do I know when to convert.
| | 09:19 | So what we did was we used the ApplicationBar
in order to add a button to say click on this
| | 09:24 | button to convert. As you saw in the running
demonstration of the app when we looked at it earlier.
| | 09:30 | When you put things in the ApplicationBar,
either they're here, they show up in the Emulator,
| | 09:35 | they never show up in these four circles here.
| | 09:38 | So never expect to actually
see your icons in the designer.
| | 09:42 | And if we look at the attributes that
we've got here, you can see, first of all, that
| | 09:46 | we have a Click attribute.
| | 09:48 | This is an event that says, what should I
execute when the user taps the button? We're
| | 09:54 | going to have a method called Convert_Click.
| | 09:56 | And then we also have URI for the image that
we're going to show up there, and in a moment
| | 10:02 | I'm going to show you how we're going to go
get that image from a collection of images
| | 10:06 | that Microsoft gives you with the toolkit.
| | 10:09 | And finally, there's a Text attribute, which as
we saw when you click on the ellipsis, the ...
| | 10:14 | on the right-hand side of the ApplicationBar
and the ApplicationBar scrolls up, this is
| | 10:19 | what's going to show up in that
tiny text underneath the icon.
| | 10:23 | There are some very specific rules on which
kinds of URIs you can use for various things.
| | 10:30 | At the end we'll have a list of the Microsoft-
specific requirements for different things, but one
| | 10:36 | of the things you can remember right now is
that for every image you always need to have
| | 10:41 | a Leading Slash, especially
for things in the ApplicationBar.
| | 10:44 | So let's go bring the image into our app
so that when we run it, you actually see the
| | 10:48 | two curved arrows icons at
the bottom of the screen.
| | 10:50 | So we're going to come back to the Solution
Explorer, and as you see from the URI here
| | 10:55 | where it says /images, it's expecting a folder.
| | 10:59 | So we're going to right-click and add a new
folder, call it Images, and then we're going
| | 11:04 | to right-click here and say Add Existing Item.
| | 11:07 | As I mentioned, Microsoft provides in the
toolkit a collection of icons, so it's under
| | 11:14 | Program Files(x86) > Microsoft
SDKs > Windows Phone > v7.1 > Icons.
| | 11:23 | What I like to do is to take that folder and
drag it right over here to my Favorites, because
| | 11:28 | I'm going to access it over and over again.
| | 11:30 | When I click on Icons, you're going to see
three folders here: there's a dark folder,
| | 11:36 | there's a light folder,
and there's a vector folder.
| | 11:38 | The dark folder and the light folder
contain the same set of icons, but one of them is
| | 11:43 | white-on-black and the other is black-on-white.
| | 11:46 | While Microsoft provides both of those, here's
a tip, only use the ones from the dark folder
| | 11:51 | in your application, the operating system
will automatically switch to the light ones.
| | 11:55 | If you're doing this and debugging on the
phone itself, and you have your phone set
| | 12:00 | to the light theme, you're thinking maybe
I should use the one from the light folder
| | 12:03 | because that looks really great.
| | 12:04 | That's great as long as the user never
changes his phone or her phone to the dark theme,
| | 12:08 | because as soon as they do, the icon disappears.
| | 12:12 | So we're going to always use
the ones from the dark folder.
| | 12:15 | In the vector folder are all the
Adobe Illustrator vector images there.
| | 12:19 | So if you wanted to take these and
customize them and build something of your very own,
| | 12:23 | you could start with that and
create your own dark or light icon.
| | 12:26 | So we're going to come
back to the dark folder and
| | 12:29 | as you can see--it's probably a little hard
to see on a smaller screen--but each one of
| | 12:33 | these things has an icon in it. But it's very
dim trying to see it in the Open File dialog here.
| | 12:40 | But what we want to do is come down here and
scroll down to where we get appbar.sync.rest.png,
| | 12:48 | and we just click Add, and that comes
over here and ends up in our solution.
| | 12:52 | Now, that's not quite enough.
| | 12:54 | In addition to bringing it in as Add
Existing File, we also have to set the properties on
| | 12:59 | it, because the default properties
is that it shows up as a resource.
| | 13:04 | And for the use with the ApplicationBar with
Silverlight, it needs to be a content file.
| | 13:08 | So we'll open up the Properties tab here by
pressing F4, and we come over here to Build
| | 13:14 | Action, drop this down and select Content,
and then you also have to set Copy to Output
| | 13:19 | Directory, we'll drop this down and select Copy
always, and then we'll get rid of the Properties window.
| | 13:24 | So now we have everything we
need for our user interface.
| | 13:28 | If we tried to build this right now, it
wouldn't run because we don't have the code behind.
| | 13:32 | But that's the topic of the next movie.
| | Collapse this transcript |
| Responding to the Application Bar| 00:00 | Now that we've built our user experience let's
put some code in the CS file in the code behind
| | 00:06 | so that we can respond to the icon with the two
curved arrows, which implements our conversion.
| | 00:11 | So we come to the Solution Explorer, we
open up MainPage, we open up MainPage.xaml.
| | 00:17 | Before we start writing code, let's take a
brief look at the contents of this class,
| | 00:21 | as it was expanded from the template.
| | 00:24 | The first set of use statements give us
connectivity to the base.net class libraries.
| | 00:29 | The ones labeled System.Windows
connect us up to the Silverlight libraries.
| | 00:34 | And finally, the Microsoft.Phone.Controls
using connects us up with the specific controls
| | 00:39 | such as the ApplicationBar and the ApplicationPage
that you get specific to the Windows Phone.
| | 00:45 | The namespace comes from
the name of your application.
| | 00:48 | And you have by default a Constructor, which
calls InitializeComponent, which is required
| | 00:53 | in order to be able to initialize
the Silverlight controls on the page.
| | 00:57 | Your class may not look exactly like this,
because during the demonstration of building
| | 01:01 | the user experience I clicked in the word
Click in XAML in the ApplicationBar XML, and
| | 01:08 | it automatically added this
ApplicationBarIconbutton_Click method.
| | 01:12 | We're going to replace that with
one that's called Convert_Click.
| | 01:16 | So to implement the code here we're going to
select everything between the opening brace
| | 01:21 | underneath the class declaration and
the closing brace that closes the class.
| | 01:25 | So we will delete that, and then we will type
in our snippet, and now let's go take a look
| | 01:29 | at what we've actually got.
| | 01:31 | So we have our Constructor still.
| | 01:33 | We have a Convert_Click, which is how we
respond to the button on the ApplicationBar.
| | 01:39 | And we have two empty implementations of the
GotFocus event handlers so that when the user
| | 01:45 | taps on the textbox, the appropriate method gets
called so that when we're actually implementing
| | 01:50 | the full conversion, it can clear out both
textboxes and decide whether you're converting
| | 01:56 | Fahrenheit to Celsius, or Celsius to Fahrenheit.
| | 01:59 | So now we have the minimum amount of code
behind let's check and see if everything is wired up.
| | 02:05 | So we'll press F5 and run
this app in the Emulator.
| | 02:09 | Right now, our app doesn't do anything.
| | 02:10 | If we tap here, we get the keyboard, if we tap
here, we get the keyboard, if we tap anywhere
| | 02:16 | else, the keyboard goes way.
| | 02:17 | But to make sure we've got our ApplicationBar
connected up let's tap on the icon, and there
| | 02:23 | we've got a message box, so we know we're
wired up, we know we're good end to end.
| | 02:28 | So let's make sure that you got this far,
and then we'll go on the next movie to actually
| | 02:34 | add the semantic logic behind here to
actually make this a Units Converter App.
| | Collapse this transcript |
| Implementing click handlers| 00:00 | All right, now that we've built the user experience
and we've made sure that we can connect to the
| | 00:05 | application bar respond to that click,
let's implement a more meaningful click handler
| | 00:10 | for the application bar button and
implement two click handlers for the GotFocus event
| | 00:16 | that's associated with each one of the textboxes
so that we can properly decide which direction
| | 00:20 | we're doing the conversion and clear out the
pre-existing values from the previous conversion
| | 00:26 | before the user starts typing.
| | 00:28 | So let's open up the Solution Explorer,
and once again open up MainPage.xampl.cs.
| | 00:33 | The first thing we're going to do is to
delete the existing code, because we are going to
| | 00:38 | completely replace that with
our new implementation.
| | 00:40 | But before we paste in the full implementation
I mentioned a couple times that we have to
| | 00:45 | know which direction we're converting. Are
we converting Fahrenheit to Celsius or Celsius
| | 00:50 | to Fahrenheit? So let's create a Boolean
variable, private bool convertValue1 so that we know
| | 00:57 | whether we are converting value 1 Fahrenheit
into Celsius or value 2 Celsius into Fahrenheit.
| | 01:03 | And then let's put in our click
handlers, and let's take a look at them.
| | 01:09 | So here is the handler Convert_Click which
is invoked when the user taps the icon in
| | 01:14 | the application bar at the bottom screen, and it
simply says the Boolean variable convert value one.
| | 01:20 | If that's true that means
we're converting Fahrenheit.
| | 01:22 | So we're going to get the fahrenheitValue by parsing
it from the textBox1 text property into a double.
| | 01:28 | So track 32 and multiplied times five nines,
the classic conversion formula and then put
| | 01:33 | the variable back as a string into
the textbox property of the textBox2.
| | 01:38 | The format code capital F means
converted as a two decimal place string.
| | 01:42 | We put this inside a try catch block,
because if the user types something say 32.0.5 the
| | 01:51 | parse method on the double type would
throw an exception, and if that happens we want
| | 01:55 | to put the word Error in the textbox where the
user didn't type so that they can correct there.
| | 02:01 | If convertValue1 is false that means
we're converting from Celsius to Fahrenheit.
| | 02:06 | So again we go get the double value from textBox2,
apply the conversion algorithm Celsius value
| | 02:12 | times 9.5 plus 32, and once again convert
it back to it to a two-decimal place string
| | 02:18 | and put it back into the text property of
textBox1 and similarly handle the exception
| | 02:22 | in case the user typed an
invalid value into textBox2.
| | 02:25 | Finally, the last line in this method this.
Focus is what makes this software keyboard go away.
| | 02:31 | If you look in the upper left-hand corner
here you can see that the name of our class
| | 02:35 | is called UnitsConverted.MainPage.
| | 02:37 | When we say this.Focus it means that
we're asking the page to become the focus which
| | 02:42 | take focus away from one of the textboxes
which then tells the operating system to remove
| | 02:47 | the onscreen keyboard.
| | 02:48 | Finally, let's take a look at the two handlers
for GotFocus event that happens with either
| | 02:54 | one of our textboxes in the first one Value1_
GotFocus, we set convertValue1 = true meaning the user
| | 03:01 | tapped in value 1 we're going to convert
that into Celsius into value 2, and we set both
| | 03:06 | textboxes equal to the empty string so that
the user interface looks clear to the user.
| | 03:11 | This is less important in this case than it
is in next case, because when the user tabs
| | 03:16 | in the Fahrenheit textbox, you
can't really see the Celsius textbox.
| | 03:21 | But most definitely when the user taps in
the Celsius Textbox you could see the old
| | 03:25 | value in Fahrenheit, and
it looked a little confusing.
| | 03:28 | So we clear both of them out after we set
the Boolean flag to indicate which direction
| | 03:32 | we're doing the conversion.
| | 03:34 | So that's all we need to
actually implement our conversion.
| | 03:37 | Let's once again run our results here.
| | 03:40 | As we've seen before sometimes the
Emulator doesn't come automatically to the front.
| | 03:43 | So we'll bring it to the front, and we will
rerun that demo that we did before convert
| | 03:48 | to 12 Fahrenheit into 100 Celsius.
| | Collapse this transcript |
| Saving and loading settings| 00:00 | Now we have a basic Units Converter App that can convert
Fahrenheit to Celsius and Celsius to Fahrenheit.
| | 00:06 | But that is really only a minimally useful app,
typically Units Converter app would contain
| | 00:11 | a whole bunch of different kinds of conversions.
| | 00:13 | So to show how you would handle multiple conversions
and specifically how you would handle remembering
| | 00:19 | what was the last type of conversion that
you did, we're going to implement Saving and
| | 00:24 | Loading Settings using the Isolated Storage
Settings mechanism, and then we're going to
| | 00:29 | add another menu item on the main page to
allow you to select temperature versus Teaspoons
| | 00:34 | and Tablespoons, and then we're going to
add some code to go and read the settings and
| | 00:39 | configure the user experience, configure the
labels depending on what the saved value of
| | 00:43 | the settings was when the app starts.
| | 00:46 | So let's once again come over
and open up our Solution Explorer.
| | 00:50 | First thing we need to do is to add a new
class to access the isolated storage for settings.
| | 00:57 | You could do this in code by itself, but
it makes it much more convenient if you have
| | 01:02 | a class that does this.
| | 01:04 | That way you can actually implement the
saving and loading of your settings as a variable
| | 01:09 | declaration versus having to write a special method
for each individual settings with a bunch of code.
| | 01:15 | So let's come to the UnitsConverter
project, right-click and say Add Class.
| | 01:22 | We'll call it Settings, and in this case
we have a snippet that implements the entire
| | 01:28 | class, so we're just going to select the entire
thing, all right, and then we'll expand our snippet.
| | 01:34 | So let's take a look at what this code does.
| | 01:36 | Come back to the top.
| | 01:37 | The only using we need is
for System.IO.IsolatedStorage.
| | 01:41 | Windows Phone has a separate sandboxed collection
of files that are associated uniquely with each app.
| | 01:48 | Means, that the section of the file system
that's associated with the UnitsConverter app
| | 01:52 | isn't accessible to the section of the
file system in the phone's storage that's
| | 01:57 | associated with the Take a Note App. But
it means that you can load and save files in
| | 02:02 | a hierarchy just as you
would with any other.NET app.
| | 02:05 | Plus there is additional facilities that we'll
look at when we implement this on its application
| | 02:09 | to allow you to use an on-screen database.
| | 02:11 | But in this particular case, we're going to
use a specific part of the Isolated Storage
| | 02:15 | library that talks about
being able to implement settings.
| | 02:19 | First we declare a class, Settings of T. So
that when we use it to declare variables we
| | 02:24 | can declare an individual variable each type
for each individual kind of setting that we have.
| | 02:29 | And we keep track of the tag for that setting
so that we can use that to talk to the Isolated
| | 02:35 | Storage APIs, and a default value.
| | 02:38 | And you'll see how we use this when we actually implement
the Settings variable back in our MainPage.xaml.
| | 02:44 | And then finally we implement a value
property that has the getter and the setter and the
| | 02:50 | getter says, if (!IsolatedStorageSettings.
ApplicationSettings.TryGetValue.
| | 02:55 | So this says let me go to isolated storage
and see if I can find a value for this setting.
| | 03:00 | If I can't find it, we actually set the
setting to the default value that you specified in
| | 03:05 | the constructor and return that.
| | 03:07 | If there was a setting that came back,
we return the value for that setting.
| | 03:12 | And similarly when you set the setting and code
as you'll see in a minute from our MainPage.xaml,
| | 03:17 | we simply call IsolatedStorageSettings.ApplicationSettings
using the name of the setting that you passed
| | 03:23 | and store the value in it.
| | 03:25 | So we'll save this and close this, and now
we'll come back to our MainPage.xaml and start
| | 03:32 | using the Settings class.
| | 03:36 | First thing we're going to do is to add a
using for the namespace for the Settings class,
| | 03:39 | because we name that WPET, because we reuse
the same Settings class code in all of the
| | 03:47 | sample applications that we're building.
| | 03:49 | So now that we've done that, we now need to
construct a variable that is connected with
| | 03:55 | the Settings class that helps us remember
whether we're doing a temperature conversion
| | 03:59 | or whether we're doing a
Teaspoons Tablespoons conversion.
| | 04:03 | So, this is how that works.
| | 04:08 | We say Settings of type String and the
variable we're going to use to keep track of that is
| | 04:12 | called conversionType, and then we just simply
call the constructor for settings with conversionType
| | 04:19 | which is the tag that's going to be stored
in Isolated Storage, and the word temperature
| | 04:23 | which is the default value.
| | 04:25 | What happens when this is executed at runtime?
When the variable is declared is that it actually
| | 04:30 | goes as we saw out to isolated storage to see
if there's an existing value for conversionType
| | 04:36 | in which case that's what gets returned
versus this default value of temperature.
| | 04:40 | So the first time this code is run, this gets
set to temperature subsequently, it gets set
| | 04:45 | to whatever value is being
stored in isolated storage.
| | 04:48 | All right, now that we're going to be doing
multiple kinds of conversions let's once again,
| | 04:54 | select our click handlers, delete them, and
now we're going to expand the code snippet
| | 04:59 | and then go look at the code that we pasted in.
| | 05:01 | All right, now let's go take a
look at the code we just added.
| | 05:07 | We'll start out here,
PhoneApplicationPage loaded.
| | 05:11 | This is a handler that can respond to an event
that we're going to add to the XAML that will
| | 05:16 | be called when the page is loaded.
| | 05:18 | What it's going to do is by default set
convertValue1 = true and call this method called SetupLabels
| | 05:25 | which is above here.
| | 05:27 | That properly configures the label at the
top of the screen, the label at the top of
| | 05:32 | each textbox so that the user knows
whether they're converting temperatures or spoons
| | 05:38 | and whether it's Fahrenheit and
Celsius or Teaspoons and Tablespoons.
| | 05:41 | Now that we've got those two things implemented,
and I will be going over to the XAML in a
| | 05:46 | minute to add the particular attribute
to make it call that PageLoaded handler.
| | 05:51 | We've expanded our Convert_Click method now
to look at the value of the conversion type,
| | 05:56 | because we've got two types now,
we've got temperature and spoons.
| | 05:59 | So in the Temperature case we have exactly
the same code that we had in the previous
| | 06:04 | version of the app that we had at the end
of the last movie, and in the Teaspoons and
| | 06:08 | Tablespoons section, in that case, we have
very, very similar code except we have two
| | 06:13 | different algorithms here for Teaspoons to
Tablespoons, you divide by 3 and for Tablespoons
| | 06:20 | to Teaspoons you multiply times 3.
| | 06:25 | The two GotFocus handlers are
exactly the same as they were before.
| | 06:30 | And now we have two additional click handlers
for the two menu items which we're about to
| | 06:35 | add to the Application Bar.
| | 06:37 | One to change the settings to say we're converting
temperatures and another to change the settings
| | 06:42 | to say we're converting
Teaspoons and Tablespoons.
| | 06:45 | That's all the C# code we need to do, so
let's go to the XAML page and add the two bits of
| | 06:51 | XAML that we need to
connect these things together.
| | 06:56 | Up here in the PhoneApplicationPage, here's
where we're going to add the callout that
| | 07:00 | we want to call our PageLoaded method.
| | 07:03 | So add that, and so we set the Loaded
attribute to PhoneApplicationPage_Loaded, that connects
| | 07:11 | it up to that method in the code behind.
| | 07:15 | Then we come all the way to the bottom, and
currently inside of our Application Bar all
| | 07:20 | we have is the one ApplicationBarIconbutton.
| | 07:24 | Now we're going to add a couple of ApplicationBar
icon menu items. That are for Temperature and
| | 07:33 | for Teaspoon/Tablespoons and the appropriate
Click items here to call the appropriate methods.
| | 07:41 | And now let's run our new version of the app.
| | 07:48 | So by default just as before we convert
Fahrenheit to Celsius, and Celsius to Fahrenheit.
| | 07:52 | But now we have our temperature and teaspoon/
tablespoon menu items in the Application Bar, so we can
| | 07:59 | now select teaspoon/tablespoon.
| | 08:00 | And now you see the name of the page is changed,
and the Teaspoons and Tablespoons text blocks
| | 08:06 | have changed at the top of each of the
textboxes, and if we come down here and say how many
| | 08:10 | Teaspoons of oil do we need to make our popcorn?
Turns out we need 9 Teaspoons, or 3 Tablespoons.
| | Collapse this transcript |
| Preparing your app for shipment| 00:00 | The final step in completing our UnitsConverter
app is going to be that we're adding an About page.
| | 00:06 | This is going to help us understand how to
add new pages, how to do basic navigation
| | 00:11 | between one page and another, and also
adding an About page is something that Microsoft
| | 00:16 | says is a good practice, because it helps
your users communicate feedback to you and
| | 00:22 | helps them find other applications that
you have in the Windows phone marketplace.
| | 00:25 | And we will also update the icon and trim down the
list of capabilities in the WMAppManifest.xml file.
| | 00:33 | So to begin we're going to come over here
and add another page, doing something similar
| | 00:38 | to what we did when we added a new class,
we're going to right-click on Units Converter,
| | 00:42 | come down to select Add.
| | 00:43 | We're going to say New Item, and we're going to
come up here and select Windows Phone Portrait
| | 00:48 | Page--because it matches the same style for
the rest of the UnitsConverter app--and we're
| | 00:52 | going to call it About.
| | 00:57 | When you add a page, you get
both a XAML and a code behind file.
| | 01:03 | What we're going to do here is we're
actually just going to select all of this XAML and
| | 01:07 | replace it, and let's take a quick
look at what XAML is that we just added.
| | 01:16 | Everything up here at the
top is all the standard things.
| | 01:19 | We titled the ApplicationTitle UNITS
CONVERTER just as we did with our main page.
| | 01:25 | Our PageTitle is about and down here in the
ContentPanel we first have a TextBlock where
| | 01:31 | we're going to put some text about which is the
version number of this app and a few other details.
| | 01:36 | We set the TextAlignment of this to Center so that
the text shows up nicely when we take a look at it.
| | 01:41 | Then we added three buttons. Scroll down here.
| | 01:46 | As you can see, all three buttons, and go
back here and look at each button in turn.
| | 01:53 | So the first button says, Suggest a new
feature, and it goes off to Suggestion_Click.
| | 01:58 | The second button says, More from DreamTimeStudios,
this is how you can learn more about the other
| | 02:03 | apps we have in the store, and finally, we
have a Learn how to build this application
| | 02:08 | button that directs you to this class.
| | 02:11 | So when you buy this app in the store, which
will be free, you'll be able to actually direct
| | 02:16 | yourself back to this course.
| | 02:18 | So now let's go over here and open up the
code behind, and once again we're going to
| | 02:22 | select the entire thing and paste in our class,
and let's take a look what's in the class.
| | 02:29 | We've got our standard set
of usings here at the top.
| | 02:33 | In our constructor we initialize the text
property of our text block so that we can
| | 02:38 | see the version number and copyright message,
and then we have our three click handlers.
| | 02:43 | What's useful to know about these three click
handlers is that we're using two of the launchers
| | 02:48 | that are built into the
Windows Phone operating system.
| | 02:51 | The first is the EmailComposeTask.
| | 02:54 | What we're doing here is we're saying we're going
to create a new instance of the EmailComposeTask,
| | 02:58 | we can set the Subject, we can set the To
line, and then we let the operating system
| | 03:03 | display the pane which allows
the user to type in his message.
| | 03:06 | We can't demonstrate the functionality of
this on the Emulator, because there is no
| | 03:10 | mail clients in the emulator, but when you
run this on a device, it will actually open
| | 03:15 | up your mail client, and it
will allow you to send a mail.
| | 03:18 | We look at the More_Click handler and the
Learn_Click handler, and you can see we're
| | 03:23 | going to use the WebBrowserTask, and this
is going to allow us to launch the built-in
| | 03:28 | Internet Explorer and
direct it at a specific URI.
| | 03:31 | In one case, it's our dreamtimestudioz web
site and in the other case it's my author
| | 03:36 | landing page here at lynda.com.
| | 03:38 | Now that we've built our About page, we
need to go back to our main page and implement
| | 03:43 | the menu item to be able to see our About
page and the code behind that which actually
| | 03:49 | navigates to the new page.
| | 03:51 | So let's come back to MainPage.xaml, and
we're going to open the CS file and come down here
| | 03:56 | at the bottom and add the code.
| | 03:59 | And if we look at this click handler, we can see
it's using something called the NavigationService.
| | 04:04 | Every page has a reference to the NavigationService
which is how you open up one page from another.
| | 04:09 | In our case, we're telling it to go ahead
and open up the About page, and this actually
| | 04:14 | pushes the current page on the
stack, and goes to the About page.
| | 04:19 | When the user clicks the Back button as you will see
in a minute, it will bring us back to the main page.
| | 04:24 | So next thing we have to do is to open up
our XAML and come down to the bottom, and
| | 04:35 | in addition to our Temperature and Teaspoon/
Tablespoon menu items, we're going to add one more for
| | 04:39 | the About page which goes off to the About_
Click handler and now when we run our application.
| | 04:49 | We'll first see the Settings class in action,
because the last thing we did was convert
| | 04:54 | tablespoons to teaspoons in order to make our
popcorn, and when we pop up the application bar.
| | 04:59 | We'll now see three menu
items here in the application bar.
| | 05:02 | Now one of the things you might find
interesting here is that if you look in our XAML, the
| | 05:09 | text for the top menu item has Temperature
with a capital T, the second one has Teaspoons
| | 05:14 | and Tablespoons with two capital Ts and
the last one has About with a capital A.
| | 05:18 | Microsoft in their Metro Design Guidelines
enforces in this particular case that all
| | 05:24 | these things should always be lowercase,
because they want to make sure that the flavor of
| | 05:31 | the design aspects of the Metro
remains consistent throughout.
| | 05:35 | So let's select our About page, and there
we go, you can see our About page, here's
| | 05:39 | our centered text which we added
programmatically, and here's our buttons.
| | 05:44 | So let's click here, and go take a
look at the course page on lynda.com.
| | 05:48 | The first time you run Internet Explorer in
the Emulator, it asks you whether you want
| | 05:53 | to send your browsing history to Microsoft, and
sometimes, it also fails to navigate on the first try.
| | 05:59 | But once you've been through that the first
time, then you have functionality, and that
| | 06:02 | particular glitch doesn't happen on the devices.
| | 06:06 | But you might see it because that was your first
time using the Internet Explorer on the Emulator.
| | 06:10 | Then if we click the Back button to go back
to our app, we click the Back button again,
| | 06:14 | we navigate back to our UnitsConverter.
| | 06:16 | And that's it We've now built a complete end
to end app with the user experience, with
| | 06:21 | controls on the screen, and click handlers
that go along with those controls, in this
| | 06:25 | particular case our GetFocus thing so that we
can know which value we're going to convert.
| | 06:29 | We've implemented a Settings class which we're
going to be using in many of these applications
| | 06:33 | we're building that allow you to have
persistent settings using the Isolated Storage Settings
| | 06:37 | API, and we've added an About page.
| | 06:41 | Ok so that's the code for
our app, it's ready to go.
| | 06:44 | To get it ready for the marketplace,
we have two more things we have to do.
| | 06:47 | First, we have to update the icons and
secondly we need to go update that WMAppManifest in
| | 06:54 | order to edit the capabilities.
| | 06:55 | So let's exit the app in the Emulator, jump
back to Visual Studio, open up the Solution
| | 07:02 | Explorer and come over here, and
we'll say once again Add Existing Item.
| | 07:07 | We'll navigate to the desktop, into our
exercise files folder, and pick up the icon from the
| | 07:14 | End state of our UnitsConverter example files.
| | 07:18 | We need both the application icon and the
background, remember the application icon
| | 07:24 | is the 62x62 pixel image that shows up in
the application list, and the background icon
| | 07:30 | is the 173x173 image that
shows up on the homepage.
| | 07:40 | And now when we run our app one more time and click back
to here, we'll see, ah, this is a good thing to know
| | 07:54 | It didn't update this,
because we didn't rebuild.
| | 07:56 | So we will come back to Visual Studio, stop
our debugger, rebuild the solution which will
| | 08:05 | cause it to re-add those application icon
resources to the binary, and then we'll run it again.
| | 08:15 | There is our UnitsConverter, there is our
new icon, and when we pin to start, there
| | 08:23 | is a new icon from the Background.png.
And that's it! We're done with the icon update.
| | 08:30 | Now let's go take a look at the capabilities
update, back to the Solution Explorer, open
| | 08:36 | up the Properties folder,
and open up WMAppManifest.xml.
| | 08:42 | Now for this particular
application let's see what we need.
| | 08:46 | We don't need Gamer Services, not identifying
our device or our user, we're not using location
| | 08:52 | services, we're not using the
media library or the microphone.
| | 08:56 | We are using networking,
because we're using the web browser.
| | 08:58 | We're not using phone dialer or
push notifications or the settings.
| | 09:03 | We'll leave in the web Browser Component.
| | 09:04 | We're not using the camera, or
the context, or the appointments.
| | 09:08 | Again, remember it's important to narrow this
down as much as possible, because the uptake
| | 09:14 | of your app by users is inversely
proportional to the number of capabilities that you need.
| | 09:19 | People feel comfortable having your app ask
for only the capabilities that it actually needs.
| | 09:27 | And that's it! We're done with the
UnitsConverter and ready to move on.
| | Collapse this transcript |
|
|
5. Building SonnetsIntroducing sonnets| 00:00 | If the person of your romantic interest is
an English literature major, or you just
| | 00:05 | have a great desire to work with a small
set of structured public domain data, then the
| | 00:10 | next app is for you.
It's called Sonnets.
| | 00:13 | Let's take a look at the finished app.
| | 00:16 | Shakespeare wrote 154
sonnets, and this is all of them.
| | 00:19 | You can scroll through the list and
see all the sonnets and read them.
| | 00:24 | Sonnet XVIII, Shall I compare thee to a summer's day?
You can read the sonnet, go back, and
| | 00:31 | read another one to your heart's content.
| | 00:35 | Also as with all of our
apps, there's an About page.
| | 00:38 | The reason we're building this app is because it
demonstrates basic data binding with Silverlight.
| | 00:44 | It's going to allow us to show how to
explore the model View ViewModel otherwise known as
| | 00:49 | MVVM pattern as it relates to
building applications for Windows Phone.
| | 00:53 | It's going to allow us to demonstrate how to
build a master-detail pattern using Windows
| | 00:58 | Phone pages, as in this being the master list,
and this being the detail of an item in that list.
| | 01:06 | And finally, it's going to allow us to
demonstrate how to load external data, in this case, the
| | 01:11 | XML file filled with all 154 of the sonnets.
| | 01:16 | One last thing that I want to point out is
in the XML file all of the sonnets have all
| | 01:21 | of the lines in a completely unformatted way.
| | 01:24 | Part of the app we're going to be building
also formats the last two lines indented,
| | 01:29 | which is the standard way of
formatting Shakespeare's sonnets.
| | 01:34 | So enough looking, let's roll up
our sleeves and start building.
| | Collapse this transcript |
| Data binding with Silverlight | 00:00 | Time to write some more code.
| | 00:02 | Let's begin by creating a new project for
our Sonnets app, and we'll call it Sonnets,
| | 00:08 | and we'll pick the Windows
Phone Databound Application.
| | 00:12 | As you can see, over here in the miniature
view, it's an app that has an application
| | 00:17 | title, a page name, and a collection of items
in the list box that the user can scroll through
| | 00:22 | to put actual data in, in our case, 154 sonnets from
the bard, so we'll click OK and create the new solution.
| | 00:30 | And before we actually start adding our
customization in here, we'll change the name of the app
| | 00:36 | and change the name of the page title, and
then explore some of the differences between
| | 00:40 | this solution and the one that came from our just
plain Windows Phone portrait application setup.
| | 00:46 | So as always, first thing we'll
do is reformat the XAML.
| | 00:51 | Click in the XAML Pane and select Edit > Advanced >
Format Document so we can see all of the attributes.
| | 00:56 | Over here in the designer view, you'll see
that the list box visually appears to have
| | 01:02 | data in it, design one followed by some
Lorem Ipsum, design two, and so forth.
| | 01:06 | I'm going to shrink this down just
a little bit so you can see it all.
| | 01:09 | Between Visual Studio and Expression Blend,
there is a way that you can create data that
| | 01:15 | shows up only at design time just so that you can
see the way the items in your list box will work.
| | 01:20 | Right now, we're just going to completely hide the
entire designer pane so we can look at the XAML.
| | 01:26 | That is done by adding in this XML namespace
here for expression/blend, and then providing
| | 01:32 | these three items here, the DesignWidth, DesignHeight,
and design DataContext which says in the SampleData
| | 01:40 | directory, there is a XAML file that has the
sample data that we want to load into the list box.
| | 01:46 | We don't actually touch the sample data, but
it's useful if you had other kinds of data.
| | 01:52 | This is where you're going to find that in
order to be able to customize the sample data
| | 01:55 | as you customize your user interface.
| | 01:58 | Now we'll scroll down here
and change the name of this.
| | 02:01 | We're going to call it SONNETS, and we're
going to change the page title to all, and
| | 02:07 | the reason is because in the subsequent chapters,
we're actually going to build a Sonnets app
| | 02:13 | that allows you to have the list
of all sonnets, and your favorites.
| | 02:16 | So we want to make this look visually similar.
| | 02:20 | The next thing we'll see, if we go down now
to the content grid is that the content grid
| | 02:24 | is filled with a list box, and the list box
uses Silverlight data binding, something that
| | 02:30 | you should be familiar with from the Silverlight
course or from your past experience with Silverlight.
| | 02:35 | You see here the ItemsSource is the item's
property from the binding, and here is an
| | 02:41 | event so that when someone taps on one of
the items in the list, the SelectionChanged
| | 02:45 | event is raised, and this method is called.
And there is a data template for this list
| | 02:50 | box which sets up exactly the visual
appearance of the two text blocks that represent each
| | 02:56 | item in the list box.
| | 02:58 | In this case, the first one is bound to the LineOne
property, and Is set up as PhoneTextExtraLargeStyle.
| | 03:05 | There are a number of textual styles so that you
can have your apps look like the built-in apps.
| | 03:11 | So there is an ExtraLargeStyle, there is a
LargeStyle, and there is also something called
| | 03:15 | SubtleStyle which is what LineTwo is set up
so that the line one we use in this app to
| | 03:21 | show the number of the sonnet, line two, we
show the first line of the text, and that's
| | 03:27 | bound to the LineTwo property in the ViewModel.
| | 03:30 | One last thing before we get off of the
main data binding is just to show that we have a
| | 03:35 | --in the source code here--a ViewModels
folder which is where this actual data context comes
| | 03:41 | from the MainViewModel which is where
the LineOne and LineTwo properties are.
| | 03:45 | And the sample data for designing comes out
of the SampleData folder you saw the URI there
| | 03:50 | before for MainViewModelSampleData.
| | 03:54 | So that's the setup that this project
template configures for Silverlight data binding.
| | 03:59 | Let's move on and take a look at the model
View ViewModel pattern in implementation.
| | Collapse this transcript |
| Exploring the Model-View-ViewModel pattern (MVVM)| 00:00 | So we've looked at data binding from the XAML side,
now let's look at data binding from the code side.
| | 00:06 | First of all, we'll open up the xaml.cs
file that goes along with the main page.
| | 00:12 | When we look at the constructor, we can see
that in addition to the InitializeComponent
| | 00:16 | call, we have two more lines.
| | 00:18 | The first one sets the data context for this page to
the value of the ViewModel property on the app class.
| | 00:24 | We'll go look at how that's set up in a minute.
| | 00:27 | But in addition, it also sets the Loaded event to
point to a new event handler called MainPage_Loaded.
| | 00:35 | So this is an alternative way of getting
the Page_Loaded event to be called compared to
| | 00:41 | the XAML version that we
used in the units converter app.
| | 00:46 | Since we know that we have our list of sonnets
on the main page, we have a SelectionChanged,
| | 00:51 | and we'll dig into how all this works in
the next movie, but this is where we determine
| | 00:56 | which sonnet is selected and navigate off
to the details page. And if we come down to
| | 01:01 | the Page_Loaded call, this is a way of
making sure that the data has actually been loaded
| | 01:07 | from the external file.
| | 01:09 | It says if the DataLoaded properly on the
ViewModel is set to false, we call the LoadData
| | 01:14 | method on that ViewModel
to get it to load its data.
| | 01:18 | If we go and look at the app class, we'll
see it has a ViewModel instance variable and
| | 01:25 | a ViewModel property which simply says when
somebody tries to get this if that instance
| | 01:30 | variable is null, we new up a new instance
of the ViewModel class, and if we go and look
| | 01:36 | at the ViewModel class, we'll see that it
is a traditional MVVM INotifyPropertyChanged
| | 01:44 | implementation, and that's what makes it work to bind
the data between the class and Silverlight and the XAML.
| | 01:51 | In our case, we're not changing any of the
data, so the properties won't change other
| | 01:56 | than the fact that we're
loading new data into it.
| | 01:59 | But this is a standard
way of doing data binding.
| | 02:01 | Right now, we're using what's called one-way
data binding just from our data to the screen.
| | 02:06 | You could in subsequent apps that you build
end up using two-way data binding, so that
| | 02:11 | if the user changes something on the screen,
that it actually changes something in the model.
| | 02:15 | Here's our SampleProperty, here's our
IsDataLoaded property, and here in the default template
| | 02:22 | is where the data for the
ViewModel is actually instantiated.
| | 02:27 | In fact, let's go ahead and run this app
Right now, so you can see what happens with the
| | 02:32 | template straight out of the box.
| | 02:34 | Remember that you saw in the XAML, we'll go
take a look at it, for the MainPage, we open
| | 02:40 | up the designer again, we see design
one, designed two, and design three.
| | 02:47 | When we run it, we come back over here to the
ViewModel, you'll see that it's instantiating
| | 02:52 | instances of the ItemViewModel class and filling
it in with runtime one, runtime two, and so forth.
| | 02:57 | So let's run this press F5, and we'll
see there is our runtime data.
| | 03:03 | Again, this is all still can't data, but it
shows you how if you simply wanted to make
| | 03:07 | a real symbol app that only had fixed data, all
you have to do is modify this LoadData method.
| | 03:13 | In our case, when we complete our app, we're
actually going to load the data from an external file.
| | 03:19 | Before we complete our examination of the
MVVM pattern, let's go take a look at the
| | 03:25 | definition of ItemViewModel because we're
going to be using that throughout this particular
| | 03:29 | app and the next two.
| | 03:32 | So here ItemViewModel is yet another
implementation of INotifyPropertyChanged which has three
| | 03:38 | properties: lineOne, lineTwo,
and lineThree, that's it.
| | 03:43 | Three strings, and you're good with the standard
NotifyPropertyChanged mechanism that implements
| | 03:48 | that INotifyPropertyChanged interface.
That's our MVVM overview.
| | 03:53 | Let's move on now to looking at how the two
pages interact with each other in order to
| | 03:58 | implement the master-detail
pattern using Windows Phone pages.
| | Collapse this transcript |
| Implementing the Master-Detail pattern using pages| 00:00 | The final part of our examination of the Windows
Phone Databound template, we're going to look at how
| | 00:06 | the master-detail pattern is
implemented using Windows Phone pages.
| | 00:11 | Come back to our code again.
We looked at this briefly before.
| | 00:15 | The key is to look at the
MainListBox_SelectionChanged event handler.
| | 00:20 | When the user taps an item in the list box,
the SelectionChanged event is fired, this
| | 00:25 | method gets called, and we First of all, make
sure that the selected index has some value.
| | 00:31 | Sometimes this event gets fired on
un-selections, in other words, you select something, and
| | 00:35 | then you do something else and the event
will get fired again, but there won't actually
| | 00:38 | be an item selected.
| | 00:39 | So you put a guard here to make sure that
that's the case because you don't want to
| | 00:42 | navigate to your detail page
if there is no actual selection.
| | 00:47 | The way the master and detail is set up is
that the detail page is basically capable
| | 00:52 | of displaying any one of
those ItemViewModel data objects.
| | 00:56 | So what we do is we use the page
navigation service to say we want to navigate to the
| | 01:01 | details page, and because Silverlight has
a history from a web environment, it uses
| | 01:07 | URIs and query parameters similar to the
way you would if you were doing web pages.
| | 01:12 | So in this particular case, we create a
query item of the name selectedItem, and we pass
| | 01:17 | it the SelectedIndex from the MainListBox.
| | 01:22 | When we get to the detail page, you'll see
that the detail page will take this index,
| | 01:26 | go back to the MainViewModel, and
extract the individual item that we want.
| | 01:30 | Finally, when the user taps on the screen to
select an item, it will highlight in whatever
| | 01:36 | the current theme color is for the phone,
but you want the highlight to turn off so
| | 01:41 | that when the user comes back to
the page, there's no item selected.
| | 01:45 | So in order to do that, we set the
SelectedIndex of the MainListBox equal to -1.
| | 01:50 | So this is how we start.
| | 01:51 | Let's go to the detail page and
see what happens when we get there.
| | 01:55 | Here on the DetailPage, we'll see the main
constructor, and we'll see a common method
| | 01:59 | that you'll use when you have multi-
page applications which require parameters.
| | 02:04 | In this case, you use the OnNavigatedTo method.
| | 02:08 | So we start out by saying let's figure out
what our selectedIndex is then we go to the
| | 02:13 | NavigationContext which is a class associated
with this page, we retrieve the QueryString,
| | 02:20 | and we use TryGetValue to see if we can
get a query parameter called selectedItem.
| | 02:25 | The reason we do that is because if someone
writes code navigates to this page and they
| | 02:31 | don't put the query string on, we
might want to do something else.
| | 02:35 | Notice that the result of TryGetValue is always a
string, so if we do get the value for selectedItem,
| | 02:41 | the first thing we have to do is to parse
it back into an integer so now we have an
| | 02:45 | index, and then we set the data context for
this details page equal to the App.ViewModel.Items
| | 02:53 | of that specific index.
| | 02:55 | And to see how it actually gets displayed, let's
take a look at the XAML, and we see two things.
| | 03:01 | One, we haven't yet changed the name of our
application on this page, that's something
| | 03:05 | you have to do on every single page.
| | 03:07 | It's not something that you can change
once and have it cascade all the way through.
| | 03:11 | So we're going to come up here and say
again, Edit > Advanced > Format Document, change the
| | 03:16 | text here to SONNETS.
| | 03:17 | You'll notice that we're not going to change the
name of the page because we have a different thing.
| | 03:22 | We have a TextBlock which has a ListTitle,
and that's going to be replaced by the LineOne
| | 03:29 | of our ItemViewModel instance.
| | 03:31 | So in this case, it will
be the number of the sonnet.
| | 03:33 | That's all we have to look at for how we
implemented the master-detail pages so far.
| | 03:39 | When the user is done, they click the Back
button and go back to the list of the sonnets,
| | 03:43 | and there's no selection in the
list box and they can try again.
| | 03:46 | So let's move on in the next movie to actually
loading our sonnets in and getting it to display
| | 03:51 | instead of the sample data.
| | Collapse this transcript |
| Loading external data| 00:00 | It's time to stop looking and start writing.
| | 00:03 | Let's bring in our ShakespeareSonnets and write
some code to be able to put it on the screen.
| | 00:09 | The first thing we do is come to the Solution,
come to the Sonnets project and Add a New
| | 00:13 | Folder, and we will call it Content.
| | 00:17 | Inside the Content folder, we will Add an
Existing Item for those of you with the exercise
| | 00:22 | files, that's going to be in the Sonnets_End folder
for this chapter, and it's called ShakespeareSonnets.xml.
| | 00:31 | Similar to the data we used for units
converter for images and so forth, we have to make sure
| | 00:36 | that this is content, so when we go the
Properties page, in this content but we need to make
| | 00:42 | sure it's says Copy always.
So it's actually gets included into our build.
| | 00:47 | We are done with properties, and now to
actually make this run, what we are going to do is
| | 00:52 | we are going to come down to the
MainViewModel and look at its LoadData method.
| | 00:57 | So we come down here, and we see the LoadData
method that came from the template which puts
| | 01:02 | scan data into the view model.
| | 01:05 | We want to put real life Shakespeare data
in it, so we are going to select comments
| | 01:08 | ahead of that method and entire
LoadData method, delete it and put our code in.
| | 01:15 | Let's take a look at what this does.
| | 01:17 | What it does is load the content of our
ShakespeareSonnets.xml into an XDocument, and you can see that the
| | 01:24 | XDocument has a little red squiggles underneath
it which means we need to add a new name space.
| | 01:29 | So let's go the top and
type using System.Xml.Linq.
| | 01:37 | you see from the red squiggle under Linq
that we don't have the proper assembly so let's
| | 01:42 | go to the Solution Explorer, right-click on
References, select Add Reference click here
| | 01:47 | to sort the list by name, and when it's in
ascending order, we will come down to the
| | 01:53 | bottom, and we will find System.Xml.Linq.
| | 01:55 | We will click OK and red squiggles go away
which means we have that code that we need.
| | 02:01 | So now let's scroll back
down to our LoadData method.
| | 02:05 | So we load the contents of the
ShakespeareSonnets.xml file into a XDoc.
| | 02:10 | Let's take a look what that file looks like.
| | 02:13 | Each sonnet has a number, an id, it has a
Roman numeral letter, and it has a body, and
| | 02:19 | that goes on for all 154 sonnets.
| | 02:22 | So in order to load this into our data structures,
what we do is select the Sonnets Descendants
| | 02:28 | so that we get all of the sonnet data, and
we are going to do for each loop, creating
| | 02:32 | a new instance of
ItemViewModel for each sonnet.
| | 02:36 | We create the instance, we set the LineOne
property equal to the Roman numeral character
| | 02:41 | of the sonnet that we extract from the XML.
| | 02:43 | Then we are going to go through, and iterate
through each line and the reason that we are
| | 02:47 | going to do that is because we need to do
two things and the LineTwo property of the
| | 02:52 | Item view model, we want to put first line
of the sonnet, and then the line 3 property
| | 02:57 | of the ItemViewModel, we want to put the
entire sonnet with lines 13 and 14 indented.
| | 03:03 | We have a counter to know which line we
are on, we have a string so we can accumulate
| | 03:07 | the body, and we go get each one of the line
elements inside the body and do before each over that.
| | 03:15 | We say, it was the first line, we set the
LineTwo property because that's going to show
| | 03:18 | up on our master page where we have the
roman numerals and the first line of the sonnet,
| | 03:23 | and then we say if the LineNumber is less
than 13, we simply put the line in as it is
| | 03:30 | if the line is 13 or greater, we put in the
line and an extra of couple of spaces in order
| | 03:34 | to indent those last two lines.
| | 03:36 | Finally, when we are done iterating over the lines,
we set the LineThree property of our ItemViewModel.
| | 03:41 | Now at the end here, we now have a new
ItemViewModle instance, and we added to the items collection
| | 03:48 | for this page so that we see all the items
in the main page list box and so we also have
| | 03:55 | those two extracts, remember over in the
details page we looked at the fact that it comes back
| | 04:00 | to this items property and extracts the
selected one to show on the details page.
| | 04:06 | So let's go ahead and give this a try and
voila, we have 154 sonnets, and if we come
| | 04:13 | down to our favorite sonnet and click on it,
there we go, Shall I compare thee to a summers
| | 04:18 | day? Right there in front of us.
| | 04:21 | Let's exit the app, and we need to do the
same two things here that we did at the end
| | 04:26 | of the unit's converter.
| | 04:27 | Let's add the above box,
and let's customize the icons.
| | 04:30 | We will come here, we will say add new items,
select Windows Phone Portrait Page call it About.
| | 04:39 | In this case we are going to use the same
code snippet we used for units converter and
| | 04:43 | change the title, like up here let's say SONNETS,
over the Solution Explorer and open the About
| | 04:53 | code and the same thing, you will select it,
we will use the code snippet, change the title
| | 05:01 | of the app Let's say SONNETS and change the
namespace here. And finally, we will come over
| | 05:10 | to the MainPage.xaml.
| | 05:12 | Now so far we haven't have any application
bar going on in this particular thing so we
| | 05:17 | are going to come down here, and we are going to
uncomment the application bar xml that's in the template.
| | 05:24 | We can do that by coming to
Edit > Advanced > Uncomment Selection.
| | 05:30 | We are going to delete the ApplicationBarIconbutton
elements because we don't have any of those,
| | 05:35 | and we are going to delete the two template menu
item ones and twos, and then add our codes in here.
| | 05:43 | Change this to the to say About sonnets. And
finally, we will come to our MainPage.xaml,
| | 05:51 | go to the bottom and add the method which we
actually invoke the About box, and we are good to go.
| | 05:59 | Let's give it one last run.
| | 06:02 | One of things that can happen to you when
you copy, code, end our xaml from another
| | 06:06 | projects and put it into a new project.
| | 06:09 | What happens is that our About.xaml up here
has the name of our namespace for our Class.
| | 06:15 | So for instead of UnitsConverter,
this needs to be sonnets.
| | 06:19 | Some of this is going to happen to your many
times as you move things around between projects.
| | 06:23 | I know it is the name space in
the code, have to be correct.
| | 06:27 | The name space in the xaml has to match.
| | 06:29 | Now if we try to run this Right now, we
would end up with some compile errors because we
| | 06:34 | change the xaml let's go over to the Solution
Explorer and right-click here and say Rebuild
| | 06:39 | Solution because that will allow
xaml and the code to get in sync.
| | 06:43 | So the compiler knows the
two of them are together.
| | 06:46 | So now when we run it, we will deploy off
here to the emulator, it was our sonnets,
| | 06:53 | here is our About box, and when we come back,
we can look and see there is our new icon,
| | 06:59 | which is the roman numeral for 154.
| | 07:02 | Now we are done with this app, and this is
what we are going to do with these one, we
| | 07:04 | will pin it to the Start menu.
| | 07:06 | So there now we are now done with app number two,
here in Windows Phone SDK Essential Training.
| | Collapse this transcript |
|
|
6. Implementing Persistence with Isolated StorageChoosing a multipage controller| 00:00 | Well, now that we have all 154 sonnets that
we can browse through and read, it might be
| | 00:06 | a good idea to be able to keep track
of which one of those are your favorite.
| | 00:09 | In order to do that, we need to have a control that
allows us to display multiple pages of information.
| | 00:15 | The Windows phone operating system
has two different ways of doing that.
| | 00:19 | Those two ways are called the
Panorama control and the Pivot control.
| | 00:22 | What you are looking at here is
the Panorama example application.
| | 00:26 | You can see here is a list of items, we
can swipe to the right, here is a second list
| | 00:30 | of items, there is a background image that
encompasses the entire thing, and if you watch
| | 00:35 | as it scrolls here, you can see that the
title up at the top scrolls at a different speed
| | 00:40 | than the text and the background
scrolls at a different speed than the list.
| | 00:44 | It's all designed to simulate
effectively in magazine format.
| | 00:48 | You can imagine one big wide magazine with a
single background image and different articles
| | 00:54 | or different chapters of an article underneath.
| | 00:56 | Typically, what's done with a Panorama
control and a good example of that is the pictures
| | 01:01 | hub on an actual Windows phone device is
that you are showing multiple lists of related
| | 01:07 | but separate information.
| | 01:09 | For example, the pictures you took on the phone
and the pictures your friends posted on Facebook.
| | 01:14 | Often times, the list of things in the Panorama,
when you click on them, will dive down into
| | 01:19 | another Pivot control which allows you to
show two different views on top of the same data.
| | 01:24 | And of course, you can come back to the Panorama and
go to a different section of the Panorama and so forth.
| | 01:30 | One thing that I do want to show you is that
if we look at the code for the panorama, and
| | 01:35 | the solution, we will see that there is a
panorama background image here, and if we
| | 01:40 | look at that you will see this as an entire
one wide, in this case 1024x768 pixel image
| | 01:46 | that the operate system automatically
scrolls underneath the pages in your panorama.
| | 01:51 | And Microsoft has said that you should have
no more than seven items in a panorama and
| | 01:56 | then use that to drill down.
| | 01:59 | For our sonnets application, it makes a
whole lot more sense than to use a pivot because
| | 02:04 | we want to show two different views on top
of the same list, you want to show all the
| | 02:08 | sonnets, and we want to
show the favorite sonnets.
| | 02:11 | So let's take a look at that.
| | 02:14 | And here is our sonnets plus application
which has all of the sonnets as we had before, and
| | 02:18 | it also has a page of favorites.
| | 02:20 | Now we haven't created any favorites yet,
so let's go look at a couple of sonnets and
| | 02:24 | say, oh, I like that, we have added an application
bar button down here, click it, and we get
| | 02:29 | a little gold star up there as well as when
we come back and look at the favorites list,
| | 02:33 | its now in the list.
| | 02:35 | Let's favorite a couple of more so you can
see not only that we can have multiple items
| | 02:44 | in the list that show what happens if we
decide that we have fallen out of love with this
| | 02:48 | particular one and say, no not that one anymore,
so we click the button again, the gold star
| | 02:53 | goes away, when we come back to the
list of favorites, it's not there anymore.
| | 02:56 | So again, as we talked about, this is a
pivot control, it has two separate list boxes in
| | 03:01 | it, one list containing all of our sonnets
and another list containing the ones that
| | 03:06 | we think are our favorites.
| | 03:08 | And on both pages, you can of
course go to the about page.
| | 03:11 | All right, that's what we are going to build.
| | Collapse this transcript |
| Preparing for persistence| 00:00 | To begin moving the sonnets application into a
multipage application using pivot with persistence,
| | 00:07 | we have started out and created a new solution
called SonnetsPlusFlatFile, and we have copied
| | 00:12 | over some of the things from the
Sonnets that we had built previously.
| | 00:15 | You have got the original ShakespeareSonnet
in xml form, we have added two images, one
| | 00:21 | is the star that shows up down in the application
bar so that we can choose a favorite, and
| | 00:25 | we have also added a yellow version of that
for use on the page which works in both the
| | 00:32 | light theme and the dark theme.
| | 00:34 | So we couldn't just use this image here, the
appbar.fav.rest.png because in the light theme
| | 00:41 | it wouldn't show up.
| | 00:42 | When you use an icon from the icons directory
in the application bar, the operating system
| | 00:46 | automatically switches it when you change
light and dark themes, and it doesn't of course
| | 00:50 | change it on your application content area
because you want to have full control over that.
| | 00:55 | So we took that, filled it in
with yellow and named it favorite.
| | 00:57 | We have also copied over the About page so
that we don't have to do that all over again,
| | 01:02 | and now what we are going to do is look at it,
we have also added a couple of references
| | 01:07 | because the way we are going to store our
list of sonnets is we are going to store it
| | 01:11 | in an isolated storage file as a flat XML
file and in order to do that we brought in
| | 01:16 | System.Xml, System.Xml.link
and System.Xml.Serialization.
| | 01:22 | We've also because we are going to be
building two versions of this app, one that uses a
| | 01:25 | flat file and one that uses the onboard SQL
CE database, we have made a couple of minor
| | 01:31 | changes to the WMAppManifest changing the
title of the app to Sonnets+FF and changing
| | 01:37 | the title of the large background icon
when you painted the homepage to Sonnets+FF.
| | 01:43 | All right, so the first thing we are going
to do is we are going to add a class which
| | 01:48 | is going to hold our data
that we are going to persist.
| | 01:52 | So we are going to add a new class, we are
going to call it Sonnets and in sonnets, we
| | 01:59 | are just going to create a collection of
properties because we are going to be serializing and
| | 02:03 | de-serializing this
information back and forth with xml.
| | 02:07 | So we have added an ID property which will
allow us to connect to the sonnet by number
| | 02:11 | which is different than the title property
which is the sonnet number in roman numerals.
| | 02:15 | We have also added another lines, the first
line property which is the first line that
| | 02:19 | shows up in that list box and then other lines
property which is all the rest of our sonnet,
| | 02:24 | and then finally a boolean to
say whether it's a favorite or not.
| | 02:27 | So the way we are going to do this in the
flat file version is we are actually going
| | 02:31 | to read and write all 154 sonnets to and
from XML, and when we want to create our list of
| | 02:36 | favorites, we will be looking at the boolean
flags iterating through the list of sonnets
| | 02:40 | to create a subset of our list.
| | 02:41 | Save that. Now we are going to come and add some code into
the main app, C# file, let's look at what we did here.
| | 02:52 | We first of all added some additional using
statements, for System.Io, System.Io.IsolatedStorage
| | 02:59 | and System.Xml.Serialization and so that we
can serialize the data back and forth using
| | 03:05 | a stream readers and writers, and text
readers and writers while we need the system.Io and
| | 03:10 | the System.Io serialization is so that we have
serialize and deserialize against the xml model.
| | 03:15 | So the name of our "database" here in isolated
storage is going to be "SonnetsWithFavorites.xml"
| | 03:23 | and in the app constructor after we go
through all the standard template stuff, we then say
| | 03:28 | we want to look and see if the database file "
exists", and if not, we are going to prepopulate
| | 03:34 | it with the contents of that ShakespeareSonnets.
xml which is in a format that is not exactly what
| | 03:40 | we want to use in this app and so instead
of just reading that and creating the view
| | 03:44 | model each time, we are actually going to, on
a one-time basis read that and create instances
| | 03:49 | of our sonnets class so that we
can shuffle it back-and-forth.
| | 03:53 | Isolated storage is essentially all the read/
write file system that exists on the Windows phone
| | 03:59 | device for you to save and load files.
| | 04:02 | The reason it's called isolated storage is
because the set of files and folders for each
| | 04:07 | app is isolated in the sandbox so that all
of your files in sonnets plus are separate
| | 04:13 | from all of the pictures in the picture hub,
are separate from all of the mail stored by
| | 04:18 | the mail application.
| | 04:20 | There is no way for one app to see the
contents of the isolated storage for another app.
| | 04:25 | In order to get access to the isolated
storage directory for your app, you have to use this
| | 04:29 | isolated storage file that
get user store for application.
| | 04:34 | So we go and get that, we do it in the using
statement so that it actually gets disposed of
| | 04:37 | at the end of the access to isolated
storage because the isolated storage implements I
| | 04:43 | disposable, and this is a good way
to have your app not leak memory.
| | 04:46 | So we go get access to the user store for
application, that's the isolated storage and
| | 04:51 | from there we can create files, delete files,
first thing we are going to do is use file
| | 04:56 | exist to see whether or not our database
file exist out there because when we want to do
| | 05:01 | this once, so we look and see if it exists,
if it doesn't we are then going to go and
| | 05:05 | create file, so you use open file, passing
the name and new System.IOFilemode.Create,
| | 05:11 | and you get a stream.
| | 05:14 | Then we have to have some data to put into
that stream and so we have a modified version
| | 05:18 | of the method we had in our view model
before that loads the ShakespeareSonnets.Xml file
| | 05:24 | into a observable collection
of item view model instances.
| | 05:28 | We'll look at that in just a second, but
that essentially looks like what our view
| | 05:31 | model looked like before.
| | 05:33 | Now we have this observable collection of
ItemViewModel instances, and we use the standard
| | 05:37 | XML serializer techniques
to write it up to the file.
| | 05:41 | We create a serializer from that, create a
text writer from the stream, serialize it
| | 05:45 | out and close everybody down.
| | 05:47 | Now we have this file and isolated stories
that anytime you need to load up the data
| | 05:52 | to put into a list box or to add favorite
or delete a favorite, we can use that file.
| | 05:58 | This LoadDatabase from XML as I said is
essentially identical to the implementation we had in
| | 06:04 | the main view model of the basic sonnets app
with difference being instead of taking the
| | 06:10 | items and adding them to the items collection of
the view model, we create a new ObservableCollection
| | 06:15 | of the items and at the end of the--as we
create each one, we simply add it to that items list.
| | 06:22 | We also go through and prepopulate the two
new things that we have added to the view
| | 06:27 | model, the SonnetId and the IsFavorite property.
| | 06:31 | We set IsFavorite property to false,
remember this is happening only when we are loading
| | 06:35 | the static data from ShakespeareSonnets.
Xml so we don't have any favorites yet.
| | 06:40 | And we then also set up to sonnetNumber so
that we can access things in this list by index.
| | 06:45 | So now we have looked at the solution that
we have got, we have added the sonnets class
| | 06:50 | so that we have a place to put our data
that we are going to store in isolated storage,
| | 06:54 | and we modified the App.xaml.cs file to
include a one time code to transfer our static data
| | 07:01 | from the ShakespeareSonnets.Xml file into
our file and isolated storage so that the
| | 07:06 | rest of our app has a known state to begin.
| | Collapse this transcript |
| Updating the data model| 00:00 | Okay. We've got our raw data transferred from
our solution from our ShakespeareSonnets file
| | 00:06 | into our IsolatedStorage.xml "database".
| | 00:10 | Now we need to change the data models to be
able to read and write that and create the
| | 00:15 | things that we need to
have for our Pivot control.
| | 00:18 | But before we get into that let's take a brief
look at what a Pivot control needs in terms of data.
| | 00:24 | So let's open up the Main XMAL, reformat and
what we're looking at here is the raw pivot
| | 00:31 | data from the template, but it will give
us a way of looking at what the structure of
| | 00:35 | it is so we understand what we've got to do.
| | 00:38 | So here we've got in our controls, we don't
have a grid at the top with our name of our
| | 00:43 | Application and the Title of the page,
instead we use the Pivot control that's where the
| | 00:48 | application goes, and there are
two PivotItems, one for each page.
| | 00:53 | Now obviously you can have more than two,
but for Pivot, you usually have at least two.
| | 00:58 | So let's take a look at what
it's inside of a PivotItem.
| | 01:00 | Inside of a PivotItem here we have a ListBox
that doesn't have to be what's in every Pivot,
| | 01:04 | but that happens to be what we're doing
because we want two Lists, one for all sonnets and
| | 01:08 | one for the favorite sonnets.
| | 01:10 | Again this ListBox in this case is bound to
the Items property of our MainDatamodel and
| | 01:16 | similar to the Windows data bound application
that ListBox.ItemTemplate has a StackPanel
| | 01:21 | in it with LineOne and LineTwo.
| | 01:23 | Now if we go look at PivotItem number 2 in
the default text that comes out of that of
| | 01:29 | the template, again they're binding to
the Items collection in the MainDatamodel.
| | 01:34 | When we look at our actual Pivot control,
you'll see we're going to binding to a separate
| | 01:38 | Items collection that way we get two
different views over the top of the same data.
| | 01:44 | Now let's go to the
MainViewModel and make some updates there.
| | 01:53 | Let's take a look at what we did here.
| | 01:55 | Again we added some code to access IsolatedStorage
because here is where we're going to go load
| | 02:02 | that SonnetsWithFavorites.xml and also write
it back when the user taps the star icon in
| | 02:09 | the application bar.
| | 02:10 | Because we now have two lists in our Pivot,
and we look at the actual structure of the
| | 02:15 | pivot just before we run the final app.
| | 02:18 | But we need two lists in our ViewModel,
because we need one for the ListBox of all items and
| | 02:22 | one for the ListBox of FavoriteItems.
| | 02:24 | So we created two ItemViewModel ObservableCollections,
we created an additional property in order
| | 02:30 | to be able to retrieve those FavoriteItems.
| | 02:32 | This is all the same for the ItemsProperty,
but we also added a new property to go along
| | 02:37 | with the INotifyProperty interface so that
when we update the Favorites, the list of
| | 02:44 | favorites automatically gets updated.
| | 02:45 | We saw that in run-through of the app that
when we clicked on the star and then used
| | 02:49 | the Back key to go back to the list of
favorites, it automatically was there, we didn't have
| | 02:54 | to do any code in order to be able to get that
Favorites updated because of the Silverlight data binding.
| | 02:59 | And now our LoadData is different because instead
of loading from the ShakespeareSonnets.xml,
| | 03:04 | we're not going to load
from our IsolatedStorageFile.
| | 03:07 | So we do something sort of in reverse
order for what we did for saving it.
| | 03:11 | We go create an
ObservableCollection to get all of our sonnets.
| | 03:14 | Once again we go GetUserStoreForApplication
to get access to the IsolatedStorage for this
| | 03:19 | app, and then we create an IsolatedStorageFileStream
in order to read it, but in this case, we
| | 03:23 | use OpenFile and use Filemode.Open.
| | 03:26 | And then similarly we create StreamReader
instead of a StreamWriter, another serializer,
| | 03:30 | and then we call
Deserialize to load the data in.
| | 03:34 | Once we've done that, we now have this ObservableCollection
of ItemViewModels and what we're going to
| | 03:38 | do is go through and populate our two lists.
| | 03:41 | If you remember, we have two
lists of items in our ViewModel.
| | 03:45 | One is our main items list and the other is
just a list of Sonnets that are favorites.
| | 03:50 | So we basically add everything to the main
items list and then look at the Favorite flag
| | 03:54 | as we are iterating over them to decide if
it should be added to the Favorites List.
| | 03:59 | The reason this has the red squiggly underneath
is because we haven't yet updated the ItemViewModel
| | 04:03 | which is the next thing we are going to do.
| | 04:04 | So this will automatically resolve itself.
| | 04:06 | And finally, we added two more methods here
which are called from the Details page when
| | 04:11 | the user taps the star icon to
set a favorite or delete a favorite.
| | 04:16 | So at that point, we'll see that when we
look at the code for that, the user taps that,
| | 04:20 | it comes back here to the MainViewModel and
says either add this particular item to Favorites
| | 04:25 | or remove it from Favorites.
| | 04:27 | And it simply uses the built-in collection
mechanism to add or remove, and because when
| | 04:32 | we loaded the data from the XML file, we
took the same instance of the ItemViewModel and
| | 04:37 | put it into both lists. We can use these
methods because essentially even though we
| | 04:41 | might have a list of all items with all 154
sonnets in it and a list of favorite items
| | 04:47 | with three sonnets in it.
| | 04:49 | Those lists are not two separate copies of
say sonnet number three, they both effectively
| | 04:54 | point to the same instance of an
ItemViewModel class that is sonnet number three.
| | 04:59 | Because we're implementing an instance of
INotifyPropertyChanged, we have to call NotifyPropertyChanged
| | 05:04 | to indicate that the favorites have changed, and
that's how the list gets automatically updated.
| | 05:09 | Finally, the very last method is how do we
actually update the database when somebody
| | 05:14 | makes a change? So the code in the Details
page, which we'll see in just a minute that
| | 05:19 | handles the tap on the star icon calls one
of those two methods to add or remove from
| | 05:24 | the Favorites list and
then calls UpdateDatabase.
| | 05:26 | Now UpdateDatabase is essentially the same
as what we did in the main app constructor
| | 05:32 | with one caveat which is that we delete the
file first and then write it all over again.
| | 05:38 | So we're not actually updating the XML file in
place we're simply writing it completely over again.
| | 05:43 | So while this is a reasonable thing to do
for 154 Shakespeare Sonnets, clearly this
| | 05:48 | would not scale to thousands of items.
| | 05:50 | But we simply delete the file, create it over
again and write it back, and that's over changes
| | 05:55 | to the MainViewModel and one more change to
the ItemViewModel to add a couple of properties,
| | 06:01 | and we'll be ready to start actually looking
at what the changes are to our Details page.
| | 06:05 | So let's open up the ItemViewModel and add
these two properties and the two properties
| | 06:11 | are called SonnetId and IsFavorite, and
because we implement INotifyPropertyChanged, we have
| | 06:20 | to as we do each set call
NotifyPropertyChanged for these particular properties.
| | 06:24 | So we've now taken our basic structure, we've
added a class of Sonnets.cs to hold the data
| | 06:30 | for our XML file, we've made some changes
to the App.xmal.cs to initialize the XML file
| | 06:38 | from the ShakespeareSonnets.xml on a one-time
basis, and we have made changes to the MainViewModel
| | 06:43 | and the ItemViewModel in order to support
two lists in the MainViewModel and in order
| | 06:48 | to support the additional properties we
need for the ItemViewModel namely the SonnetId
| | 06:53 | and the IsFavorite property.
I think we are ready to go.
| | 06:56 | Let's go on now and build the Details page and
get ready to make this app save our favorites.
| | Collapse this transcript |
| Creating the details page| 00:00 | If you remember back to our original sonnet
set, we had a details page, but all it allowed
| | 00:04 | you to do was look at the sonnet, and the
only way you could interact with it was by
| | 00:08 | clicking the Back button to go back to the list.
| | 00:11 | Here we need a details page that not only has the
XAML for putting the text of the sonnet on the screen.
| | 00:18 | We also need some code behind that actually
influences the functionality of the toggle
| | 00:22 | favorites button, and so we're going to
add a new details page to our solution.
| | 00:27 | Also note that we created this solution
using the pivot application template, which gave
| | 00:32 | us only a main page and not a details page.
| | 00:35 | It's not every pivot
application has a details page.
| | 00:39 | But here we are going to add a new item, I
am going to put a Windows Phone Portrait Page.
| | 00:43 | I am going to call it DetailsPage, and in XAML
what we're going to have in there, looks like this.
| | 00:54 | It has our title for our application.
| | 00:57 | The text block at the top now has the word
sonnet, because we're also going to put the
| | 01:01 | sonnet number in there.
| | 01:03 | We also have an image control, that you can
see by default has an empty string for the
| | 01:08 | source property which makes it transparent.
| | 01:10 | And when the sonnet has a favorite, will put
images/favorites.png, to make our gold star show up.
| | 01:16 | Lastly, we've added down here in the ApplicationBar,
a menu item with that appbar.favs.rest.png
| | 01:26 | image and also the Text of Favorite and a
Click-handler called toggleFavorite, which
| | 01:32 | will now go and add to the code.
| | 01:40 | So let's take a look at what the
code behind our DetailsPage is.
| | 01:43 | So we can now see what it is we need to do.
| | 01:46 | So, as before we have our ItemViewModel
for the item, and we have our OnNavigatedTo.
| | 01:54 | But now our OnNavigatedTo
method needs to do a little more.
| | 01:57 | First, we go to see if we have a
selectedItem, which we always should have.
| | 02:01 | Then we parse it back into an integer.
| | 02:04 | We are going to see if we have another
query item that we add to the code that handles
| | 02:11 | selection from the favorites list or the all list,
which recalled from favorites, and we go to
| | 02:17 | see if we've got that.
| | 02:19 | So that we know that if the fromFavorites
is set to 1,that we need to extract from our
| | 02:24 | FavoriteItems in the ViewModel
versus the regular items in the ViewModel.
| | 02:30 | Once we've got our item we also keep track
of the sonnet number, and finally we need
| | 02:35 | to look at the IsFavorite property of that
item that we just got to determine whether
| | 02:39 | or not the URI for the image should be Images/
favorite.png or it should be left at the empty string.
| | 02:45 | The second thing we've added here is this
toggleFavorite_Click method, which handles
| | 02:50 | the event when the user taps on
the star in the ApplicationBar.
| | 02:54 | First, we'll see that we have a Debug.
WriteLine here, as we were building this app
| | 02:59 | we wanted to know that we actually got the
right one. And as you probably already know
| | 03:05 | the way to get access to that debug stuff
is to add System.Diagnostics to your usings,
| | 03:11 | and then you can use this, and it will come
out in the output window of your Visual Studio
| | 03:16 | as you're running the app.
| | 03:18 | So what toggleFavorite does is it goes,
gets our current item, toggles the state of
| | 03:22 | that favorite boolean, and then we
look at what is the new state of it.
| | 03:28 | So if it means it's now a favorite, we set
the image source of our favorite image to
| | 03:33 | the favorite PNG so that the gold star shows up.
| | 03:36 | And then we go back to the
MainViewModel and call AddItemToFavorites.
| | 03:40 | So now this item will get added to our
Favorites collection, and because that's databound to
| | 03:46 | the list box in the Favorites section of
the pivot, it will automatically get updated.
| | 03:51 | Similarly, if it's no longer a favorite, we
falling out in love with that particular sonnet.
| | 03:56 | We set the FavoriteImage.Source back to the
empty string, and we go back to the ViewModel
| | 04:00 | and call RemoveItemFromFavorites so that it
gets removed from that list, again data-binding
| | 04:05 | will take it out of the actual list box.
| | 04:07 | And either way, whether or not this is a
new favorite, or you know an old song that we
| | 04:13 | no longer care about, we call
UpdateDatabase which will take our collection of sonnets
| | 04:17 | along with its favorite flags and
write it back out to the isolated storage.
| | 04:21 | Next step, we're going to make the changes
to our main page to actually put our version
| | 04:26 | of the lists into the pivot control,
and then we will be ready to run.
| | Collapse this transcript |
| Bringing it all together| 00:00 | So we still have to update the standard pivot
template XAML and code to put in our all and
| | 00:07 | favorites list and bring it all together so that
we can actually run this puppy. So let's do that.
| | 00:13 | Come here to the Solution we'll open up the
MainPage.xaml, and we'll substitute our version
| | 00:18 | of this and then take a look at it.
| | 00:24 | You can see we've titled our pivot control
SONNETS PLUS, and we have set the title of
| | 00:29 | our first PivotItem to all.
| | 00:32 | And we've bound that particular thing to the
items collection of our main ViewModel, and
| | 00:37 | we use the FirstListBox_SelectionChanged
handler to handle tabs in the all list.
| | 00:44 | If we go look at the second PivotItem,
here is our second PivotItem, and it is titled
| | 00:50 | favorites, and we bound it to the FavoriteItems
collection on our MainView model, and we have
| | 00:56 | a SecondListBox_SelectionChanged event
handler to handle tabs in the favorites list.
| | 01:01 | If we go over here to the code, let's
take a look at what we changed here.
| | 01:12 | So here's our FirstListBox_Selection handler.
| | 01:16 | This looks just like the ListBox_
SelectionChanged in the basic sonnets app.
| | 01:20 | And you see that we just pass selectedItem
as a query parameter to our DetailsPage.
| | 01:27 | That indicates that this came from the all list.
| | 01:30 | If we look at the SecondListBox_SelectionChanged
event handler, you'll see that we not only
| | 01:35 | interact with the SecondListBox, and we
pass the selectedItem, you see we've added this
| | 01:40 | fromFavorites query parameter so that the
DetailsPage knows to retrieve the selectedItem
| | 01:45 | from the favorite items collection on the
main ViewModel, not the items collection on
| | 01:50 | the main ViewModel.
| | 01:54 | And that's it, of course we have our About
_Click as we had in the main sonnets app.
| | 01:58 | We are ready to rock and roll.
Let's save all this and see it in action.
| | 02:08 | All right, there we go.
Here's our pivot control.
| | 02:12 | You can see we've got two lists on our
pivot, here is our list of 154 sonnets.
| | 02:16 | Here is our list of our favorites
which has nothing in it right now.
| | 02:20 | So let's go down and pick our favorite
sonnet, once again to a summer's day.
| | 02:27 | And you can see we now have the word sonnet,
and we've got the Roman numerals for the sonnet,
| | 02:31 | and this isn't favorite yet,
because there is no gold star.
| | 02:34 | We tap the app bar icon, and look now there
is a gold star, and when we go back, we'll
| | 02:40 | see of course it still remains in the all list, but
now the favorites list has our favorite sonnet in it.
| | 02:47 | Let's go back to the all list and pick a
couple of others, add them as favorites.
| | 02:56 | And if you go over to our favorites list,
you can now see we've got three favorites.
| | 03:00 | Well, let's say that sonnet XIII, we've just
fallen out in love with you, it just doesn't
| | 03:04 | speak to us anymore.
| | 03:06 | We come back over here, we click the toggle
favorites button, the gold star goes away,
| | 03:11 | and when we go back to the list,
it's gone. Just the way we want it.
| | 03:15 | What we've seen here is that we have now a
way of dealing not only with persistent data,
| | 03:20 | in this case we use a flat XML
file inside isolated storage.
| | 03:25 | We also have seen how we can show multiple
views on the same list using the pivot control,
| | 03:30 | and we've shown how we can use query parameters
being passed to a page to change the behavior
| | 03:35 | of the page, in this case the way the DetailsPage
determines whether it picks up the selected
| | 03:39 | sonnet from the favorites
list or from the all list.
| | 03:43 | We're done with flat files and isolated storage.
| | 03:46 | Next up we are going to convert this same app
to work with a database in isolated storage,
| | 03:51 | which will be slightly different because we
don't have to read and write the entire thing,
| | 03:54 | we can update an individual
sonnet one at a time.
| | Collapse this transcript |
| Cloning a Windows Phone app| 00:00 | Continuing on with our work in persisting
data to isolated storage, let's convert the
| | 00:06 | Sonnets app from using a flat XML file
into using the onboard SQL CE database.
| | 00:13 | In order to get ready to do that work we're
going to do something that I do all the time,
| | 00:18 | and something probably you'll need to do,
which is to take an existing running Windows Phone
| | 00:23 | app and copy it--a.k.a. clone--it and
change the name and make it a new app.
| | 00:30 | There are number of steps involved, so let's
go through them one by one, and then we can
| | 00:34 | verify that we have the new app under the
new name, properly running in the emulator
| | 00:39 | before we start making changes.
| | 00:41 | Step number one is to open up the directory
containing all of your source code files which
| | 00:47 | probably still also contains a
Bin directory and an obj directory.
| | 00:53 | No matter what you do in changing all these
source code files and rebuilding the solution,
| | 00:58 | if you don't delete these two directories
first, the emulator and the device are not
| | 01:02 | going to load your code,
so I'll delete those guys.
| | 01:08 | Now we will go up one level, and we'll open
up the solution and start the renaming process.
| | 01:16 | If we look in the code we'll see that we
have a namespace of SonnetsPlusFlatFile.
| | 01:22 | If we look in the WMAppManifest, we'll see
we have Sonnets+FF and number of other changes
| | 01:30 | that we need to make.
| | 01:32 | So let's go to the Edit menu and select Find
and Replace and select Replace in Files, and
| | 01:37 | let's find SonnetsPlusFlatFile and replace
it with SonnetsPlusDB, and be sure to open
| | 01:46 | the Find options and select Look at these
file types, and make sure you have *.* selected.
| | 01:52 | That way it will find all the
instances of SonnetsPlusFlatFile.
| | 01:56 | We'll do the Replace, and you should get 17
occurrences replaced if you're following along
| | 02:03 | with the end of the code from the last movie.
| | 02:07 | Now we can close this Find
and Replace, that's part of it.
| | 02:12 | Let's next rename the project SonnetsPlusDB, and
let's rename the Solution, again to SonnetsPlusDB,
| | 02:26 | and then let's open up Project Properties.
| | 02:32 | Here we're going to find a number of things
that still say SonnetsPlusFlatFile, because
| | 02:36 | Find and Replace can't
find and replace inside here.
| | 02:40 | So again, we'll change this to DB, and this
to DB, and you will notice the Startup object
| | 02:48 | is no longer selected, but if we click on
this, here is the SonnetsPlusDBApp, which
| | 02:53 | is the one we want.
| | 02:54 | And let's also change the name of the Xap
file, SonnetsPlusDB and then change the Title
| | 03:01 | to Sonnets+DB and the title token for the
Tile, once again to Sonnets+DB, and let's
| | 03:09 | take a quick look inside Assembly Information.
| | 03:12 | Our Search and Replace got that,
since that was in the assembly info.cs.
| | 03:16 | So now we can save and close this, and we
need to go take one more look at WMAppManifest,
| | 03:24 | and let's make sure that that's in a
state where we can see all the properties.
| | 03:28 | So you see we've already changed because of
the Project Properties dialog, here Sonnets+DB
| | 03:35 | and here is Sonnets+DB.
| | 03:37 | But let's also go ahead and change the Author to
SonnetsPlusDB author and the Publisher to SonnetsPlusDB.
| | 03:46 | And finally, there's one more crucial thing
that we have to do, and that is we have to
| | 03:50 | change this ProductID GUID.
| | 03:53 | Because if you have the ProductID GUID as we
used for Sonnets+FF, the emulator or device
| | 03:59 | will not even load the app on the device.
| | 04:01 | So we'll delete that, and
now we need to generate a GUID.
| | 04:03 | So we have got two options to do that.
| | 04:06 | If we look at our Windows Explorer here, the
Windows 7 SDK includes a tool you're probably
| | 04:13 | familiar with called guidgen.
| | 04:14 | That's what we're going to use.
| | 04:17 | Go ahead and run that and select Registry
Format, select New GUID and Copy, and then
| | 04:23 | we'll go back to Visual Studio and paste it in.
| | 04:27 | If you don't have guidgen, which is found
in the Program Files Microsoft SDKs Windows
| | 04:35 | v7.0A Bin directory.
| | 04:39 | You could also go to the Windows Phone Marketplace,
and as we can see here--at least at the time
| | 04:43 | of our recording--there were five free
applications that will also generate your GUID.
| | 04:50 | All right! That's all that we need to do in
order to be able to clone a Windows Phone App.
| | 04:56 | Now since we're also cloning Sonnets+SF into
Sonnets+DB, we want to make one more change,
| | 05:02 | and that's in the string in the About box,
down here where we have the emailTask.Subject,
| | 05:07 | so let's change that to DB also.
| | 05:13 | And now let us just say a sure to wish
to the clone gods, and we'll press F5.
| | 05:23 | This is what happens when we screw something up.
| | 05:27 | When we have an app that has all of the things
that are supposed to be changed, changed it just runs.
| | 05:33 | In our case, we clearly missed something,
so the way you know that it misses something
| | 05:39 | is that it actually can't find the current
app in order to change the IdleDetectionMode.
| | 05:45 | So let's stop and take a look and figure
out what we missed and then fix that up.
| | 05:51 | So our first thing to do is once again try
to delete the Bin and obj directories and
| | 05:57 | see if that fixes it.
| | 05:58 | So let's go back to Windows Explorer, once
again, we'll delete the Bin and obj directories,
| | 06:07 | and we'll close this, and
we'll give it another try.
| | 06:15 | All right, we didn't stop there.
| | 06:17 | The Emulator saying Hello, woo-hoo! We have
now successfully renamed our app and cloned
| | 06:23 | it, and we can prove that by coming back here and
seeing there's a Sonnets+DB in the Application list.
| | 06:29 | We are going to have to remember to change the icon
there so we can visually differentiate the two of them.
| | 06:34 | We've now successfully cloned
SonnetsPlusFlatFile into Sonnets+DB.
| | 06:40 | So we're ready to move on and start looking
at actually these onboard SQL CE database
| | 06:47 | to read and write our data.
| | Collapse this transcript |
| Using SQL CE| 00:00 | Now that we've cloned our SonnetsPlusFlatFile
solution into a SonnetsPlusDB solution, let's
| | 00:07 | talk about the overall architecture
of reading and writing to the database.
| | 00:12 | Microsoft on Microsoft Developer Network or
MSDN has a great article just recently published
| | 00:18 | called Local Database Overview for Windows
Phone, and there's lots of nuanced detail
| | 00:23 | in there which you'll probably want to
review after you complete this section.
| | 00:28 | Well, what we're going to talk about right
now is just the architectural considerations
| | 00:32 | on how we're going to connect up as database to our
lists, which are done with Silverlight Data Binding.
| | 00:39 | So the way that's connected you can see over
here in the blue square inside Isolated Storage
| | 00:45 | you can now have SDF files,
which are SQL CE database files.
| | 00:51 | The orange arrow in the middle there says that
you use LINQ to SQL to talk to that database,
| | 00:56 | and the way in which you use LINQ to SQL
is the System.Data.Linq namespace has a Data
| | 01:03 | Context object which implements the same
kind of data context functionality required for
| | 01:08 | the Silverlight data binding.
| | 01:10 | So what we're going to do is we're going
to add a reference to that System.Data.Linq,
| | 01:15 | and then we're going to go ahead and start
converting the bits and pieces of our Sonnets+DB
| | 01:22 | application to use the database.
So now let's open Visual Studio and get started.
| | 01:27 | First-order of business is to open the
Solution Explorer, open up the References, and add
| | 01:32 | a reference to System.Data.Linq, because that's what
we need in order to be able to talk to the database.
| | 01:37 | Come down there.
There we are, System.Data.Linq.
| | 01:41 | Now the next we're going to
do is go to our Sonnets class.
| | 01:45 | Now this is our Sonnets
class in the FlatFile version.
| | 01:48 | You can see we simply have a connection of properties
that we used to read and write data from the XML.
| | 01:54 | When we convert that to the database version,
it looks very similar except that there are
| | 01:59 | number of attributes associated with each item.
| | 02:02 | First of all, we edited a couple of additional
using statements in order to be able to bring
| | 02:06 | in the assemblies that support these attributes.
| | 02:09 | And then this is the equivalent of the
DDL to define the structure of the database.
| | 02:14 | We start out by saying Sonnets is a Table
in the database, and we define each one of
| | 02:19 | our properties as a column.
| | 02:21 | Now because this is a database, and we want
to be able to do queries against it, we also
| | 02:26 | want to have a Primary Key and so this
collection of stuff right here is all the magic linq
| | 02:34 | stuff that says that we want this
Column SonnetId to be a primary key.
| | 02:39 | We want the database to generate it for us,
and we want the database type to be Integer,
| | 02:43 | not Null, and we want it to be an Identity
column, which means it's got to be a unique value.
| | 02:49 | We said CanBeNull = false, because there is
no point of having a primary key that's null,
| | 02:54 | because again we search on it.
| | 02:55 | And then we say AutoSync = AutoSync.onInsert,
which means that when we insert something
| | 03:03 | that's when the initial value
of the primary key is generated.
| | 03:06 | But beyond that, our properties look the same, other
than they say that they are now Columns in the database.
| | 03:12 | So this is, in terms of the
database setup, all that we need to do.
| | 03:16 | We don't need to open up the SQL Server
Explorer and go through the wizards and dialog boxes
| | 03:22 | and grids in order to be able to create the
data--especially because this data is being
| | 03:26 | created in the SQL CE database on the phone
inside your app's private isolated storage.
| | 03:33 | So we'll Save that, and now we need to be
able to connect that table definition to the
| | 03:41 | database using a database context class.
| | 03:43 | So we'll come back to the Solution Explorer and Add
a new Class, and we'll call it SonnetsDBDataContext,
| | 03:55 | and we'll fill that in.
Here is what we got.
| | 03:58 | We've got some using statements
which are similar to what we had before.
| | 04:03 | We've System.Data.Linq and System.Data.Linq.Mapping, and
we've a class which implements the System.Data.Linq.DataContext.
| | 04:14 | It only has two things in it, one of them is
a declaration of a property which represents
| | 04:19 | the Table which is the type table of T, and
that specifies items so that we can use the
| | 04:25 | existing data binding, because
we're going to be using items.
| | 04:29 | And the constructor, which is because this
is a System.Data.Linq.DataContext also has
| | 04:35 | to have a connection string, and we've to pass the
connection string to the base class during construction.
| | 04:43 | Now the ItemViewModel is going to remain the
same, but we need to make a few more changes
| | 04:47 | to the App.xaml.cs in order to be able to
support the initial process of using the database.
| | 04:54 | So here is what we're going to
actually start accessing the database.
| | 04:58 | Now let's take a look at what we've got.
| | 05:02 | If you remember back in the previous version
we had a DBName property, well that's gone now.
| | 05:09 | We have replaced that with a
DBConnectionString property.
| | 05:12 | And since this is actually SQL, it needs to say
Data Source=, and then you see here, isostore:/.
| | 05:20 | So this is a specific string format that tells
the database that the connection is in a database
| | 05:26 | and in the Isolated Storage.
And in our case, we called it Sonnets2.sdf.
| | 05:32 | Whatever databases you create
have to have a file extension of SDF.
| | 05:37 | Then in order to be able to connect to this
data context from other parts of the application,
| | 05:41 | we define a private instance variable of type
SonnetsDBDataContext, which we've just looked
| | 05:47 | at, and a property getter and setter that
allows us to know that we need to actually
| | 05:53 | you do the construction in the first time we
access this and pass in the Database Connection String.
| | 05:59 | If we look at the rest of App.xaml.cs, most
of it is the same as we've seen before except
| | 06:05 | at the beginning of the App Constructor we
initialize a variable of type SonnetsDBDataContext
| | 06:12 | and call our property in order to actually
instantiate the database, and we'll use it
| | 06:17 | down here a little bit further on, and just
as we did before, you need to determine whether
| | 06:22 | the database has been pre-populated
by the Shakespeare's Sonnets.xml file.
| | 06:27 | Here unlike in SonnetsPlusFlatFile, we use
the database Data Context in order to be
| | 06:33 | able to query whether the database exists
rather than the isolated storage manager and
| | 06:40 | trying to see whether the file exists.
| | 06:42 | So we first ask the System.Linq.DataContext
whether the database exists.
| | 06:49 | If it doesn't exist, then we create it with
this db.CreateDatabase, that does introspection
| | 06:56 | over the table class and actually creates the
table in the database with all the appropriate types.
| | 07:01 | Then just as we did before--and this method
hasn't changed--our LoadDataBaseFromXML which
| | 07:06 | reads the Shakespeare sonnets.xml and
creates an observable collection of ItemViewModel.
| | 07:11 | And then instead of taking that and writing
about as a serialized XML file, we're going
| | 07:16 | to iterate over the collection of ItemViewModel
instances and ask the database to insert the items.
| | 07:24 | But it Inserts them OnSubmit.
| | 07:26 | So what happens here as we say Database.Items.InsertOnSubmit,
and we create a new instance of that Sonnets
| | 07:33 | class that has the data that we want--the
one that was annotated by the attributes that
| | 07:39 | describe the columns and their data types.
| | 07:42 | You notice because we're using the default
values, we don't set the SonnetId. That's the
| | 07:49 | primary key which is auto generated, and we
don't need to set the IsFavoriteValue because
| | 07:54 | it defaults to false.
| | 07:56 | So we say db.Items.InsertOnSubmit, we create
a new instance of sonnets, fill it in, and
| | 08:03 | when we're all done with that, then we say
db.SubmitChanges, and that actually takes
| | 08:09 | all of those objects that were in the ObservableCollection
and writes them out to the database.
| | 08:15 | As always depending upon the size of the
data that you're dealing with and the amount of
| | 08:19 | memory in the device that you're
dealing with, it works great for 154 sonnets.
| | 08:24 | If you had 10,000 U.S. Census data items, you probably
would want to call dbSubmitChanges earlier than at the
| | 08:32 | end of calling InsertOnSubmit 10,000 times.
| | 08:35 | So now we've the database set up, we've got
our Sonnets class with the proper attributes,
| | 08:41 | we've got our DBDataContext class all set up,
and we've seen the first instance of accessing
| | 08:47 | and writing data to the database.
| | Collapse this transcript |
| Updating the data model| 00:00 | Surprise, surprise! Here we find
ourselves in Visual Studio again.
| | 00:04 | Let's update the data model now to have it
access to database to do the querying to
| | 00:09 | build our initial set of items and to
implement the logic we need for the details page.
| | 00:15 | So move over here is the Solution Explorer,
open up the MainViewModel.cs, and put our new
| | 00:22 | version in and see what we've changed.
| | 00:29 | To start with, we have a local intense variable,
we're going to hold the Sonnets dbDataContext.
| | 00:34 | And in our MainViewModel Constructor we're
going ask the App class for the instances of
| | 00:40 | the database that we've created there. Also as
we did before, we're going to create art to
| | 00:44 | ObservableCollection of ItemsViewModels for
items and favorite items. All that remains the same.
| | 00:52 | What's going to change now is
the logic inside load data.
| | 00:56 | So instead of looking at the data that we
got from XML--which is what we did before--we're
| | 01:02 | simply going to query the
database for the Sonnets.
| | 01:05 | So the way you do queries using the SQL is
to simply say var sonnetsInDB equals from
| | 01:13 | sonnets, variable S, in dbDataContext.Item--remember that
was the table we defined over layer in dbData Context.
| | 01:22 | Select this and so that the equivalent of
select star from Sonnets in the database.
| | 01:29 | And now that we have that, we're going to
create an observable collection of those sonnets
| | 01:33 | in order to be able to iterate over them
and create our ItemViewModel, and we'll simply
| | 01:38 | then company properties from the Sonnet
Objects into the ItemViewModel objects.
| | 01:44 | And then we added to the items list and
again to the favorites list if it is a favorite
| | 01:49 | sonnet, and that's all we need to do
to love the data from the database.
| | 01:52 | You can also see that add item to favorites
and remove items from favorites are the same
| | 01:58 | as what we use for the flat
file version of Sonnets plus.
| | 02:02 | But you might notice that the update database
method is missing, and that's because we're
| | 02:07 | going to use link to SQL over in the
details page in order to do the actual updates.
| | 02:13 | We don't need to do the updates here
because we're not managing the XML file anymore.
| | 02:18 | So let's move on to updating the details page
and fire this puppy up and see if it runs.
| | Collapse this transcript |
| Querying and updating the database| 00:00 | We've got two last things to do before we fire
this up and see it running against the database.
| | 00:06 | First we're going to update the DetailsPage,
then we're going to update the icon, and we're
| | 00:09 | going to give it a try.
So let's go over to the Solution Explorer.
| | 00:13 | I'll open up the CS code-behind
file for the DetailsPage.
| | 00:17 | XAML doesn't change any between the flat file
version and the database version of sonnets plus.
| | 00:24 | So we'll put in the new version and
take a look and see what we changed.
| | 00:30 | First we add a reference to System.Linq
because we need to be able to do it LinkQuery and
| | 00:37 | then OnNavigatedTo method it's
still the same as it was before.
| | 00:43 | But our toggleFavorite_Click handler is going
to be different, because here's where we use
| | 00:48 | things differently between
the XML and the database.
| | 00:51 | So first, when the user taps on the Toggle
button, we need to be able to go find the sonnet
| | 00:56 | in the database because
that's what we want to update.
| | 00:59 | So we do that with a little bit more
sophisticated query than we did before.
| | 01:04 | Because now we don't want to get all the sonnets
in the database, we only want to get the sonnet
| | 01:08 | that matches the one we're actually looking at.
| | 01:11 | So again, pretty standard link to SQL, from
Sonnets matchingSonnet in db.Items, now we
| | 01:18 | have a where clause, where matchingSonnet.SonnetId
is equal to ourItem.SonnetId, and we select it.
| | 01:25 | Now because we're doing an exact query here,
and we know that SonnetId is a system-generated
| | 01:31 | identity key, we know that there is only one
possible answer, so we call ourRow.First to
| | 01:37 | get access to the sonnet.
| | 01:39 | And just to prove to ourselves that we
retrieved the right item from the database, we'll put
| | 01:44 | in this Debug here to make sure that the
SonnetId we retrieved is the one we're expecting.
| | 01:49 | Same logic as we had before about the toggling
except that we now want to toggle not only
| | 01:54 | our item, which is ItemViewModel instance
which is related to what's on the screen.
| | 01:59 | We also want to toggle IsFavorite property of
the Sonnet object which is what's in the database.
| | 02:05 | So all we have to do is toggle that properly
and call db.SubmitChanges, and that changes
| | 02:11 | the database. We didn't have to do anything
other than an initial query, change the property
| | 02:16 | and submit changes, and that writes it back.
| | 02:18 | And of course the rest of this is the same as
before, meaning we update the AddItemToFavorites
| | 02:23 | or RemoveItemFromFavorites in order to get our favorites
list in the second part of our pivot to update.
| | 02:30 | And because we did this db.SubmitChanges here,
we no longer have to go and call the MainViewModel
| | 02:37 | and tell it to update the database,
a.k.a. write the XML file back out.
| | 02:42 | That's the end of the code changes.
Now let's do the really hard work.
| | 02:48 | Open up that icon and set this one to a little
lighter green, so I have three different versions
| | 02:58 | of this icon, one for each
version of this app that we built.
| | 03:03 | That's the ApplicatioIcon, here's the
Background, and pick the same light green, our favorite
| | 03:10 | paint bucket, boom, boom and save that,
don't forget now to do a Rebuild Solution.
| | 03:17 | Since we changed the icons we need to make
sure that you've done, and let's give it a try.
| | 03:24 | Before we do that, let's make sure that
we don't already have an instance of that
| | 03:28 | app, which we do. Let's get rid of that, because
we want to actually see the process of creating
| | 03:36 | the database, and now let's run it.
| | 03:49 | And we can see here in our Output window we
didn't find the database, so we initialized it
| | 03:54 | from the XML, which means that we're going
to have all of our Sonnets, but we won't have
| | 03:59 | any favorites, and let's come
down here and pick a Sonnet.
| | 04:05 | Once again, the beautiful summers day here, and
when we tap it we've now updated the database.
| | 04:11 | So what happens is we printed out this line,
Toggle Favorite for :XVIII, and it shows that
| | 04:17 | we actually did retrieve item 18
from the database and updated it.
| | 04:22 | And we can tell that because we come back
here, and it's in our favorites list, and
| | 04:27 | it has our gold star on it, meaning
we like this Sonnet, and that's it.
| | 04:32 | So it was just a quick review, we cloned our
application, we went through all the steps of doing that.
| | 04:37 | We built a database object, our Sonnets.cs in which
we added all the attributes here, we decorated
| | 04:47 | this object in order to
make it a database table.
| | 04:51 | And we build our SonnetsDBDataContext
object which has a constructor for connecting us
| | 04:56 | to the database and an items instance variable
telling the database what kind of information
| | 05:02 | the database is going to store.
| | 05:04 | We also updated our MainViewModel, to go
and retrieve the data from the database here,
| | 05:13 | to get our items to display in our list boxes,
and then finally we updated our DetailsPage.xaml
| | 05:21 | in our toggle method down here to query the
individual item that we wanted the individual
| | 05:27 | Sonnet from the database and updated and
called db.SubmitChanges to write it back.
| | 05:31 | Well, this was a non-trivial process
to convert from flat file to database.
| | 05:36 | You can see that the process of using the
database on Windows phone devices is very
| | 05:42 | easy and very quick to implement using Linq
to SQL and the SQLCE features that are there.
| | 05:51 | And finally, let's go back to our Emulator,
and let's pin our application to the Start
| | 05:59 | menu, and now we can see how far
we've come since we started the course.
| | 06:02 | We built our Units Converter and three
different versions our Sonnets application, Illustrating
| | 06:07 | Pivots Isolated Storage or Flat Files
and Isolated Storage for the database.
| | Collapse this transcript |
|
|
7. Capturing the WorldWorking with the camera| 00:00 | Every Windows phone device has sensors to
be able to capture the world around you.
| | 00:05 | There is an image sensor which enables implementation
of Camera capability, it has a GPS radio which
| | 00:13 | implement location awareness capability,
and it has an Accelerometer which enables you
| | 00:18 | to determine when the device is actually moving.
| | 00:21 | So let's look and how you use each one
of these three capabilities in order.
| | 00:25 | At first we'll look at the sample
application, and then we'll dig into the code.
| | 00:29 | So first we look at the Camera, and the Camera
is connected by something called the Camera Task,
| | 00:35 | and when we launch it, the Camera shows up.
| | 00:38 | Now in the Windows phone emulator all you
see is the sample camera user experience.
| | 00:44 | But there's no actual Camera connected to
the emulator and the emulator does not use
| | 00:48 | any camera connected to your development system.
| | 00:52 | And in fact, regardless of how we set these
settings, when we take a picture and accept it,
| | 00:57 | you always get back this white square with a
red square with a little green square inside
| | 01:02 | of it as the image coming back from the Camera.
| | 01:05 | If you connect this up to an actual Windows
phone device, there is yet another wrinkle
| | 01:10 | which is that you can build this app,
download it to a Windows phone device,
| | 01:14 | but if you tap the Launch Camera Task button
while your device is still connected to your
| | 01:19 | development PC, the Camera
itself doesn't actually run.
| | 01:23 | So the only way you can actually take
pictures and get the results is by running it on a
| | 01:28 | device which is not tethered
to your development system.
| | 01:32 | Next we look at the GPS, and we can start
tracking location. Now as we saw before in
| | 01:39 | the Device Capabilities chapter, there is a
simulation for the location built into the emulator.
| | 01:45 | So we can come back here to Useless Bay and
say that's where we are, or we can go to Everret.
| | 01:51 | You can see the numbers over here Longitude
and Latitude updating, or we can come over
| | 01:55 | to another favorite place of mine, Post Townsend.
| | 01:58 | And then finally, we look an Accelerometer,
if you remember in the Device Capabilities
| | 02:03 | movie we looked at Accelerometer
and move this guy around like so.
| | 02:06 | Now we can actually see
what's happening there within code.
| | 02:09 | So we'll Start Tracking, and as removed the
similar device, you can see over on the emulator
| | 02:15 | the numbers are changing and they match the
numbers that we have here at the bottom of the
| | 02:19 | Accelerometer user controls that
allow you to simulate the movement.
| | 02:22 | All right, that's the sample app, now let's dig
into the code behind the Camera Task Launcher.
| | 02:29 | So we'll fire up VisualStudio, and we're going
to take a look at this sample implementation
| | 02:33 | of Camera GPS and
Accelerometer that we just looked at.
| | 02:37 | To start with what we have, just the MainPage
with three buttons, and that simply launches
| | 02:43 | the Accelerometer GPS or Camera
page were the actual implementation is.
| | 02:49 | We'll start with the Camera Page. The Camera
Page consists of a single button which invokes
| | 02:55 | the Camera Task and an Image Control where
we put the results from the CameraTasks so
| | 03:00 | that you can take a look at them.
| | 03:02 | So we look at the code behind the Camera Task. The key
thing is to bring you Using for Microsoft.Phone.Tasks
| | 03:08 | and then create an instance variable of
type cameraCapturedTask. You initialize it with
| | 03:14 | an instance of the cameraCaptureTask, and
then you have to create an EventHandler to
| | 03:19 | handle the cameraCapturedTask.completed event.
| | 03:23 | In our button, and we simply call cameraCapturedTask.show,
which invokes the camera user experience that we saw.
| | 03:30 | And then after the user has tapped the
button in the emulator, or when they've tapped the
| | 03:35 | screen in the Camera Task, this Camera Task
method is called. And if the camera actually
| | 03:41 | took a picture and our TaskResult is okay,
| | 03:44 | then we create a Bitmap SetSource of the
bitmap from the PhotoResult.ChosenPhoto stream and
| | 03:51 | then set that bitmap into the Image
control so that you can actually see it.
| | 03:55 | So in order to really see this in action
what you have to do is build a code, connect up
| | 04:00 | to your Windows phone device, download the
code into the device, and then unplug the cable
| | 04:05 | and then run the Camera section to this code.
| | 04:08 | Now Microsoft also has sample code that
allows you to access the raw Camera data.
| | 04:13 | So if you wanted to build augmented reality
type applications or things which implement
| | 04:18 | custom zoom features--just basically raw
access to the camera sensor and the flash--
| | 04:23 | you can dig into that at a much deeper level.
| | 04:26 | But for most applications this
Camera task will be sufficient.
| | 04:30 | So now let's go on and take a look at the GPS.
| | Collapse this transcript |
| Exploring GPS| 00:00 | We looked toward what the camera task can do,
now let's look to see how you can interact
| | 00:05 | with where you are in the
world using the GPS radio.
| | 00:08 | Back to the Solution Explorer,
let's take a look at our GPS page.
| | 00:12 | We have a button that starts tracking the
data coming from the GPS radio, and this is
| | 00:17 | independent of whether you
have the radio turned on or not.
| | 00:21 | So when you click here, it's assuming you
have the radio turned on, and then it will
| | 00:24 | start delivering updates.
There are two modes for updates, fast and slow.
| | 00:29 | We are going to showing the fast mode, and
I will show you where you could change it
| | 00:32 | if you want to use a slow mode,
which is useful and saves battery life.
| | 00:37 | The fast mode you would use, for example,
if you wanted to build an application, say,
| | 00:40 | to track how fast you were going in a car.
So let's dig into it's behind here.
| | 00:45 | So in order to access the GPS, you have to
include it using for System.Device.Location,
| | 00:51 | then you can create an instance
variable of type GeoCoordinateWatcher.
| | 00:55 | In our button click handler we call BeginTracking, and
we pass in the GPS position accuracy that we want to use.
| | 01:03 | In our example, we used .High, there is also an
option here you could use .Default so we use .High.
| | 01:11 | And this is basically starts the GPS radio
feed by creating a new GeoCoordinateWatcher,
| | 01:17 | setting the MovementThreshold to 20, and then
setting up an EventHandler for the PositionChangedEvent
| | 01:24 | so that we get called back when the
geographic position changes based on the GPS radio.
| | 01:29 | Here is our callback, like many other callbacks,
depending upon the level of the system which
| | 01:34 | the APIs implemented, the callback
sometimes don't come on the UI thread.
| | 01:38 | So this EventHandler here simply dispatches
using BeginInvoke to the PositionChanged EventHandler
| | 01:45 | so that we can actually update the
latitude and longitude on the screen.
| | 01:48 | And that is all it takes in order
to be able to track GPS information.
| | 01:52 | Next let's take a look at the
Accelerometer implementation.
| | Collapse this transcript |
| Exploring the accelerometer| 00:00 | And finally let's take a look
at how to use Accelerometer.
| | 00:04 | Once again, back to our Solution Explorer, let's
open up Accelerometer page. And here, similar
| | 00:09 | to the GPS, we have a button which Starts
Tracking the Accelerometer data, because again
| | 00:13 | it's Event driven, and you do not want to be
tracking it all the time unless you are actually
| | 00:18 | using it, partly to save battery life.
| | 00:20 | And then we have three text blocks where
we are going to show what the current values
| | 00:24 | of the three axes of the Accelerometer
are as being reported by the Accelerometer.
| | 00:28 | So let's go take a look at the code behind this.
| | 00:32 | In our Accelerometer page, in order to be
able to access the Accelerometer, we need
| | 00:35 | to get access to the Microsoft.Devices.Sensors
API, where there is an Accelerometer object.
| | 00:42 | Then we need a Timer because we use the Timer
in order to update the UI as opposed to using
| | 00:47 | a BeginInvoke that we used in the GPS thing.
It's just a different way of getting data
| | 00:52 | updated on the UI thread.
| | 00:54 | So instead of taking the actual Update events
and firing off for UI thread, we simply update
| | 00:58 | the UI thread based on the Timer.
| | 01:01 | The result of an Accelerometer Readback is an
object of type Vector3, so you got X, Y, and Z axes.
| | 01:07 | And then, each time we get an Accelerometer
result, we get to find out whether or not
| | 01:11 | the Accelerometer data is valid.
| | 01:14 | So we start up by saying, you know, do we
have an Accelerometer on this device?
| | 01:18 | Well, all existing Windows Phones have Accelerometers,
but it is possible that you might eventually
| | 01:22 | have one that doesn't.
| | 01:24 | And assuming that we do have one, then we
initialize our Timer or set it to 30 Milliseconds
| | 01:29 | and set up an EventHandler for it,
but we do not actually start the timer.
| | 01:33 | Accelerometer starts when
the user taps the button.
| | 01:36 | First time through we go to see if we have
actually allocated our Accelerometer object.
| | 01:40 | If not, we allocate it, we set up time between
updates of 20 Milliseconds, and again we set
| | 01:44 | up an EventHandler for the current value
changed event, and then we Start the Accelerometer,
| | 01:50 | and we Start our Timer.
| | 01:51 | It is highly unlikely that there would be
any problem with that, but just in case, we
| | 01:55 | cache the exception to make sure that
the Accelerometer actually did start.
| | 01:59 | Here is our callback method, all we do is set
the dataOK flag and set the Vector3 whatever
| | 02:04 | the current reading for the Accelerometer is.
| | 02:07 | And then we access that data in our Timer
callback, going and looking at if the data
| | 02:11 | is okay, then we look at the X, Y, and Z
Properties on that Vector3 object and set the text
| | 02:17 | properties of our text blocks to
update the current X, Y, and Z value.
| | 02:22 | And that is a brief overview of the different kinds
of sensors that you can access on every Windows Phone.
| | 02:28 | Some newer Windows Phones also have a Compass,
and in the future there may very well be other
| | 02:33 | kinds of sensors that may show up.
| | 02:35 | So stay tuned to the Microsoft web site
that gives you information on how to access the
| | 02:39 | detailed sensors, especially the how-to site,
it always has samples for each kind
| | 02:44 | of capabilities that are
available in Windows Phone devices.
| | Collapse this transcript |
|
|
8. Building Take-A-NoteIntroducing recording and playback with XNA| 00:00 | Windows Phone supports a variety of media
recording and playback features, including,
| | 00:06 | Recording from a Microphone, Playing back
through the Speaker from a Recorded Sound,
| | 00:10 | Playing back through the Speaker from Sound
that is streamed over the Network, Playing
| | 00:14 | back Video from Local Files, Playing back
Video over the Network and many Windows Phone
| | 00:19 | handsets also include an FM Radio, which you
have software APIs to be able to tune the
| | 00:24 | radio to specific channels.
| | 00:26 | This page right here is ground zero for all those
technologies and is frequently updated by Microsoft.
| | 00:32 | In this chapter we are going to dig into
using the Microphone to record sound and playback,
| | 00:38 | store it to a file, and be able to select one of
many songs that we have recorded and play it back.
| | 00:43 | So let's dig right into the code.
| | Collapse this transcript |
| Capturing sound| 00:00 | All right, so we are going to build the
smallest application that we can build that interacts
| | 00:04 | with the Xna Framework and capture sound.
Let's take a quick look at the solution.
| | 00:09 | First we added the Xna.Framework and Xna.Framework.GamerServices,
Library references so that we can access the Xna.Framework.
| | 00:17 | Then we added a couple of images from the
SDK icon library, one of a Microphone and
| | 00:21 | one of a Square or a Stop button so that we
can have our button at the bottom of the screen
| | 00:26 | in the Application Bar, toggle back
and forth between Record and Stop.
| | 00:30 | And then finally we've built some code.
| | 00:32 | In our code we have System.Windows.
Threading, because we need to create a dispatch timer
| | 00:38 | to create a periodic callback in order to
drive the Xna.Framework, and then we have
| | 00:43 | the two Xna.Framework usings so that we can
get to the basic framework, and we can also
| | 00:48 | get to the audio which is where
the Microphone code is located.
| | 00:51 | In terms of instance variables for our main
page here, we have a Microphone object, which
| | 00:55 | is how we're going to ask the system to start feeding us
data. We assigned it to the Microphone Default property.
| | 01:02 | Currently, no Windows Phone devices have
more than one Microphone, but in the future it
| | 01:07 | might be possible to differentiate between
the hardware Microphone on the device and
| | 01:11 | a microphone on a handset. And we have a buffer
in which we are going to put the samples returned
| | 01:17 | to us by the Xna.Framework and then a MemoryStream
where we are going to write the buffers out
| | 01:22 | as each buffer comes in.
| | 01:23 | We write it out to the stream so that when
we are done we could then save that stream
| | 01:28 | to a file, which we will be
doing in a future chapter.
| | 01:30 | And then finally, we have a boolean here inRecordingMode,
which we'll use to determine what we should
| | 01:35 | do when someone taps the
button on the Application Bar.
| | 01:39 | If we are not inRecordingMode, we start
recording, if we are inRecordingMode, we stop.
| | 01:45 | As I mentioned, in order to use code from
the Xna.Framework, we need to essentially pull
| | 01:49 | the Xna.Framework by calling this method FrameworkDispatcher.Update,
and this code here in the middle of the screen
| | 01:55 | right now simply creates a timer that fires off every
50 milliseconds and calls Framework.Dispatcher.Update
| | 02:01 | so that we can get frequent
updates of data from the Microphone.
| | 02:05 | And finally, in order to start we need to
fire it off just once in order to be able
| | 02:10 | to get things going.
| | 02:11 | When we are ready to figure out how big of
a buffer of the data we want, we tell the
| | 02:16 | Microphone how much data we want per
callback, in this case we are saying a half a second
| | 02:21 | worth of data, which is good for our first
application because we can see the data coming
| | 02:26 | in at a slow enough rate that we can manage.
| | 02:29 | In one of the later recordings in this
chapter, we're actually going to cut that way down
| | 02:33 | so that we can actually display some visual
feedback which we need to do a lot more quickly
| | 02:37 | than every half a second.
| | 02:39 | And finally, we tell the Microphone, here is
your BufferReady handler, here is our EventHandler
| | 02:44 | for when Microphone data is
ready, call us back there.
| | 02:47 | We also have a MainPage_Loaded Event
Handler that sets one of the textboxes on our user
| | 02:53 | interface to say Tap record to
begin when the page is loaded.
| | 02:57 | Once we start recording, the Microphone code
in the Xna.Framework will fire its BufferReady
| | 03:02 | event which we attached to this microphone_BufferReady
method and give us a buffer full of data each time.
| | 03:09 | So we write out how much data we got, we
can write that stream to the buffer, and then
| | 03:14 | we figure out what position we are within
that recording stream and set a text block
| | 03:19 | on our screen so that we can show the user
1 second, 2 second, 3 seconds of recording.
| | 03:24 | And finally, we have the code that handles
our Record button, as we mentioned before,
| | 03:30 | if we are inRecordingMode, we stop, change
the text for the button, back to record, set
| | 03:35 | the image for the button, back to the microphone,
and set the textbox to say Recording Complete,
| | 03:41 | and of course we set inRecordingMode = False.
| | 03:44 | If we are not recording, we create a new MemorySstream,
we go allocate the buffer by asking the Microphone
| | 03:50 | to give it its sample size in bytes
based on the duration that we told it.
| | 03:54 | So we said to it we want to
be called every half a second.
| | 03:58 | It's then going to compute how many bytes
that is so that we can allocate our buffer,
| | 04:02 | and we change the text of the button to stop, and
we change the image to the appbar.stop.rest.png.
| | 04:08 | And Finally, we call microphone.Start which
starts the process of the Microphone calling
| | 04:13 | us back, giving its buffers full data,
and we set inRecordingMode to true.
| | 04:18 | So let's give this a try.
| | 04:22 | So we have a single portrait page template that we
have started with, we set the name to record & play.
| | 04:28 | We have a text box here where we are
going to put the time, and we have our App.
| | 04:32 | bar down here with a Recording button.
| | 04:34 | So we touch the Recording button, and
we are now recording. You can see the
| | 04:38 | time is updating, and you can also see a
debug output saying we have received 16,000 bytes
| | 04:43 | and then other 16,000 bytes
and then other 16,000 bytes.
| | 04:46 | And you can see if you are looking at a large enough
screen that the size of the scrollbar thumb
| | 04:50 | here is getting smaller and smaller
because this is continuing on, as we get more and
| | 04:54 | more of these lines in the Debug output.
| | 04:56 | So, now we know we have got the basic
Recording mechanism going, we are getting data back
| | 05:01 | from the recording, and let's move on to the
next part where we will actually take a look
| | 05:07 | at that data and provides some visual
feedback of the data actually coming in.
| | Collapse this transcript |
| Providing feedback while recording| 00:00 | So we have set up the basic recording
capability, now let's provide some feedback to the user
| | 00:05 | to show them the amplitude of
the data that they're seeing.
| | 00:08 | We'll come over and look in the solution and
see that we've added an additional image here.
| | 00:13 | Let's take a look at what that image looks like.
| | 00:14 | So this essentially is our amplitude meter,
and what we're going to do is we actually
| | 00:19 | have another piece of XAML code that sits
on top of that whose size we shrink from
| | 00:24 | the right side to the left in time with the
data coming back from the buffer to show how
| | 00:29 | much data is there.
| | 00:30 | So we don't actually render the squares at
runtime, we simply shrink the mask that's
| | 00:35 | hiding them at runtime.
| | 00:37 | So let's take a look at the XAML for
the main page to see how we set that up.
| | 00:42 | So here is our XAML, and you can see that
here we've created an image and filled it
| | 00:48 | with the meter bar, and then inside that
we've created a rectangle that is exactly inside
| | 00:55 | the meter bar and at runtime we then shrink
that--let's say that we've set this to 400.
| | 01:01 | But we also adjust the Margin at the same
time so that the right-hand end of this rectangle
| | 01:07 | always stays here, and we shrink the size
of the rectangle and move it to the right
| | 01:11 | so the right-hand end is always there.
| | 01:13 | Thus, if we do this, this way and shrink it
again, the image underneath is more exposed.
| | 01:21 | Let's undo all this stuff and put it back to
its original state and go take a look at the code.
| | 01:26 | So our code looks very
similar to what we had before.
| | 01:29 | We still have our same four instance variables,
the microphone, the buffer, the stream, and
| | 01:34 | our RecordingMode, got the same Xna
.FrameworkDispatcher.Update logic.
| | 01:39 | We've reduced the time span of the buffer
duration from half a second to a 10th of a
| | 01:44 | second, and that way our meter on
the screen will update more quickly.
| | 01:48 | So how do we do that? Well, we do it all here
in the Callback method for the microphone data.
| | 01:53 | So when a buffer of data comes in, we do
what we did before, we go get the data buffer,
| | 01:58 | we write it out to the stream, and now we
compute the average amplitude of the sound
| | 02:03 | that's inside that buffer so that we know
how big or how small to make the rectangle
| | 02:08 | mask, thus deciding how much of the
meter image underneath we should expose.
| | 02:14 | So first we go through all the samples.
| | 02:16 | Now, the samples are two byte samples, so
the recording on a Windows phone device is
| | 02:23 | always 16-bit recording, and it's 16-bit raw
PCM, so we know that every one is two bytes.
| | 02:29 | So we basically loop through the data,
looking at all the samples, we extract one sample
| | 02:34 | from the buffer, then we convert it to a 32-bit
int, because we want to Math.Abs, because
| | 02:40 | the data coming from the microphone is
either -32768 in that direction, or up to +32767,
| | 02:47 | but all we really care about is the absolute
magnitude, because what that data is actually
| | 02:53 | representing is digital samples
of the sine wave of the sound.
| | 02:57 | So even though it might be loud, it might be
up in the 10,000s, it could be on the bottom
| | 03:03 | end of the sine wave, so the number coming
back might be -10,000, but we don't care about
| | 03:08 | that right here, all we really want to know
is what's the magnitude of the wave that's
| | 03:12 | currently being recorded at the moment.
| | 03:14 | So we grab it as an integer, we get its
absolute value, we create an absolute number, and then
| | 03:20 | we turn around and just calculate the average so
that we get an average volume inside that buffer.
| | 03:27 | Then we have to do a little bit of graphic
magic, so we need to scale that, because that
| | 03:31 | number is going to be between 0 and 32,000, and we
need to scale it so we can use it with our meter bridge.
| | 03:37 | We scale it by 10, because in order to get
a reasonable response out of the meter, it's
| | 03:43 | very rare that someone is actually going to
get a volume that's all the way up into the
| | 03:47 | red, but if you just use the raw values,
then you only get just a little bit of the green
| | 03:52 | showing, so we scale it up a little bit,
because most recording data is going to be in the
| | 03:56 | middle, and we want to have that meter look
reasonable in terms of what the user is expecting,
| | 04:01 | to give them visual feedback.
| | 04:02 | So now we have our CoverSize that says how
big should that rectangle be, and now we need
| | 04:07 | to convert that into XAML units so we can
adjust the coordinates for that rectangle.
| | 04:12 | So we first create a Thickness object from
the current margin of that rectangle, and
| | 04:18 | then we update the left edge of the rectangle
by saying it's 21 plus the meterCoverSize,
| | 04:23 | meaning the size we just calculated.
This is what shifts it to the right.
| | 04:27 | And then we update the Width so that it
shifts back so it doesn't overflow the right-hand
| | 04:31 | end of the graphic so that the teal border we have
around the meter always shows exactly as it should.
| | 04:38 | And then finally, this is the same code we
had before. We go get the current position
| | 04:42 | in our current stream and update the recording
number in our TimerTextBlock, and that's it.
| | 04:47 | But we've also added one more thing to the
recordbutton_Click, which is when you're in
| | 04:51 | Record mode, and you stop, we want to put
the cover back on top of our meter so that
| | 04:56 | it appears that there's no sound coming in,
so we want the meter to be completely black
| | 05:01 | now with none of the green,
yellow, or red showing.
| | 05:05 | So let's rebuild our
solution and give it a whirl.
| | 05:11 | Just like before, we click the Record button,
but now as we're recording, you can see that
| | 05:15 | the meter is showing the amplitude of the volume
that's actually coming in through the microphone.
| | 05:21 | So if I say 1-2-3, you can see as the meter
goes up, as I'm talking, we've got that visual
| | 05:28 | feedback so that the user knows something
is really happening here, and their sound
| | 05:32 | is actually being recorded.
| | 05:35 | So that's great! Now we've got the microphone
hooked up, we've got some feedback going on
| | 05:39 | so that your user knows that
there's actual sound being recorded.
| | 05:44 | Let's go on now and add something to play
that sound back so that we can actually hear
| | 05:48 | what got recorded.
| | Collapse this transcript |
| Playing a recording| 00:00 | Let's move on now to play back
the sound that we've been recording.
| | 00:04 | Again let's take a look at the solution.
| | 00:06 | We've added a couple of additional images, a
Play button and a Pause button, again, both
| | 00:10 | from the Icons Library
supplied with the Windows Phone SDK.
| | 00:14 | And let's take a look at the XAML for the
MainPage. We're dealing with the ApplicationBar
| | 00:19 | here, so there is nothing we can see in the
designer. What we can see down here at the
| | 00:23 | bottom now is that not only do we have a
button for recording, we have a button for play.
| | 00:28 | And we'll see how we actually make that
come alive, we'll take a look at the code.
| | 00:33 | So everything that we've seen so far is the
same except now we have some variables that
| | 00:39 | help us be able to play the sound back.
| | 00:42 | We have a sound effects instance, which is what
we're going to do to take that stream and play it back.
| | 00:47 | And we're using sound effect instance instead
of sound effect because we want to be able
| | 00:52 | to turn the Play button from play to pause
and handle pausing, which is something that
| | 00:58 | we don't get updated for if
we're just using sound effect.
| | 01:00 | If we just used a sound effect object to
play it, it would simply play, and that's it.
| | 01:05 | In addition, we also have a playbackStarted
button, again, the same kind of thing we use
| | 01:09 | for in recording mode when playback is started
and you touch the button, we know that we
| | 01:13 | should pause versus start playing over again.
| | 01:15 | Now, we've added a little bit
more code to the timer callback.
| | 01:19 | Originally we just had this
FrameworkDispatcher.Update.
| | 01:22 | Now, we not only want to run the game loop,
we want to update our user experience based
| | 01:27 | on the state of the playback.
This is how we know how to switch the sound.
| | 01:32 | And we can't just do this when you tap the
button, because we want to know when the playback
| | 01:37 | has actually started.
| | 01:38 | So we keep our playbackStarted flag and
every time through the timer here, first of all
| | 01:43 | we say, oh, are we actually playing something?
Great, if we are, then let's see, do we think
| | 01:49 | playback has started? If not, and the sound is actually
playing, then we set our playbackStarted logic to true.
| | 01:56 | If we think we've started playing back, and
now the sound.State has stopped, that's when
| | 02:01 | we know that the sound has stopped playing,
and we can turn the button back from the Pause
| | 02:05 | button back into the Play
button so we can play again.
| | 02:08 | And so you can see when we've detected
playback and then the sound finally stops playing,
| | 02:13 | we set the ApplicationBar back to play and
the play image and the TimerTextBlock back
| | 02:19 | to an empty string, and set the sound to null
and set our playbackStarted flag back to false,
| | 02:25 | because now we're no longer playing.
| | 02:27 | All of our other recording logic still remains
the same, so we don't have to change any of that.
| | 02:33 | Our recordbutton_Click remains the same, but
here now we have the playbutton_Click logic.
| | 02:38 | So this is the Handler for our Play button.
| | 02:40 | We, first of all, want to check to see if
we're in recording mode, because we don't
| | 02:43 | want to start playing back
a sound if we're recording.
| | 02:46 | Then we want to see whether we're in play
mode, and we want to pause or we're in pause
| | 02:50 | mode, and we want to resume.
| | 02:52 | So the logic we use says, we come in
and look at the text of the button.
| | 02:56 | If it says play, then we change the text and
the graphic to pause, and then we say is there
| | 03:01 | a sound? If there is a sound, then that means we were
already playing so we simply resume and exit here.
| | 03:08 | If you touch the Play button, and there is no
sound playing, we come down here and allocate
| | 03:13 | a new sound from the stream and play it.
| | 03:15 | Otherwise, if the button text said pause,
meaning we were actually playing something
| | 03:20 | back, we pause the sound, set the button
back to play and set the TextBlock to pause so
| | 03:26 | the user will see the word Paused on the screen.
| | 03:29 | So let's just run it.
| | 03:31 | So here we are, let's do a little
recording 1-2-3-4-5, and we'll stop.
| | 03:38 | It says Recording Complete, now
we'll play it back, 1-2-3-4-5.
| | 03:46 | And now let's exercise the Pause
functionality, we'll stop it after 2. 1-2.
| | 03:52 | Now, you can see the TextBlock here says
Paused, and if we touch the Play button again, it
| | 03:57 | continues on to play to the end, 3-4-5.
| | 04:02 | So now we've been able to record audio,
we've been able to give feedback on both the time
| | 04:07 | and the amplitude of the audio that's being
recorded, and now we've actually played that audio back.
| | 04:12 | Now, that's a great app if all you want to
do is record one thing and play it back, but
| | 04:17 | we haven't saved anything yet, and so
you can't play it back multiple times.
| | 04:20 | So let's go and Save that in Isolated Storage
as a file, as a prelude to being able to create
| | 04:26 | a list of recordings and look at
them, which is the final application.
| | 04:30 | So let's go save this data to Isolated Storage.
| | Collapse this transcript |
| Persisting a recording| 00:00 | Let's take a look at how to save that
stream of data that we had in a MemoryStream into
| | 00:04 | isolated storage so that
we can play it back later.
| | 00:08 | We haven't added any new additional images or
user experience with this, just some underlying code.
| | 00:14 | So now we've added a using for System.IO.IsolatedStorage,
and we have added a variable here to keep
| | 00:20 | track of the lastRecordedFileName and the
reason for that is we have also changed the
| | 00:24 | playback to play back from the file rather
than playing back from the MemoryStream.
| | 00:29 | So everything else we've done so
far all looks exactly the same.
| | 00:33 | We haven't changed anything for the recording
or the basic playback, except that in recording
| | 00:39 | we now make a call to this SaveRecording
method where we have the logic that actually writes
| | 00:44 | to IsolatedStorage.
| | 00:47 | Play logic is still the same until we get
to the place where we're we actually going
| | 00:52 | to play it, and we'll come
back to here in just a second.
| | 00:55 | Let's look at the method where
we actually save the recording.
| | 00:58 | So just like we did before, we use GetUserStoreForApplication
to get access to the IsolatedStorage manager.
| | 01:04 | Now, here we have to decide
what we're going to call our file.
| | 01:08 | So we do this based on the time and date in
the phone, and then we just convert that time
| | 01:14 | into Ticks and use that long number that we
get from that with the extension dat on the
| | 01:18 | end of it to create the file name.
| | 01:21 | And then we go and create the file, get the
buffer from the stream and write it out to
| | 01:27 | the IsolatedStorageFile, flush it and
close it and set the stream to null.
| | 01:32 | And then we also write an info file using
the same name, but a different extension,
| | 01:36 | in this case .info.
| | 01:38 | The reason we do this is it's not possible
with the IsolatedStorage manager to find out
| | 01:43 | the date and time of a file
that's stored in IsolatedStorage.
| | 01:47 | That particular functionality is just not there.
| | 01:50 | So in order to be able to keep track of
multiple files and have the ability, for example, to
| | 01:55 | sort them by date, we actually have to have a
separate file that has the metadata in there,
| | 02:01 | in our case, the name of
the dat file and the time.
| | 02:05 | And in the next movie we'll actually see how
we use this data to create a view model full
| | 02:09 | of data to be able to populate a list box.
| | 02:12 | And last but not least, let's look at our
updated play logic because the updated play
| | 02:18 | logic no longer displays from the in memory
stream. We actually go and load the data from
| | 02:23 | the IsolatedStorage.
| | 02:25 | Once again we get the IsolatedStorage manager,
go and open up the stream containing our data,
| | 02:30 | read it into a new MemoryStream because we
need to have that in order to be able to create
| | 02:34 | a SoundEffect instance, so we
need to use stream.ToArray here.
| | 02:38 | So we load the entire sound into memory,
create a sound, and play it just as we did before,
| | 02:43 | and that's it for persisting the recording
as an individual file in IsolatedStorage, which
| | 02:48 | once again is great if you only have one file,
but the app becomes a great deal more useful
| | 02:53 | if we can record multiple files and
choose which one we want to play back.
| | 02:56 | So let's do that.
| | Collapse this transcript |
| Listing recordings| 00:00 | So our app is coming along, isn't it? We've
got the ability to record sound, we can see
| | 00:05 | the sound as its recording, we can play
it back, and we can save it to a file.
| | 00:09 | So now let's add some user experience to
allow our user to see the list of recorded sounds
| | 00:14 | and play the ones that they want.
We'll take a look at the solution again.
| | 00:17 | We have now added one more
image here, the folder icon.
| | 00:22 | Now we have three buttons in our ApplicationBar,
the record stop button, the play pause button,
| | 00:27 | and now a folder button to take us to the list.
| | 00:30 | We've also added essentially a data bound
page just as we did with the first sonnets
| | 00:35 | app, so we have ViewModel, a
MainViewModel, and an ItemViewModel.
| | 00:39 | And if we take a look, the MainViewModel
simply has individual names of files in it.
| | 00:45 | And the way we populate that ViewModel is
by going to the file system and getting a
| | 00:50 | list of all the filenames and
then searching for the .info files.
| | 00:54 | Remember, from the last thing that we built
we saved the name of the file and the date
| | 00:59 | of the file in a .info metadata file
so that we could do just exactly this.
| | 01:04 | So we search through, we find a name that
ends with .info, we open it up, we read it,
| | 01:09 | we split it into two parts using the Split
functionality, one part is the file name,
| | 01:13 | the other part is the date, and we add a RecordingInfo
object that is the thing we add into our ItemViewModel.
| | 01:20 | Our RecordingInfo object here is very simple,
it's just two string properties, a file name
| | 01:25 | and a display string.
| | 01:26 | And our ItemViewModel simply has two
properties, DisplayString and FileName.
| | 01:32 | And then of course, we added a Recordings.xaml
file, which has a ListBox that shows the items,
| | 01:38 | which is the FileName and the DisplayString.
| | 01:42 | Finally, take a look at the code for this.
What this does is we keep track of which item
| | 01:46 | is being selected so that when we want to play
it back, we can load the sound in and play it.
| | 01:53 | We've got some instance variables here, so
A: we can figure out which one is the last
| | 01:56 | selected item for playback.
| | 01:57 | We have a Brush, because we actually set
the highlight on the selected item, because we
| | 02:02 | want that to be persistence so that the
user can see which sound they're playing back.
| | 02:06 | Of course we have an instance of our ItemViewModel,
so we can extract the RecordingInfo object out of that.
| | 02:11 | We have an instance of the Microphone, and
the reason that we get that has to do with
| | 02:15 | being able to look at some of the buffer
sizes and things, not because we're actually doing
| | 02:19 | any recording in this file.
| | 02:20 | We've got the buffer that's going to hold
the sound, the MemoryStream we're going to
| | 02:24 | play it back from, the SoundEffectInstance
we're going to play it with, and we have the
| | 02:28 | same kind of logic in here that we used in
the MainPage in order to be able to determine
| | 02:34 | play and pause and switch the state of the
application button for play and pause, so
| | 02:38 | we need to know when it's actually started
and more specifically, we need to know when
| | 02:42 | it stops so we can switch it back to play.
| | 02:44 | So here we go ahead and load up our ViewModel
and set up another Dispatcher and go through
| | 02:49 | the same logic we did before about
detecting playbackStarted, switching the button from
| | 02:53 | play to pause and pause to play.
| | 02:57 | On Page_Loaded we deselect everything in
our ListBox, because we can go back and forth
| | 03:02 | here pretty easily, and then when somebody
actually taps one of the items in our list,
| | 03:07 | we go and get the ListBoxItem from the ListBox
so that we can actually set the background for it.
| | 03:13 | So what we do is go get the ListBoxItem and
keep track of what the background was, because
| | 03:18 | we're going to set the background to the theme
color, and when we're done we want to turn it back.
| | 03:22 | So then we go get our SelectedItem, make
sure we know which one it is, and we go get our
| | 03:27 | container from the item, and we get the currentAccentColor,
which the user has chosen in settings, and
| | 03:32 | we set that ListBox that the user is selected
to that background color, and that's all we
| | 03:37 | do, we just keep track of which one it was.
| | 03:39 | So that now in the Play Handler here, we use
the SelectedItem, set it to play, we do the
| | 03:44 | same kind of logic for play and pause that we
did on the MainPage, but when we're actually
| | 03:49 | playing here, we go and get the information about
which file to load from the lastSelectedItem's FileName.
| | 03:56 | Otherwise the rest of this is the same.
| | 03:58 | We create a MemoryStream, put the
data in the buffer, and tell it to play.
| | 04:01 | And that's it for this particular revision of
apps, so let's go take a look at this in action.
| | 04:08 | First we'll make a recording, recording 1-2-3-4-5.
We go look, there is our recording, we click
| | 04:19 | here and play it back.
Recording 1-2-3-4-5.
| | 04:26 | And if we look over here in the Debug Output,
you can see that we've retrieved that info
| | 04:30 | file and dumped out its data so that we
know which one we're actually doing, and we've
| | 04:34 | also detected the selection so that we
know which file we have to play back.
| | 04:38 | Let's go make a second recording.
This is recording 2-A-B-C-D-E.
| | 04:49 | If we come over here, now we have recording #2.
This is recording 2-A-B-C-D-E.
| | 04:58 | Or recording number one.
| | 05:00 | Recording 1-2-3-4-5, All right! Now, this is
great and has everything we need except two things.
| | 05:08 | One is the ability to delete a recording,
and the other is to be able to record when
| | 05:12 | the user screen is locked, so that's coming up.
| | Collapse this transcript |
| Managing the recording list| 00:00 | So that's great, now we can make recordings,
we can save them, we can play back the ones
| | 00:04 | we want, but we're still just going to fill
up the phone if we don't implement the ability
| | 00:08 | to delete one, so let's
go ahead and do that now.
| | 00:13 | Jump back to Visual Studio, we'll go to the
XAML for this, come down to the bottom here
| | 00:20 | and add another Handler for a delete button,
and then we've added a delete image from the
| | 00:26 | Icons Library that came with the SDK.
| | 00:29 | And then let's come back to the code here
at the bottom and add a little bit of code
| | 00:33 | to implement the delete.
| | 00:35 | So this actually comes in three different pieces: we
have a Handler for the ApplicationBar button for delete.
| | 00:42 | We first want to check to see if we actually
have anything selected, if we don't, we put
| | 00:45 | up a traditional message box that
says there is no recording selected.
| | 00:49 | If there is, now we're going to use that GamerServices
message box we talked about before that's
| | 00:54 | available from the XNA Library, because
we want to be able to use custom buttons.
| | 01:00 | So this BeginShowMessageBox here has a custom
title, Please Confirm, "Are you sure you want
| | 01:06 | to delete the selected recording?" and then an
array with the buttons, in this case Yes and NO.
| | 01:12 | And then we have a new AsyncCallback for OnMessageBoxAction
so that when the user clicks one of the buttons,
| | 01:18 | we can respond to it.
| | 01:19 | So here in OnMessageBoxAction, we look to
see which button the user clicked, and if
| | 01:25 | in fact he clicked the Yes button,
then we're going to call DeletePart2.
| | 01:29 | The important thing to know is that this
OnMessageBoxAction method is not called on the UI thread, which
| | 01:36 | is why we have to use BeingInvoke, so we have
to say Deployment.Current.Dispatcher.BeginInvoke
| | 01:43 | and call the DeletePart2 to make
sure we call it on the UI thread.
| | 01:46 | And so DeletePart2 says go get the last selected
file name, we need to get the info file for it.
| | 01:54 | We go get IsolatedStorage, and we delete both
the file and the info file, and then we reload
| | 01:59 | the data in our ViewModel by scanning all the .info
files, and then we call App.ViewModel.FilesUpdated
| | 02:06 | in order to fire the event to get the
list of files updated so our ListBox updates.
| | 02:11 | So let's see this in action.
| | 02:14 | So here's our list of files, there is our
delete button, we click it first, there is
| | 02:19 | no recording selected, we
get a regular message box.
| | 02:22 | Now, we click it again, this is our recording
number 2, and we delete, and we get a special dialog box.
| | 02:30 | Now, note two things: one, there was a sound
to go along with it; two, we have a big title
| | 02:36 | and a small bit of text; and three, the system
overwrote the capitalization that I initially
| | 02:42 | put in for the buttons.
| | 02:43 | I initially put in capital Y small E, small
E for the Yes button and capital N-O for the
| | 02:48 | No button in order to try to show that, that
was an important thing you might want to choose,
| | 02:53 | but the system overwrote that, because the
Metro Design Guidelines say those buttons
| | 02:57 | are always lowercase.
| | 02:58 | so in this case we'll say Yes, and you
see that item was updated in the ListBox.
| | 03:04 | We went and reread the list so now all we
have now is our first original recording.
| | 03:08 | Recording 1-2-3-4-5.
| | 03:12 | And now I've got everything done for this
app except recording under the lock screen,
| | 03:17 | so let's go take a look at the very last
build of this to see the small thing we need to
| | 03:20 | add in order to be able to implement the
ability to record while the user's screen goes black.
| | Collapse this transcript |
| Recording under the lock screen| 00:00 | The last thing we want to do to Take A Note is
make it possible to record under the lock screen.
| | 00:05 | Most applications don't want to run when
the user screen locks, meaning when the screen
| | 00:10 | goes black, because the purpose of that is
to save the battery and therefore stop the
| | 00:14 | apps and reduce the load on the CPU.
| | 00:17 | But in the case of recording, we want to still
be recording even though the lock screen comes
| | 00:21 | on, because Windows Phone devices don't have that
option of turning the lock screen off altogether.
| | 00:25 | We have to do one simple thing.
| | 00:28 | So let's open up our MainPage.xaml here,
and we'll go take a look at what it is.
| | 00:32 | So down here we simply have to say PhoneApplicationService.
Current.ApplicationIdleDetectionMode=IdleDetectionMode.Disabled.
| | 00:42 | You may remember that we looked at this in
the App.xaml.cs, and it gets invoked when
| | 00:48 | you're running in a debugger.
| | 00:49 | So if you want to make sure that the
record under the lock screen works for your app,
| | 00:54 | you'll need to deploy the app to an actual
phone device and then disconnect it from your
| | 00:59 | development system in
order to be able to test that.
| | 01:01 | And one more reminder, if you disconnect the
phone while Zune is running--because you want
| | 01:07 | to show somebody your great app, or in this
case you want to test this feature--oftentimes
| | 01:11 | you'll have to quit and restart the Zune
app even after you've plugged your phone back
| | 01:16 | in, in order to be able to continue
to do development with Visual Studio.
| | 01:20 | So there it is. I hope that you make great
recordings, and I hope that Take A Note has
| | 01:25 | helped you understand the intricacies of
recording and playing back sound with Windows Phone
| | 01:31 | and that you have fun making
recordings and playing them back.
| | Collapse this transcript |
|
|
9. Building TweetMonitorBuilding the UX| 00:00 | All right, ready to get connected and go social?
We're going to build TweetMonitor. This is
| | 00:05 | going to allow us to demonstrate how to
access network resources, how to detect whether the
| | 00:10 | network is actually connected.
| | 00:12 | We're going to use the web client API to
go read a list of Twitter status updates via
| | 00:17 | XML using the Twitter rest API.
| | 00:20 | And then we're going to create a BackgroundAgent
so that we can have a live tile that will
| | 00:24 | update with the number of tweets and the name
of the twitter handle that you're following.
| | 00:28 | And finally, we're going to be able to
detect that tweets have URLs in them and actually
| | 00:33 | launch the Internet Explorer web browser
with the URL to go read whatever attachment is
| | 00:39 | associated with a particular tweet.
| | 00:41 | And this will allow us to also investigate
the rather nice updated facilities in Windows
| | 00:47 | 7.5 Mango for handling the dreaded tombstoning
requirement for your applications, which is required
| | 00:54 | so if the application is moved not just to
the dormant state, but moved to the tombstone
| | 00:59 | state when the user comes back, say, from Internet
Explorer exploring an article and your application
| | 01:04 | has been discarded by the operating system,
you can actually restore it and make it look
| | 01:09 | like the application has
been running the whole time.
| | 01:11 | So, first let's take a look at the application
in action, and then we will take a look at
| | 01:15 | building this initial user interface.
| | 01:18 | So, we'll come up here and use the hard word
keyboard because it's little easier to type
| | 01:22 | twitter handles, and we'll look at my twitter
feed--which is michael_lehman--and we downloaded.
| | 01:28 | And this is my current list of tweets, and
there I am building a Windows phone twitter
| | 01:31 | app with the BackgroundAgent.
| | 01:33 | And of course I can scroll out through my
other tweets and one interesting one here
| | 01:38 | was an article that I found on TechCrunch
recently, which was about building smarter
| | 01:42 | web apps. And there we go, and now we are
looking at live browser image of what's on TechCrunch.
| | 01:47 | Now I want to click the Back button we come back
to our app, and we can go off and do another one.
| | 01:51 | What we're going to do next is actually start
up the background agent so that we can create
| | 01:56 | a live tile for our application and see who
we're watching and how many tweets they have.
| | 02:01 | I'll click Start Agent, come back here, go to the
list of applications, and pin this to the Start menu.
| | 02:07 | Now right now it says TweetMonitor. In just
a little while that's going to update to be
| | 02:12 | the number of tweets and then the back of
the live tile is going to be the twitter handle
| | 02:15 | that we're following.
| | 02:17 | So there are 3885 number of tweets that I've done since
I join twitter in 2007, and there's my twitter handle.
| | 02:25 | If we were to go back into the app--which
clicking on that live tile will take us back
| | 02:28 | there--and change who were watching, say, to
watch lynda.com and click Start Agent again.
| | 02:35 | When we go back to the live tile in a minute
this is going to update with a number tweets
| | 02:39 | that lynda.com has done, and you'll see the
back of the tile have the lynda.com twitter
| | 02:44 | handle, so there's my twitter handle.
| | 02:46 | In a second this is going to update to say
lyndadotcom, and when it flips back over you'll
| | 02:50 | see 1331 tweets which is what the
lyndadotcom twitter account has.
| | 02:55 | So let's exit the emulator here and go take a
look at what it takes to build a user experience,
| | 03:00 | and then we actually start building the app.
| | 03:02 | So, we'll come back to Visual Studio, we'll stop
running, and we'll take a look at the main
| | 03:09 | XAML page. So this XAML page is actually
fairly straightforward. We have the standard layout
| | 03:14 | root here at the top with the name of the
app and the name of the page, then we have
| | 03:18 | a text box where you type in the twitter
handle, an Update button which goes and reads using
| | 03:23 | the rest API, the twitter feed data.
| | 03:27 | The Start Agent button, which will invoke
our background agent code, a text block we put
| | 03:32 | in the status, downloading or download complete
or download failed, and then the list box where
| | 03:38 | we actually put the data
that we got from twitter.
| | 03:41 | And that's the basic user
experience for this whole thing.
| | 03:44 | The implementation of the live tile doesn't
have any XAML to go with it, it's all API driven,
| | 03:49 | and we'll see that later.
| | 03:50 | So let's get started building
some code to go and get those tweets.
| | Collapse this transcript |
| Using WebClient| 00:00 | All right, we've got our UX all setup, the
XAMLs all ready, let's implement some code
| | 00:04 | to go get those tweets from twitter.
| | 00:06 | So we come down here and start out with the
code that we need. You might notice that we
| | 00:12 | also already added the About box and the
About box calling menu item to the MainPage.xaml
| | 00:18 | so that we don't have to do that at the end.
| | 00:20 | And now we'll bring in the real code here,
and we'll add another class in order to store
| | 00:26 | our tweets, so I Add Class, and it's called Tweet.
| | 00:31 | It looks like this just has three strings
Name of the twitter handle, Content, and Statuses.
| | 00:37 | We use that to feed our list box.
| | 00:39 | Now let's go take a look at the code
behind where we actually go get the tweets.
| | 00:43 | We've got phone application page as always,
we're using our settings class that we used
| | 00:48 | back in our units converter sample application
so that we can keep track of the twitter handle
| | 00:53 | that we're getting status for.
| | 00:55 | This is in anticipation of implementing the tombstone
in support, we're going to do later on this chapter.
| | 01:01 | So, we set it up to be the blank string
when we actually get a string from the user we
| | 01:06 | stored into there which then to get stored into
isolated storage if you recall from the units converter.
| | 01:11 | The only kind of HTTP web access available to
developers in Windows phone is asynchronous,
| | 01:17 | you can't do HTTP client
and do synchronous web access.
| | 01:21 | So, the way we do this is we
instantiate an instance of the WebClient class.
| | 01:26 | We set the DownloadStringCompleted handler to a new
method of ours called connectTwitter_DownloadStringCompleted,
| | 01:34 | and then we call DownloadStringAsync on the
web client instance and in this case we passed
| | 01:40 | api.twitter.com/1/statuses/user_timeline.xml?screen_name,
and then we put the screen name or the user
| | 01:50 | handle that we got from the text box.
| | 01:53 | One thing to note if you're working with this
app or you're working with building your own
| | 01:57 | twitter clients, Twitter has two kinds of
APIs, it has the Free, Public Rest API, which
| | 02:03 | is what we're using in this app.
| | 02:05 | And that has a restriction
of 150 API calls per hour.
| | 02:09 | As we were developing this app for this course,
we ran into that a few times and had to wait
| | 02:14 | an hour before we could
continue to access Twitter.
| | 02:17 | If you're going to be creating an actual
twitter application, you're going to want to use the
| | 02:21 | OAuth API, and that has a
limit of 350 API calls per hour.
| | 02:26 | So unless your user is sitting there tapping
on the screen wanting to update the twitter
| | 02:30 | status, that should be more than enough.
| | 02:32 | But if you start to try to access Twitter,
and you get back 400 errors, it pretty much
| | 02:38 | means you run into that twitter API
throttling limit, and you should wait an hour before
| | 02:42 | you continue on working on your app.
| | 02:44 | Now once we've made the request to twitter,
when that request is satisfied and the web
| | 02:49 | client completes, we get called
back here to DownloadStringCompleted.
| | 02:53 | If you did run into that 400 error, you'd end
up in here, and when you look at the e.Error,
| | 02:59 | it's pretty clear what's happening.
| | 03:00 | So let's assume that we got valid data, so
we use the built-in System.Xml.Linq facilities
| | 03:07 | to parse out the XML looking at the status
collection and getting the user statuses_count
| | 03:14 | and the text and the screen_name
for each of the tweets.
| | 03:18 | We don't do anything with it yet, but
let's go ahead and run this just so that we can
| | 03:22 | see that we're going to get the tweets,
and because we're putting them into this item
| | 03:26 | source, we actually would be able to see
the data binding work and the tweets will show
| | 03:31 | up in the list box.
| | 03:34 | We'll come up here and put our twitter handle in
again, click Update, and there's our tweets.
| | 03:40 | We don't have anything handling them yet,
so as we click on them nothing happens right
| | 03:44 | now, and that's what we're going
to get to as we carry on with this.
| | 03:48 | Next step, we're going to go and look and
make sure that we can know when we're actually
| | 03:53 | connected to the network so that we know
how to handle errors, and when the application
| | 03:57 | starts we can tell people
what's really going on.
| | Collapse this transcript |
| Determining network connectivity| 00:00 | We've managed to connect to Twitter and get
the statuses for the Twitter user handle or
| | 00:05 | screen name that we want.
| | 00:07 | But let's be a little nicer to our user, first,
checking whether we have network connectivity
| | 00:11 | at all before we request data from Twitter
and then providing a little active feedback
| | 00:16 | telling the user when we're downloading, when
the downloads complete, or if the download fails.
| | 00:21 | So, we'll come to our Solution Explorer, open
up the MainPage.xaml.cs again, and come through
| | 00:27 | here and update the Click
and DownloadCompleted handlers.
| | 00:32 | First up, this is how you can tell whether
or not your Windows phone device is actually
| | 00:36 | connected up to any kind of a network.
| | 00:38 | So, you've got Microsoft.Phone.Net.NetworkInformation.
DeviceNetworkInformation, and then you check for IsNetworkAvailable.
| | 00:46 | There is a bunch of
variations of this you can use.
| | 00:49 | Right now, we're checking for any kind of
network, but if in your app you needed to
| | 00:52 | know whether you've got CellularData or CellularDataRoaming
or whether you've got Wi-Fi available, you
| | 00:59 | can pick any one of these and get very
fine-grained set of network availability.
| | 01:04 | So you may not want to go grab email or go
grab calendar data if your user is roaming,
| | 01:09 | the data charges might be real expensive, or
you might be planning to download or upload
| | 01:14 | a whole bunch of data, and if you don't have
Wi-Fi, you may not want to do that again to
| | 01:18 | save the user's data bytes for more important information,
and waiting until you're connected up to Wi-Fi.
| | 01:24 | So, if we don't have a network, we put up a
message box saying we don't have any network,
| | 01:28 | and we don't go any farther.
| | 01:30 | Assuming that we do have a network, not
only do we grab the user's Twitter handle from
| | 01:35 | the textbox, but we also set the text block
to say downloading before we fire off the
| | 01:40 | asynchronous call to the web client.
| | 01:42 | And then once the web client completes, if
we got an error, we set the text blocks to
| | 01:46 | "download failed!" and stop there.
| | 01:48 | Again, that's what you're going to see if
you run into that twitter API throttling limit,
| | 01:53 | and if we didn't get an error, then we set
it to download complete and carry on parsing
| | 01:57 | the XML and putting it into our
list box just as we did before.
| | 02:00 | Now let's move on to being able to figure
out how to sense the links in the Twitter
| | 02:06 | statuses and invoke the WebBrowserControl.
| | Collapse this transcript |
| Leveraging Internet Explorer| 00:00 | Now we are going to implement the detection of
links in individual Tweets and the invocation
| | 00:05 | of the WebBrowserTask in order to be able to see the
web page or the photo that's attached to that tweet.
| | 00:11 | And we are also going to talk a little bit
about tombstoning, which you need because
| | 00:15 | when the user goes off to the WebBrowserTask,
your app may not only be pushed into dormant
| | 00:19 | but may be pushed into the tombstone state.
| | 00:22 | And what we want to do is detect when we
come back from the tombstone state--which
| | 00:26 | is something you can do in the Windows Phone 7.5
SDK--and reload the list for them automatically.
| | 00:32 | So let's take a look at how that works and
how we can use some features in Visual Studio
| | 00:36 | to test to make sure that's
actually happening properly.
| | 00:39 | So first let's implement the detection
of links in the individual tweets.
| | 00:43 | We'll go to our TweetMonitor here and go down
to the MainListBox_SelectionChanged and bring
| | 00:48 | in a full implementation of that, and
let's take a look at what that looks like.
| | 00:52 | Since links in Tweets are not actually
hyperlinks in the traditional sense, there's no markup
| | 00:56 | to tell us that that's a link.
| | 00:58 | So what we actually have to do is to parse
the data ourselves looking for HTTP and then
| | 01:04 | determining the complete length of the link.
| | 01:06 | So as we always do in any ListBox_SelectionChange,
we check to make sure we're not getting a
| | 01:11 | SelectedIndex of -1. If we
are, we just get out of here.
| | 01:15 | If we have a SelectedIndex, we just ask the
ListBox for that Tweet object and in that
| | 01:20 | Tweet object we have the text
value from the Contents field.
| | 01:25 | And then we are going to just do some
pretty straightforward string processing.
| | 01:28 | We are going to go look to see whether or
not the letters HTTP appear there at all.
| | 01:32 | If they do, then we're going to start accumulating
text beginning at the HTTP until we run into a blank.
| | 01:39 | Because we're using the WebBrowserTask, we
don't have to be real persnickety about how
| | 01:43 | we gather the link, because if the link is
bad the WebBrowserTask will simply say bad link.
| | 01:49 | But for 99.9% of the Tweets out there, they
all have HTTP in them, and now we've got a
| | 01:56 | way of collecting that.
| | 01:58 | We take that result, we turn it into a string.
| | 02:00 | If we ended up with something greater length than
zero, we create an instance of the WebBrowserTask,
| | 02:05 | create a URI based on the link we
extracted, and tell the task to show itself.
| | 02:11 | If you tap on a Tweet and there's no link,
we'll put up a MessageBox saying No link
| | 02:15 | found in that tweet.
| | 02:17 | And then finally as always,
we set the SelectedIndex = -1.
| | 02:21 | So let's go ahead and run this version,
verify that we have our link detection running.
| | 02:25 | So once again, back to the TweetMonitor, type
in a twitter handle again, get a list of things.
| | 02:33 | Now you saw it say downloading,
and now it says download complete.
| | 02:36 | So you can see that our feedback to the user
is working, and let's go back to our TechCrunch
| | 02:41 | article for Smarter Apps, and we fire up the
IE web browser like we saw in the introductory
| | 02:47 | demo, and there's our page.
| | 02:48 | And now when we click the Back
button, we come back to our app.
| | 02:52 | Let's think about what happens
when we go after that WebBrowserTask.
| | 02:55 | Essentially it's opening up another application.
| | 02:57 | And we can see that by starting it up again
and then holding down the Back button to go
| | 03:03 | into multitasking mode.
| | 03:04 | So you can see there is the IE task, and here is our
TweetMonitor task actually running simultaneously.
| | 03:11 | If IE starts consuming large quantities of
memory, we might get booted out into the tombstone
| | 03:16 | state in which case when we hit the Back
button it will say resuming, relaunch our app, but
| | 03:22 | unless we handle the resuming logic properly,
we'll just end up with our blank user experience
| | 03:27 | with nothing in the ListBox and
nothing in the twitter handle.
| | 03:30 | Because we won't know that we've been
launched, and we need to go retrieve that.
| | 03:33 | So let's implement that.
We come back to our app here.
| | 03:38 | And now in the App.xaml code behind, there are a
number of methods such as Application_Activated,
| | 03:46 | Closing, Deactivated, and then Launching
that we can use to detect what's going on.
| | 03:51 | So let's put in a version of App.xaml
and take a look at what we've done there.
| | 03:55 | So we started out by putting in some debug
code into all these App_Launching, App_Activated,
| | 04:03 | Application_Deactivated, and Application_Closing
so that when we run the application, we can
| | 04:07 | see some things going on in the debug console.
| | 04:10 | In addition, beginning with Windows Phone
SDK's 7.5--I guess the SDK is I should call
| | 04:16 | 7.1, the consumer version of this is called
7.5--the ActivatedEventArgs that comes into
| | 04:23 | the Application_Activated handler here actually has
something that says IsApplicationInstancePreserved,
| | 04:29 | which is the Boolean flag that says, was
the app tombstoned by the operating system.
| | 04:35 | So we've declared a static variable called
AppWastombstoned, and every time we get called
| | 04:39 | here we set that variable so that we can
detect it in our page code, which we'll see in a
| | 04:45 | minute, and we then look at this flag and
write some stuff out so that we can see what's
| | 04:49 | happening with the app.
| | 04:51 | That's all we need to do here just to be clear.
| | 04:53 | We added this static Boolean property up here,
and we let it initialize to false by default.
| | 04:59 | We don't do it in the constructor because the
constructor would then set it so we wouldn't
| | 05:03 | be able to see it properly in the page.
| | 05:05 | So this is half of the tombstoning story.
| | 05:08 | For the second half of the tombstoning story,
we come back over here to our MainPage and
| | 05:13 | add some additional code.
| | 05:14 | What we are going to do is we are going
to add an implementation of OnNavigatedTo.
| | 05:19 | Now this gets called every
time we navigate to the page.
| | 05:22 | And so we call the base class to get all
the appropriate system things out of the way.
| | 05:27 | And then we start out by initializing our
text block, remember which is where we put
| | 05:32 | downloading, downloaded, and download
failure to the empty string because it's not quite
| | 05:37 | sure what we're doing with it yet.
| | 05:39 | And then we go from the Isolated Storage settings
and get the userHandle and put it into the textBox.
| | 05:45 | Now if we're coming back in here because we were
tombstoned, then we also need to reload the list.
| | 05:51 | And for coming back in here because we've
simply been reactivated from the dormant state,
| | 05:56 | the list is already intact,
and we don't need to reload it.
| | 05:59 | Now, you might be asking yourself, how do
we test this? Do I have to find an IE page
| | 06:04 | that's going to consume all of memory? No,
the nice folks at Microsoft added a property
| | 06:09 | on the project here in the Debug section which
says, tombstone upon deactivation while debugging.
| | 06:15 | So when we click this, when we go off to IE,
our application is going to be automatically
| | 06:21 | tombstoned so that when we come back
to it, we'll be able to test this code.
| | 06:25 | So, we're going to run it once this way,
and then we'll uncheck this and verify that it
| | 06:29 | will work in a non-tombstoned
situation as well. So here we go.
| | 06:33 | Back to the Emulator, I am going to
click Update, download some things.
| | 06:38 | You can see we got Application_Launching and
OnNavigatedTo output here, meaning we started
| | 06:42 | up the app, and we got to our page.
| | 06:44 | Now when we come down here and click on the link,
you are going to see Application_Deactivated.
| | 06:49 | That's the call that happens
when your app gets tombstoned.
| | 06:52 | Here we are in IE, now when we click the Back
button, saw the Resuming there very briefly,
| | 06:58 | the Application_Activated event got called, and
we detected that we were tombstoned reactivation,
| | 07:03 | so we set the flag.
| | 07:05 | When we came back to the page,
we reloaded the list from Twitter.
| | 07:10 | Now let's go and try the whole thing again
turning this flag off to verify that we work
| | 07:15 | when we are just in the dormant state.
| | 07:17 | Now here we go, we'll do our Update, we'll
scroll down, off to TechCrunch, you can see
| | 07:24 | we got Deactivated, but we're not actually
tombstoned, because when we come back, we
| | 07:28 | get OnNavigatedTo, but we're not tombstoned,
so we know that our list is already filled in.
| | 07:33 | And you can visually detect the difference,
because it doesn't say download completed,
| | 07:37 | because we didn't have to re-download
the data that's in our ListBox.
| | 07:41 | Now we've done the UX, we've accessed Twitter
with a web client, we've updated our network
| | 07:45 | connectivity to be more professional, we've
detected links, and we've handled tombstoning.
| | 07:51 | Time to move on to the live tile updates and
then finally on to the background agent processing.
| | Collapse this transcript |
| Adding a live tile| 00:00 | Time to take a look at Live Tiles.
| | 00:02 | When you pin an application to the homepage
using Pin to Start, as you know it uses the
| | 00:08 | second PNG file that you include in your
solution which is the background image, which is a
| | 00:12 | large 173x173 pixel image.
| | 00:17 | In addition, you can also update these properties--
the Title, the Background Image, and a Count--
| | 00:23 | using the ShellTile API.
| | 00:25 | Now, the count for this can only be from 0
to 99, which is why in Tweet Monitor, we didn't
| | 00:30 | use the Count badge because we wanted to show the
full number of tweets, not just the most recent tweets.
| | 00:37 | There is also a background for each Tile
as you've seen it flips over, and so there's
| | 00:43 | a background image, there's some
background content, and the Back Title.
| | 00:47 | Let's take a quick look at how you set these
things both statically and programmatically.
| | 00:52 | So, when we come and look at the properties
for our application, you can see we can set
| | 01:00 | the front title here, and we can set the icon
that's used for the small icon in the Applications list.
| | 01:07 | We can also set the title for the Live Tile, and
the background image that goes along with that.
| | 01:13 | We can't set the background image, the
background content, or the background title from here,
| | 01:19 | we have to do that programmatically.
So let's do a little bit of that.
| | 01:23 | First of all, open up our code, and we'll come
down here once we've got the string downloaded,
| | 01:28 | and we'll add a little code here, that
says get the Tile and do some updating.
| | 01:34 | However, you can see we need to include
another using, we need using Microsoft.Phone.Shell.
| | 01:45 | Now, when the tweets are in, we can actually set the
title of your Live Tile to the user's Twitter name.
| | 01:52 | We saw that when we saw the demo of the
application that had my Twitter handle over the lynda.com
| | 01:57 | Twitter handle on the back.
So let's go ahead and run this.
| | 02:01 | Make sure this works for us.
We'll do an update.
| | 02:05 | We'll come back to here, pin it to the start,
and in a minute when this flips over, it will
| | 02:11 | be the default color, but it will have our
Twitter handle on the bottom, and there we go!
| | 02:16 | Now, here in this code, we could have
accessed any of the things that are inside
| | 02:21 | StandardTileData, such as Count, Title, BackgroundImage,
Background Content, BackBackgroundImage, and so forth.
| | 02:30 | All right! Almost done with Tweet Monitor.
The next thing and the final thing we have
| | 02:34 | to do is to add our Background Agent, which
will allow us to do some background processing
| | 02:39 | even when our app isn't running
to update the tweet count.
| | Collapse this transcript |
| Building a background agent| 00:00 | Last thing we have to do is
to add our Background Agent.
| | 00:04 | Now, Background Agent is a special kind of project,
and we will take a look at that little bit here.
| | 00:09 | We will show how we would add one by hand, then
we are going to add our completed Background
| | 00:13 | Agent, and then talk about
what's different in there.
| | 00:16 | So, we start out here.
| | 00:18 | We would use this Windows Phone Scheduled
Task Agent project template to build it.
| | 00:24 | So let's add our existing project, and
we will take a look at what's inside.
| | 00:28 | So we want to go into here, and we want
the TweetMonitor background agent folder, and
| | 00:33 | we add the TweetMonitor agent project.
| | 00:36 | If we take a look at this, we will see that
this has pretty much standard system references,
| | 00:40 | but we have two classes in here, one is TweetData,
and this is copy of the Tweet.cs we have in
| | 00:47 | the other project, but we can't call it the
same thing because we have to actually add
| | 00:51 | a reference to this Tweet
agent to our main project.
| | 00:55 | If we have the same Tweet.cs, VisualStudio
keeps warning us that it could be confused.
| | 01:00 | So we rename it TweetData.
| | 01:02 | Then we have the ScheduledAgent class, which
we'll take a look at here in just a second,
| | 01:06 | and if we look at the Project Properties, you see
it's a little different because this is an agent.
| | 01:12 | We don't have a Xap file name or a
Startup object or Live Tile options.
| | 01:16 | So those things are all grayed out,
because this is the piece of code that's going to
| | 01:20 | run with no visible user interface
other than the Live Tile field updates.
| | 01:25 | Now, in order to make all this work, we do
two things, one: we come to the TweetMonitor,
| | 01:30 | and we have to add a reference
to the TweetMonitorAgent project.
| | 01:36 | This does something which you don't see
unless you actually go and look. It actually did
| | 01:39 | some updating to the AppManifest.
| | 01:42 | If we go here and reformat this so we can
see it a little better, we come down here,
| | 01:48 | and we can see now there's a
BackgroundServiceAgent inside the Task section.
| | 01:53 | In a non-background agent app, all you have
is this DefaultTask section which simply says
| | 01:59 | the DefaultTask should
start with this particular page.
| | 02:02 | When we have an ExtendedTask section such as
this, you see we now have a BackgroundServiceAgent
| | 02:08 | tag, and we have a specifier that says
it's a ScheduledTaskAgent, and we specifically
| | 02:13 | call out its name, it's TweetMonitorAgent,
its sources is called TweetMonitorAgent, and
| | 02:18 | its type is TweedMonitorAgent.ScheduledAgent.
| | 02:21 | So let's go take a look at the code for the
ScheduledAgent and see how it actually works.
| | 02:26 | Let's start at the top.
| | 02:28 | First of all, we have a flag to tell us
whether or not our agent has been initialized,
| | 02:33 | and we have a variable in which we keep track of the
Twitter handle that we are going to go get data for.
| | 02:38 | When we take a look at the code in the StartAgent
button, you will see that when we create an
| | 02:44 | agent, we've got one place where we can pass data
to the agent, and that is the Description field.
| | 02:50 | So what we do to start with is if we're not
initialized, we've set our Initialized flag
| | 02:54 | to true, and then we call BeginInvoke and create a
delegate so that we can handle UnhandledExceptions.
| | 03:01 | When the system wants to update a background agent,
it calls the OnInvoke method passing the task object.
| | 03:07 | In that task object, because we're going to
put the user handle in the description, we
| | 03:11 | pull the description out and put it into
our Username field, and then we call a method
| | 03:15 | that we've written called UpdateAppTile,
UpdateAppTile simply calls DoTheUpdate, and DoTheUpdate
| | 03:23 | is the same kind of two-stage asynchronous web REST
API call that we did before in the main application.
| | 03:30 | We go call the Twitter API, and then deal with the
results in the DownloadStringCompleted event handler.
| | 03:35 | Here we do a little bit of different processing
on it because we're not going to display the
| | 03:39 | tweets, we simply want to go get the tweets primarily
to get the outer wrapper for that particular TweetData.
| | 03:46 | So we go and get the tweets, we process everything,
and then we grab the title because we want
| | 03:51 | to update some of the fields.
| | 03:52 | Now, we go grab the TweetData, and now we
update the front title to the number of tweets--
| | 03:57 | or statuses as Twitter calls them--and we
update the back title to the Twitter handle
| | 04:02 | or the username, and then we call AppTile.Update
which is what actually causes the tile to be updated.
| | 04:09 | And finally, if there's anything that happens
with our background task, we set up a handler
| | 04:13 | for UnhandledExceptions so that we can
debug our background task when it happens.
| | 04:17 | All right! The last thing we have to do is come to
our MainPage.xaml and implement the StartAgent button.
| | 04:23 | So, come down here to the bottom
and stick in some additional code.
| | 04:30 | So here's the code that handles the click
for the StartAgent button, and here is the
| | 04:34 | implementation of the StartAgent button.
| | 04:36 | So we look to see first of all, do we have a
Twitter handle? If we don't have a Twitter
| | 04:39 | handle, then we put out a message box, because
there's no way we can start a background task,
| | 04:43 | because we need to provide the
background task the name of the Twitter handle.
| | 04:48 | We also need to create a constant string to
put the name of the task in because that's
| | 04:52 | going to show up in the Settings
application as the name of our task.
| | 04:55 | So we'll come up to the top here, and say
private const string TASKNAME = "TweetMonitor",
| | 05:06 | and we'll come back down to our button2_Click.
| | 05:09 | So now we've set up a periodic task and set up
the task name, and then we set the task.Description,
| | 05:16 | as we mentioned we were looking at the
ScheduledAgent from the text box, so we have got the user's
| | 05:21 | Twitter handle, and then we add that
task to the ScheduledAction service.
| | 05:26 | Now, there's a number of rules for when
these tasks actually get invoked, especially
| | 05:31 | on a real device, which is
something like every 30 minutes.
| | 05:35 | But obviously, you don't want to press F5 and
then wait 30 minutes to find out if your code works.
| | 05:39 | So, if we're debugging, we actually call
LaunchForTest, and ask for the test task to be hit right
| | 05:45 | away so that we actually get to
see what happens in short order.
| | 05:49 | One other thing we did is in our StartAgent,
if you click Start more than once, we want
| | 05:55 | to make sure that we stop the task here
before we start it again so that we don't end up
| | 06:00 | with the tasks running at the same time.
| | 06:03 | All right! That's it! Let's give it
a try and see if it's going to work.
| | 06:08 | Up to the Emulator, make sure we got
connection to Twitter, we do, click Start Agent, come
| | 06:16 | to the Live Tile here and see what happens.
| | 06:18 | In a minute, we'll see the Live Tile
flip over there with our Twitter handle.
| | 06:23 | But nothing is happening, why is our BackgroundAgent
not running? I just realized why, and it's
| | 06:27 | a good thing to go and fix.
| | 06:29 | So we will stop this, and it's because our
XAML doesn't connect up to the right thing.
| | 06:36 | So we have got button2_Click here,
but we didn't actually start the task.
| | 06:41 | So let's put some debug output here, and then
let's go look at our XAML, and make sure that
| | 06:47 | the button that we want, this one actually
is connected up to a click, which it isn't.
| | 06:52 | So let's set that to Click="button2_Click"
and save all this.
| | 07:01 | Once again, there we are, Twitter connectivity, woo-hoo!
Click Start Agent, now we see Agent started.
| | 07:09 | Now, we'll go back here.
| | 07:11 | In a minute over here, we will see that the
background agent code is actually going to get loaded.
| | 07:17 | There we go! Background task is loading.
| | 07:19 | Now, the next time that flips over,
it's going to have our Tweet count in it.
| | 07:23 | You see our task got started, now we have
our user handle, and there we go, 3885 tweets,
| | 07:31 | and if we were patient enough to wait here
for half-an-hour, and we added another Tweet,
| | 07:34 | we'd see that update.
So, that's it, TweetMonitor is done.
| | 07:38 | We have got web access, Network Connections,
Network Detection, use of web client, use
| | 07:44 | of the web browser task, Live Tiles, and a background
agent all that all wrapped up into a single app.
| | Collapse this transcript |
|
|
10. Leveraging Built-In Tasks and the Silverlight and Coding4Fun ToolkitsExploring built-in controls| 00:00 | So we've built seven apps all the way from
the simplest Hello World to the more complex
| | 00:06 | of take a note and Tweet Monitor.
| | 00:08 | But we've just scratched the surface of all
of the exciting capabilities that are still
| | 00:13 | available in the Windows Phone
operating system that you can use in your apps.
| | 00:17 | Come to this page, this is another great
landing page for you on MSDN that covers all of the
| | 00:23 | high-level concepts that you need to
understand to build Windows Phone apps of all kinds.
| | 00:29 | We've covered some of the things already such
as Frame and Page Navigation and Local Data
| | 00:34 | Storage and some of the Networking Services.
| | 00:37 | If you're building an application for a low
memory phone--or especially if you are still
| | 00:41 | building something for the old Windows Phone
7.0 operating system--studying the Execution
| | 00:47 | model section here would be of great value because
you'll need to understand what's called tombstoning.
| | 00:52 | In the modern 7.1 operating system many apps
aren't even dealing with tombstoning because
| | 00:57 | multitasking gives you the capabilities
automatically delivered by the operating system.
| | 01:02 | The other major thing that you'll most likely
use in one of your apps, one way or the other
| | 01:06 | are the Launchers and Choosers.
| | 01:08 | Now these basically allow you to take
advantage of facilities that are in the Windows Phone
| | 01:12 | operating system and use them inside your app.
| | 01:15 | For example, in Launchers we've seen
already the email composer task that we use in the
| | 01:20 | About box for each one of our apps.
| | 01:22 | But there's also ways of interacting with
big maps, there's ways of interacting with
| | 01:26 | the marketplace and the phone system and
search and the Twitter and Facebook integration,
| | 01:33 | text messaging, and web browsers,
and then there's also Choosers.
| | 01:37 | So that when the user wants to pick an address,
take a picture, pick someone's email address
| | 01:42 | from their people hub, invite someone into
a game session, pick a photo from the photo
| | 01:47 | library, you'll want to
use one of these choosers.
| | 01:50 | Now in addition to the Pickers and Choosers,
there's also a whole bunch of controls in
| | 01:54 | the Toolbox that would also be
useful for you to using your applications.
| | 01:58 | So let's just take a quick
look at the tools in the Toolbox.
| | 02:01 | There is an AdControl that allows
you to put advertisements in your app.
| | 02:04 | If you want to release a free app that's ad supported,
there is some visual Borders, reviews buttons.
| | 02:11 | Canvas is a layout section where anything put
in the canvas is located on the pixel basis.
| | 02:16 | Grid is a layout section which allows you
to define rows and columns, similar to the
| | 02:21 | way you would do it with a web page and to
be able to say here's my rows and columns,
| | 02:24 | and this one spans three columns.
| | 02:26 | This is also very useful for apps which have
a useful life in multiple phone orientations
| | 02:31 | whether it's portrait or landscape, in this
case the grid will automatically recalculate
| | 02:36 | the pixel sizes of the controls and in
some cases give you a sufficient new layout so
| | 02:40 | you can just use the automatic
layout features of the phone.
| | 02:44 | Sometimes you actually need to be able to
handle orientation changes and simply switch
| | 02:48 | to a completely different page or have a separate
section that you hide and show to do the orientation layout.
| | 02:55 | Ellipse and Rectangle, we've used rectangle before,
Ellipse is way of creating circles and ellipses.
| | 03:01 | Hyperlinkbutton is a way of creating a piece
of text with a hyperlink in it so that when
| | 03:06 | you touch it, it will either take you to
navigate to another page or will open up a web page.
| | 03:11 | We've seen the Image with the gold star we
used in the favorite section of the Sonics app.
| | 03:16 | You've seen we've used the ListBox, Map allows
you to embed big maps directly into your app.
| | 03:21 | MediaElement is a way of being
able to show movies and play sounds.
| | 03:26 | PasswordBox is another equivalent of TextBox
except that it masks that the text is being input.
| | 03:31 | Radiobutton are the kind of thing, I'm sure you're
familiar with it if you build any other Silverlight apps.
| | 03:36 | ScrollViewer is a way outside of a ListBox
of creating something at which the user can
| | 03:40 | scroll one way or another, sliders allow you
to make some various changes, and we'll see
| | 03:45 | some really nice fancier sliders in
the toolkits we're about to look at.
| | 03:50 | StackPanel is similar to Grid except that
everything just stacks up one on top of the
| | 03:55 | other from top to bottom.
| | 03:56 | We've used TextBlock and TextBox and WebBrowser,
again, as a way of allowing you to embed a
| | 04:01 | web browser in the middle of your app.
| | 04:05 | So that's what's in the operating
system as provided by Microsoft.
| | 04:09 | There are two really great free and open-
source toolkits, the Silverlight toolkit for Windows
| | 04:14 | Phone, and the Coding 4 Fun toolkit for
Windows Phone, both from Microsoft that we'll take
| | 04:20 | a look at now so you can see what kinds of facilities
are in there that you can also use in your apps--
| | 04:25 | and customize if you want,
because those are open source.
| | Collapse this transcript |
| Looking at Silverlight| 00:00 | The first of the two open source and free
toolkits for Windows phone we are going to
| | 00:04 | take a look at is called the
Microsoft Silverlight toolkit.
| | 00:07 | You can download both the binaries and the source
code for this toolkit from here: silverlight.codeplex.com.
| | 00:14 | And as of the time we are writing this course,
you definitely want to get the November 2011
| | 00:18 | version, because that works with the Windows Phone 7.1
SDK that is on all the devices currently being shipped.
| | 00:25 | So let's switch over to Visual Studio
and take a look at what's in the toolkit.
| | 00:29 | There is everything from the AutoCompleteBox
to a set of Date and TimePickers, all the way
| | 00:34 | to a WrapPanel, and all these controls allow
you to do things that are either similar to
| | 00:42 | or functionally equivalent to some of the
capabilities used in the native apps on the
| | 00:47 | phone, such as mail and messaging, and the
settings class allows you to do those
| | 00:52 | in your C# written applications.
| | 00:55 | So let's fire up this app and
take a look at it in the Emulator.
| | 00:58 | So, this is a sample application that comes
with the Silverlight for Windows Phone toolkit
| | 01:04 | that shows various controls.
| | 01:06 | As we saw in the Solution Explorer, the
samples in the Silverlight for Windows Phone toolkit
| | 01:11 | range from autocomplete textbox to Wrap Panel.
Autocomplete textbox, for example, is the
| | 01:16 | kind of thing you see when you type here and
start typing a word and a suggested list will show up.
| | 01:22 | The list of suggestions that's used here in the
sample is the well-known advertising gobbledygook
| | 01:26 | text called Lorem Ipsum
which is a selection of Latin.
| | 01:30 | We will start typing L-O, we will see there,
and we will click here, and it will automatically
| | 01:35 | type in the rest of the word for us.
| | 01:39 | ContextMenu can be very handy.
| | 01:41 | You click on something and hold, and the
menu shows up that's contextual to exactly the
| | 01:45 | thing that you were clicking on.
| | 01:48 | The Date and Time Pickers are very, very
valuable because these are things which are available
| | 01:53 | to the native apps on the Phone, but if you
want to have this functionality in a C# app
| | 01:59 | that you are writing, you
have to use the toolkit.
| | 02:01 | For example, here this allows us to select
a Date, we can select next Monday, or we can
| | 02:08 | change the Time, go to PM,
and make it sometime afternoon.
| | 02:17 | One of the other things that's good in here
has to do with the tilt effect, because you
| | 02:21 | can see as you touch the button, it animates.
It goes down and tilts back up. Or the same
| | 02:26 | thing with the check box, you
can see it sort of tilt back.
| | 02:29 | It just gives a little bit of extra visual
feedback to your users that when they have
| | 02:32 | tapped something or they've actually
physically pushed on something on the screen.
| | 02:37 | All right! That's the Silverlight for Windows
Phone toolkit, now let's take a quick look
| | 02:42 | at the Coding4Fun toolkit.
| | Collapse this transcript |
| Introducing Coding4Fun| 00:00 | Now let's take a look at the second of our
free and open source toolkits for Windows
| | 00:04 | Phone development, the Coding4Fun tools.
| | 00:07 | You can download both the binary and the source code
for Coding4Fun toolkit from coding4Fun.codeplex.com.
| | 00:14 | Now let's go take a look at this in Visual Studio.
| | 00:17 | You can see there is everything from ChatBubble to
NewColorPickers to MetroFlow to NewmessagePrompts,
| | 00:27 | all the way down to new toggle
buttons and new Toast and ProgressOverlays.
| | 00:33 | Anything that you could want to spruce up your
app to make it look more visually compelling.
| | 00:38 | So let's fire this app in the emulator
and take a look at these things in action.
| | 00:42 | So, we got three different color pickers.
| | 00:45 | This is a nice color hexagon. As you move
around the square, you can see down here at
| | 00:49 | the bottom of the screen the actual color changes.
| | 00:54 | There is an Actual Color Picker, so you
can literally move this around the screen like
| | 00:57 | this and pick exactly the color that you want.
| | 01:01 | And there is a set of sliders. There is also a
bunch of additional buttons which are very nice,
| | 01:06 | you can use them in your apps.
| | 01:12 | And they also work on color backgrounds.
| | 01:16 | They have a control here called Metroflow,
which allows you to switch pictures like this
| | 01:22 | or like this. Of course, the images can be larger
than this, this just happens to be a sample version.
| | 01:31 | They have what they call the Super slider, so
you can have slider that this very continuous
| | 01:35 | or slider that actually has discrete steps.
| | 01:39 | If you are doing integers,
you don't need 6.0087719298.
| | 01:47 | There is a Time Span Control, so you can say I
need this for 31 minutes, which is different--
| | 01:52 | of course the duration is different than the actual
time, so that's very useful in a lot of applications.
| | 01:59 | And there is ChatBubbles, which allow you
to build a text messaging app, and they have
| | 02:05 | bubble arrows that can show up on any place that
you want, you can obviously change colors and so forth.
| | 02:12 | And they were very nice built in About control.
| | 02:15 | We have built a full About page in all of
our apps, because we wanted to include a number
| | 02:19 | of additional buttons and functionality on them.
| | 02:22 | But here, you can actually just create additional
About boxes with a very small amount of code.
| | 02:29 | And this additional binding capabilities and
overlays and additional Prompt Capabilities
| | 02:35 | that allows you to create things up here
in the top, to make it look like system toast.
| | 02:40 | Again, a great collection of all kinds of
additional controls that you can use in your apps.
| | 02:46 | Like here, we talked about before about using
either MessageBox or the GamerServices MessageBox.
| | 02:54 | Here's yet another kind of MessageBox in
which you can actually have icons and of course
| | 02:58 | change the text to whatever you want.
| | 03:01 | And that's it for the
Coding4Fun Windows toolkit overview.
| | 03:05 | I highly suggest you download this and
go through all these different samples.
| | 03:09 | I am sure you will find something that
will be useful for you in building your apps.
| | Collapse this transcript |
|
|
11. Where to go from herePublishing your apps| 00:00 | In the process of developing this course,
we visited hundreds of web sites, looked at
| | 00:04 | dozens of books, and read countless articles.
| | 00:08 | We have gathered together all the useful
links for web sites, books, podcasts, and beyond
| | 00:14 | to help you get from zero to hero.
| | 00:17 | We have also included them all in a document in
the exercise files in the free exercise files.
| | 00:21 | So, you do not have to try to look at the
address bar here in the browser and write
| | 00:25 | any of these things down.
| | 00:26 | You'll be able to click on them directly.
| | 00:28 | So let's get started. First up, we are
going to talk about publishing your apps.
| | 00:33 | The Windows Phone Developer tools are free.
| | 00:36 | You can download the tools, build
apps using the emulator for zero charge.
| | 00:41 | When you decide you actually want to
publish your app, you need to join the APP HUB, you
| | 00:46 | need to join the Microsoft Developer Program.
| | 00:48 | Now, the Microsoft Developer
Program is $99 a year.
| | 00:53 | As you can see, for Windows Phone, that
gives you the ability to make free, paid or aid
| | 00:57 | funded apps, Submit an unlimited number of paid
apps to the Marketplace and up to 100 free apps.
| | 01:03 | If you want to build more than 100 free
apps, you can see it costs 20 bucks each.
| | 01:09 | All apps that you submit are Content and
Code certified to make sure that they will run
| | 01:13 | on all the Windows Phone handsets out there.
| | 01:16 | To join the App Hub Program for publishing,
you come to this page and click on join now.
| | 01:22 | In case you are wondering why we are not
going through the whole submission process, it's
| | 01:25 | because Microsoft makes frequent changes to
the certification and the submission process.
| | 01:30 | So the page that you see here may not
look like this by the time you get there.
| | 01:35 | So you want to look at the page the way it looks,
when you get there and follow those instructions.
| | 01:39 | Microsoft has also provided a full how it
works page for the App Hub, describing how
| | 01:44 | the App Hub works, about the free tools, how
to get special help, how to sign up for the
| | 01:51 | Developer Program and about how to connect
up once you've signed up for the Developer
| | 01:56 | Program to be able to track the apps that
you have submitted to the Marketplace and
| | 02:01 | watch your downloads and sales.
| | 02:04 | Finally, when you are completely ready, you are
the member of the App Hub, you are a Certified
| | 02:08 | Developer, and you have got your app ready to go.
| | 02:11 | You need follow through the instructions
you see on the screen here.
| | 02:14 | These four steps to Submit your Application.
| | 02:17 | You got to make sure that you've got everything in
your .XAP package, a proper name for the App Hub,
| | 02:22 | how it's set up for Distribution as we
upload the XAP file from the build that you did,
| | 02:28 | make sure you got the proper version number.
| | 02:30 | And if you need a technical exception,
because there are some aspects of the certification
| | 02:34 | process, you can ask Microsoft for specific
exceptions, and of course, on a case-by-case
| | 02:39 | basis they will make that decision.
| | 02:41 | Microsoft has even included some best practices
for application marketing to help you figure
| | 02:46 | out how to get the most
people to download your app.
| | Collapse this transcript |
| Learning from apps in the Windows Phone Marketplace| 00:00 | One of the best places to learn what works
and what doesn't work for real Windows phone
| | 00:05 | owners is to visit the Windows Phone Marketplace
and take a look at the apps that are already there.
| | 00:11 | There are four different lists that Microsoft
provides, and it's updated on a daily basis.
| | 00:17 | The Featured list, the Free list, Top
list, and the list of Newest apps.
| | 00:23 | And if we going to go look, for example,
at Whether Flow, here is a good example of a
| | 00:27 | description, screenshots, and you can read the
seviews and see what people actually think about it.
| | 00:35 | So find apps that are like your app and
read the reviews, read the descriptions, model
| | 00:41 | yourself after someone who has been successful.
| | 00:45 | So we can take a look at the Free Apps, we
can take a look at the Top Apps you can see
| | 00:50 | a lot of Top apps are games,
here is Angry Birds and Fruit Ninja.
| | 00:53 | And one of the most useful list is the New
apps, because you can see what the latest
| | 00:59 | and greatest innovations that you and your
fellow Windows Phone app developers are building.
| | 01:05 | This page changes every day based on the apps
that have just been approved to the Marketplace.
| | 01:11 | The one that you won't find here of course are
reviews, because these apps just got released.
| | 01:16 | But you'll find a wealth of information about
the kinds of things that you and other developers
| | 01:19 | like you think customers want to buy.
| | Collapse this transcript |
| Staying in touch with updates and new information from Microsoft| 00:00 | As of the time that we're recording this
course, Windows Phone has been publicly available
| | 00:04 | about a year and a half.
| | 00:06 | There's been a lot of changes in that year and a half
from the point of view of a developer, because
| | 00:10 | Microsoft has released a major new update
of the operating system, Mango--aka Windows
| | 00:15 | 7.5 to end users and Windows 7.1
SDK to you as a developer.
| | 00:21 | So you need to know where to stay in touch
with the latest and greatest updates from
| | 00:26 | Microsoft, because Windows 8 is coming and
Windows Phone 8 coming sooner than later.
| | 00:31 | The first thing you want to do is
Bookmark this, the Windows Phone Developer Blog.
| | 00:35 | This is the official mouthpiece of the
Windows Phone team at Microsoft, and everything that
| | 00:41 | is coming, they are going to announce it on
here and give you the greatest detail that
| | 00:45 | you can get with the official word.
| | 00:48 | MSDN is your absolute greatest site for
nuts and bolts developer information, and this
| | 00:54 | is the place to start.
| | 00:56 | The Windows Phone Development Page now, I'm
showing you the English United States page.
| | 01:01 | If you're in a different country, just search
for MSDN and Windows Phone Development, and
| | 01:05 | you'll find the homepage that applies
to your particular variation of MSDN.
| | 01:10 | But this page includes everything that's new,
how to get started, learning resources, including
| | 01:16 | the code samples and information on how to
publish your apps and games, as well as more
| | 01:21 | community resources ones that
have been curated by Microsoft.
| | 01:25 | There is a really great group at
Microsoft call Patterns and Practices.
| | 01:30 | This group not only gives out information
on what you need to do to build an app or
| | 01:35 | to build an application for Windows, they are
very specific at always creating step-by-step
| | 01:41 | instruction that gives you best practices.
| | 01:45 | For Windows Phone there's no exception,
they've created three books to date, beginning with
| | 01:49 | Developing a Windows Phone Application
From Start to Finish. If you get this content,
| | 01:54 | you can either get it in book form or read
it on MSDN, and it will take you step-by-step
| | 01:59 | through not only what you need to do, but
why those things make sense and where are
| | 02:04 | the gotchas as you're going through this that
you might want to watch out for as you build
| | 02:08 | your own apps, highly recommended.
| | 02:10 | And finally, you probably already know about
this, but if you go to windowsphone.com, you
| | 02:16 | get to see the entire gamut of
everything that Windows Phone users see.
| | 02:21 | You can figure out which phone you want to
buy, you can go to the Marketplace, you can
| | 02:25 | figure out how to operate the
Windows Phone operating system.
| | 02:28 | This page is your best friend in order to
understand what your users are actually seeing.
| | Collapse this transcript |
| Looking at Windows Phone 7 app reviews| 00:00 | Once you've finished your app, the next big task
that you have to do is to let everybody know about it.
| | 00:06 | And one of things that builds up in a developer
ecosystem, especially on mobile devices, are review web sites.
| | 00:13 | We found three review web sites that look
like they have unbiased opinions about things
| | 00:18 | and great information.
| | 00:20 | Specifically one of the great things here
on WP7applist is this little box over here
| | 00:24 | that has Marketplace stats every day.
| | 00:26 | It says as of the time we are recording
this course, there were 77,755 apps worldwide,
| | 00:32 | 65% are free, and the average price is $1.45.
| | 00:36 | And it also says 303 apps are updated every day.
| | 00:40 | So as you get busy building and shipping apps,
you will learn that updates are your best
| | 00:44 | friend, because it keeps your application
name and purpose in front of your customers.
| | 00:49 | So every two weeks, every month, every two
months, if you make some change, your customers
| | 00:54 | will get notified, that hey,
take a note, it has a new update.
| | 00:57 | And that'll bring back to their mind that, oh,
that's right, I got that take a note that
| | 01:01 | maybe I should use that or maybe now it has
the feature I really wanted, so I am going
| | 01:04 | to go back and start using that again,
and of course, recommend it to my friends.
| | 01:08 | Another really great Windows Phone
at web site is WPApp info, and
| | 01:13 | as you can see, they have detailed information
about apps, they also have a list of the top
| | 01:18 | free apps and the top paid apps, and they
also have ratings so that in addition to the web
| | 01:23 | site, you can see how many people have
rated the app and what they rated it.
| | 01:27 | Of course, they have lots of reviews with
Screenshots and also a list here of the Newest
| | 01:32 | apps, free and paid, similar
to what's on the Marketplace.
| | 01:36 | And finally, WindowsPhone Geek, which
is a partner web site with WPApp info.
| | 01:40 | There are not a lot of reviews on this site,
but there is a huge amount of information,
| | 01:44 | and oftentimes you'll find information here that
links to specific reviews on the other web site.
| | 01:50 | So as you figure out the process of dealing
with the many arms of the spiral galaxy which
| | 01:55 | is Windows Phone development, you know, sometimes
you will find out you don't have to understand
| | 01:59 | everything everywhere, but you may need to
focus on one particular section, but you'll
| | 02:04 | find here on Windows Phone Geek a lot of information
that says if you're working on this section,
| | 02:08 | this other section over here of that Spiral
galaxy might really be of great interest to you.
| | Collapse this transcript |
| Exploring web sites, books, and other useful links| 00:00 | And finally, books, podcasts, and other
useful web sites. Depending on how long you have
| | 00:05 | been doing development for Microsoft Technologies,
you may go all the way back to the original
| | 00:10 | Programming Windows by Charles Petzold.
| | 00:12 | He has made an update of that book for every
single version of Windows that's been released,
| | 00:17 | and now Microsoft commissioned him to make a
Programming Windows Phone 7 book, and they're
| | 00:21 | giving it away for free.
| | 00:22 | So you get 1,000-page eBook here by the
granddaddy of them all, Charles Petzold.
| | 00:27 | This is definitely worth downloading,
there is a lot of information in here, it's not
| | 00:31 | necessary to read the entire 1,000 pages from
beginning to end, but it's a great reference book.
| | 00:36 | In the Leveraging Built-in Controls and Toolkits chapter,
we talked about the Silverlight toolkit for Windows Phone.
| | 00:42 | Boryana Miloshevska has written a great book
that's free, but she has a Donate button there,
| | 00:48 | that actually goes into all of the details
of how to use every one of the controls in
| | 00:52 | the Silverlight toolkit,
this is highly recommended also.
| | 00:56 | Since you're taking this course, you're most
likely building Windows Phone apps for Silverlight
| | 01:01 | as opposed to building games.
| | 01:02 | Volume 1 of Adam Nathan's 101 Windows
Phone 7 Apps is absolutely priceless.
| | 01:09 | He not only has built 50 apps, but he explains
why he did, what he did, and each one of those
| | 01:15 | 50 apps and the full source code for
all of the applications is available.
| | 01:19 | So you can open them up in Visual Studio
and take them apart and look at them and tweak
| | 01:23 | them and decide and really learn from a master.
| | 01:26 | And finally, another book which is just
been released is the Windows Phone 7.5 Mango
| | 01:32 | Nuts and Bolts book from Falafel Software.
| | 01:34 | It starts out with a great introduction to
Windows Phone development, and again, contains
| | 01:39 | lots of concrete examples that you can follow
through step by step to solve particular problems
| | 01:44 | when you get there especially related to
the new features in Windows Phone 7.5 Mango.
| | 01:50 | One more book that's on the must-read list if
you're building Windows Phone apps, Essential
| | 01:54 | Windows Phone 7.5: Application
Development with Silverlight.
| | 01:58 | Shawn Wildermuth is a Microsoft MVP, and he's
been working with XAML and the WPF and Silverlight
| | 02:03 | for years and has a really great introduction
to using XAML in the context of Windows Phone
| | 02:09 | and again, lots and lots of nuts and bolts
descriptions on how to do specific things.
| | 02:14 | When you need to figure out how to do something,
if you can't find the answer on Microsoft's
| | 02:17 | web site or the answer is not as clear as
you like, he will have an example that will
| | 02:21 | help you get through that.
| | 02:23 | Beyond books, another really
useful resource is podcasts.
| | 02:27 | Over here on Channel 9 you can see Microsoft
has 423 entries--as of the time we're recording
| | 02:31 | this podcast--talking about things that real
people have dealt with in building Windows Phone apps.
| | 02:38 | Another great place to find
Podcasts is over here at developerFusion.
| | 02:41 | Here you can find information on Scott Hanselman's
Hanselminutes, Deep Fried Bytes, .NET Rocks
| | 02:47 | from Carl and Richard Franklin, a whole wealth
of Podcast that will help you learn the things
| | 02:53 | you need to know and keep yourself up to date on
the latest developments in .NET and Windows Phone.
| | 03:00 | Now a discussion of resources for Windows
Phone would be totally incomplete without
| | 03:04 | talking about user experience.
| | 03:06 | Arturo Toledo, one of Microsoft's
UX gurus has a 31-week series.
| | 03:11 | He says it's 31 weeks, he hopes
to get it done in less than that.
| | 03:15 | But the 31-week series on Metro Design
Principles and how to apply them to Windows Phone,
| | 03:19 | how to decide what fonts to use, how to decide
color schemes, how to decide layouts that
| | 03:25 | make sense that are intuitive, and how
to really know what Metro really means.
| | 03:31 | Jeff Blankenburg is a blog author who has
created two really great 31-day series for
| | 03:37 | Windows Phone development.
| | 03:39 | His first series, which he released in September
of 2010, is called 31 Days of Windows Phone,
| | 03:45 | and then when Mango came out he did
an update called 31 Days of Mango.
| | 03:49 | And one of the cool things about 31 Days
of Mango is he also put all 31 days worth of
| | 03:54 | applications into an app and put it on the Windows
Phone Marketplace that you can download for a dollar.
| | 03:59 | So you can not only learn from all those projects,
you can actually see how they actually work
| | 04:03 | on the phone and learn how to
use all these controls in action.
| | 04:07 | And finally, one place that Microsoft has
tons and tons of useful content is they have
| | 04:12 | a How-To Index for Windows Phone, in which
there are sample applications for everything
| | 04:17 | you can imagine, everything from how to use
the Application Bar, to how to read Raw sensor
| | 04:22 | data from the camera if you want to build
an augmented reality application, to how to
| | 04:27 | make sure that you're optimizing your device for the
new 256 Megabyte smaller versions of Windows Phone.
| | 04:33 | Everything you need to know
you can get to it from this page.
| | 04:35 | And last but not least, you can go to dreamtimestudios.com/blog
where we'll keep all these links up to date,
| | 04:42 | and of course, don't forget to visit lynda.com.
| | Collapse this transcript |
|
|
ConclusionFarewell| 00:00 | Thanks for taking Windows
Phone SDK Essential Training.
| | 00:04 | Windows Phone is an exciting and rapidly changing
environment, so be sure to come back to lynda.com
| | 00:09 | for the latest and greatest training.
| | 00:10 | We're publishing all six of these sample
apps as free downloads on the Marketplace.
| | 00:14 | When you publish your apps, please drop by
dreamtimestudios.com/blog and let us know
| | 00:19 | so we can help you spread the word.
See you on the Marketplace.
| | Collapse this transcript |
|
|