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
| | 00:04 |
Windows Phone and get hands on experience
making apps using the SDK.
| | 00:09 |
The seven apps we're going to build
encompass the techniques, technologies,
| | 00:12 |
and design elements you need to know to
build and debug apps using Visual Studio.
| | 00:17 |
The Windows Phone Emulator, and your
Windows Phone handset.
| | 00:21 |
During this absolute value they quickly
internalize development cycle.
| | 00:24 |
And learn how to accomplish the kinds of
things we already know like page flow,
| | 00:27 |
file IO and network access the windows
phone way.
| | 00:31 |
How do you know you're ready to take this
course?
| | 00:33 |
Well, you are if you know how to use
visual studio right code and C# and build
| | 00:38 |
very simple user experiences in XAML.
If you need a referesher on Visual Studio
| | 00:43 |
or writing code in C# or learning how to
build user experiences in XAML, Lynda.com
| | 00:48 |
has essential training courses for all
three.
| | 00:50 |
| | 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, lets get started building windows
phone apps.
| | 00:03 |
First, we've to install the tools.
If you've already worked your way through
| | 00:07 |
Doug Winnie's, up and running with
Windows phone 8 development.
| | 00:09 |
You can skip to the next chapter because
we'll be covering the same ground here by
| | 00:13 |
installing the development tools.
Building apps for Windows phone 8
| | 00:17 |
requires the installation of Visual
Studio 2012 and the windows phone 8
| | 00:20 |
developer tools.
For Windows phone 7, you'll will need
| | 00:24 |
Visual Studio 2010 and the Windows phone
7 developer kit.
| | 00:28 |
If you already have Visual Studio
Professional or Ultimate in the
| | 00:31 |
appropriate flavor, you just need to
download the tools and use the version
| | 00:35 |
you already have.
If you don't already have Visual Studio,
| | 00:38 |
the developer tools include a version of
Visual Phone Developer Express, which is
| | 00:42 |
a free version, suitable for phone
development in C sharp.
| | 00:46 |
To get set up, you go to the Microsoft
Developer Network or msdn.microsoft.com
| | 00:50 |
and click on the Windows Phone hub.
Then, you can click on the big GET SDK
| | 00:55 |
button right here and download the tools
to be able to build Windows phone apps.
| | 00:59 |
Windows phone 7 requires Windows Vista or
Windows 7.
| | 01:04 |
For Windows phone 8, you require Windows
8 Pro or above and a 64-bit CPU.
| | 01:10 |
In addition, the Windows Phone 7 emulator
requires some specific version of
| | 01:14 |
Microsoft DirectX, a specific Windows
driver, and some specific Microsoft
| | 01:20 |
Direct3D drivers.
If you have a system that's 2009 or later
| | 01:24 |
and you're running Windows 7, you
probably already have those drivers installed.
| | 01:29 |
The Windows phone Emulator can also
require GPU emulation to support certain
| | 01:33 |
scenarios, such as profiling, XNA
Framework applications for Windows phone
| | 01:38 |
7, and displaying content in web browser
controls.
| | 01:41 |
The Windows phone 8 Emulator also
requires a processor that supports Second
| | 01:45 |
Level Address Translation or SLAT because
the Windows Phone Emulator is a full
| | 01:50 |
virtual machine all by itself.
One other important thing to note is that
| | 01:54 |
the operating system you use must be the
ENU or English United States version.
| | 01:59 |
Unless you install one of the localized
versions of the Windows Phone SDK in one
| | 02:03 |
of the other languages such as Japanese,
Chinese, and so forth.
| | 02:27 |
So, pretty much if you're going to be
doing Windows phone development, you'll
| | 02:29 |
want to have a dedicated machine that
you're connected up to with a dedicated
| | 02:33 |
display so you can get the full
performance.
| | 02:36 |
Once you've got the tools installed and
fired up and ready to go, in the next
| | 02:40 |
video, we'll build the traditional Hello
World application for Windows phone.
| | 02:43 |
| | 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 |
| Debugging on a Windows Phone device| 00:00 |
The Windows Phone Developer tools are
sufficient for building apps and testing
| | 00:04 |
them in the emulator.
Even though this is very useful, it's not
| | 00:07 |
enough to complete an app that's destined
for the Windows Phone store.
| | 00:10 |
Before you ship, you should, if at all
possible, test on an actual Windows Phone device.
| | 00:16 |
For Windows Phone 8, everything you need
is included in the Windows Phone 8 SDK
| | 00:20 |
add on for Visual Studio 2012.
For Windows Phone 7, you'll need to
| | 00:24 |
install the Zune software, because it
contains the drivers and associated
| | 00:28 |
modules necessary for tethered debugging.
In both cases, you need to have a
| | 00:32 |
Microsoft ID and be a registered
developer on the Dev Center with
| | 00:35 |
Microsoft to unlock your device.
If you're developing for Windows Phone 8
| | 00:39 |
only, you can jump to the next video.
The remainder of this video is for
| | 00:43 |
Windows Phone 7 developers only.
To install the Zune software, go to
| | 00:48 |
zune.net and click on the download page
and click on this Download Now button.
| | 00:53 |
You don't have to sign up for the Zune
service in order to be able to use the
| | 00:57 |
Zune software for a developing Windows
phone.
| | 01:00 |
Detailed instructions on how to register
your phone for development are found on
| | 01:04 |
this msdn page.
You can search for Register Your Phone
| | 01:08 |
for Development.
The way you do this is you come down to
| | 01:12 |
start menu, come down to the Windows
Phone SDK 7.1 section and click on the
| | 01:16 |
Windows Phone Developer Registration.
Which brings up this app, in which case
| | 01:21 |
you can enter in the Windows Live ID and
password that you used to connect your phone.
| | 01:26 |
As you can see here on this system, we
don't have the Zune software running.
| | 01:30 |
You have to have the Zune software
running before you can register your phone.
| | 01:33 |
The next step is to actually connect our
device to our development system.
| | 01:37 |
I recommend using the USB cable that came
with your device.
| | 01:41 |
Because not all micro-USB cables are the
same and that's the one you're going to
| | 01:44 |
be able to know that is actually designed
to work with your device.
| | 01:47 |
So, the way we verify this connection is
by starting Zune and we'll need to click
| | 01:51 |
the Sign In button.
I've already pre-configured this one to
| | 01:54 |
sign in with my LiveID that is associated
with my Nokia Lumia 900 phone And now we
| | 02:00 |
plug the USB cable into the phone.
The first time you do this you'll
| | 02:04 |
probably see a little pop-up that says,
installing driver software.
| | 02:08 |
And then, once the phone is connected
you'll see, it'll have a phone menu up
| | 02:11 |
here at the top.
And there'll be something down here that says.
| | 02:15 |
Let me see the sync status.
Now, you can see here on this particular
| | 02:19 |
phone that it says, sync relationship,
guest.
| | 02:20 |
That's all the sync relationship that's
necessary to connect up your Windows
| | 02:24 |
phone device to your development system.
Your development system does not have to
| | 02:28 |
be the primary synchronization partner
for your device if that's not where your
| | 02:33 |
music and your pictures and your movies
are located.
| | 02:36 |
But now we know we've got this connected.
Let's go back to Visual Studio and set up
| | 02:40 |
for debugging on the device.
And up here in the top toolbar where it
| | 02:44 |
says Windows Phone Emulator, we can now
drop this down and select Windows Phone Device.
| | 02:49 |
Now, you need to make sure, when you do
this, you have the Zune software running
| | 02:53 |
and your device plugged in.
And now when we press F5 or click on the
| | 02:58 |
Screen button, Visual Studio is going to
go into debug mode.
| | 03:01 |
It's going to download the application to
the phone, and you'll interact with
| | 03:05 |
visual studio in the same way that you
did before.
| | 03:07 |
But the interaction with your application
will actually be on the device itself.
| | 03:10 |
You'll see it says connecting to windows
phone device.
| | 03:13 |
Launching the UI task, now Visual Studios
in debug mode, and in a second you'll see
| | 03:19 |
the app actually running on the device.
All right, well we've now got all the
| | 03:23 |
development software installed, let's
move on to building some apps that we'll
| | 03:27 |
be ready to submit to the marketplace.
| | 03:29 |
| | 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 |
With the introduction of Windows Phone 8,
the Windows Phone emulator has become a
| | 00:04 |
fully functional virtualized phone.
This is the reason why in order to build
| | 00:10 |
and develop apps for Windows Phone 8, you
have to use Windows 8 Pro and a processor
| | 00:15 |
capable of implementing second level
address translation.
| | 00:18 |
The reason is is because the emulator is
a self contained virtual machine running
| | 00:23 |
the exact phone operating system that an
actual phone runs with a few small variations.
| | 00:29 |
For example, there's a fake telephone in
which you can actually make phone calls
| | 00:34 |
but it doesn't actually call anyone.
And of course you can simulate voicemail
| | 00:40 |
but there isn't any actual voicemail
there.
| | 00:43 |
In addition it has a full chat app, a
full implementation of Internet Explorer,
| | 00:49 |
a built-in mail client.
A full implementation of the Windows
| | 00:52 |
Phone Store in which you can actually
download and store apps on this
| | 00:55 |
virtualized phone.
A music app, the Xbox games app,the
| | 01:01 |
office app, which includes the full
ability to edit office documents
| | 01:05 |
including Word and Powerpoint and Excel.
And implementation of 1 note calender and
| | 01:13 |
implementation of kids corner so that you
can test that your applications if you've
| | 01:16 |
added age restrictions to them to make
sure that they work either with or
| | 01:20 |
without kids corner enabled.
A full photo hub including sample photos
| | 01:28 |
and an implementation of Local Scout.
The full list of applications is
| | 01:33 |
available from the application list just
as it would be on an actual Windows Phone device.
| | 01:38 |
When you build apps, they'll show up here
as well.
| | 01:41 |
For example one of the apps we're going
to build in this course is the Sonnets
| | 01:44 |
+DB app.
And here's the icon and the app itself
| | 01:48 |
showing in the app list.
When we click on that, it runs the app
| | 01:53 |
just as if we were running it on an
actual device.
| | 01:56 |
Now there are some things you can't do
with the emulator such as simulate being
| | 02:00 |
interrupted by a phone call.
Or being bumped off the device because
| | 02:04 |
you don't have enough memory.
For those things you'll need an actual
| | 02:07 |
windows phone device.
In addition if you click on the double
| | 02:11 |
chevron here.
I'll move this over so you can see it.
| | 02:15 |
There's a set of additional tools that
come with the emulator that allow you to
| | 02:19 |
simulate 3D motion of the device for
testing the accelerometer.
| | 02:24 |
Allow you to simulate location services
so you can say I'm here.
| | 02:29 |
And have your app monitor that.
The ability to take screenshots like
| | 02:34 |
this, which is very useful when you're
building your apps and ready to put them
| | 02:38 |
in the store.
And finally network description so that
| | 02:42 |
you know exactly what IP address you have
and which adapters are actually connected
| | 02:46 |
up to your device.
In addition to these tools, the emulator
| | 02:51 |
can simulate rotation as well as you can
change the scale on the emulator to be smaller.
| | 02:57 |
Which works well for some of the higher
resolution screen sizes for Windows Phone
| | 03:02 |
8 if your laptop or your desktop screen
is not large enough to display the entire
| | 03:07 |
screen with the emulator running.
This is emulator for Windows phone 8.
| | 03:12 |
If you're building for Windows phone 7
and Windows phone 8, this emulator will
| | 03:16 |
do all you need.
If you are building only for Windows
| | 03:19 |
phone 7, please watch the next video
because it describes the Windows phone 7
| | 03:23 |
emulator only.
If you are building for both Windows
| | 03:26 |
phone 7 and Windows phone 8, you can skip
that video and go on to the one after that.
| | 03:30 |
| | 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 Sonnet's application
into a multipage application using pivot
| | 00:05 |
with persistence, we've started out and
created a new solution called Sonnets
| | 00:10 |
Plus flat file.
And we've copied over some of the things
| | 00:13 |
from the Sonnets app that we built
previously.
| | 00:15 |
We've got the original Shakespeare
Sonnets in CML form.
| | 00:18 |
We've added two images.
One is the star that shows up down in the
| | 00:23 |
application bar so that we can choose a
favorite.
| | 00:25 |
And we've also added a yellow version of
that for use on the page which works in
| | 00:31 |
both the light theme and the dark theme.
So we couldn't just use this image here,
| | 00:36 |
the appbar.favs.rest.png, because in the
light theme, it wouldn't show up.
| | 00:42 |
When you use an icon from the Icons
directory in the Application bar, the
| | 00:46 |
operating system automatically switches
it when you change light and dark themes.
| | 00:49 |
But it doesn't, of course, change it on
your application content area, because
| | 00:53 |
you want to have full control over that.
So we took that, filled it in with
| | 00:56 |
yellow, and named it Favorite.
We've also copied over the About Page so
| | 01:00 |
that we don't have to do that all over
again.
| | 01:03 |
And now, what we're going to do is look
at, we've also added a couple of references.
| | 01:07 |
Because the way we're going to store our
list of sonnets is we're going to store
| | 01:11 |
it in an isolated storage file as a flat
XML file.
| | 01:15 |
And in order to do that, we brought in
system.xml, system.xml.link and
| | 01:19 |
system.xml.serialization using isolated
storage in this example.
| | 01:24 |
Because it works with both Windows Phone
7 and Windows Phone 8.
| | 01:28 |
If you're targeting Windows Phone 8 only,
you should investigate the
| | 01:31 |
windows.storage name space because that's
the one that's compatible with Windows 8.
| | 01:35 |
And will be the one that'll be used
exclusively on Windows phone moving
| | 01:39 |
forward in the next generations of
Windows phone.
| | 01:42 |
We've also, because we're going to be
building two versions of this app, one
| | 01:45 |
that uses a flat file and one that uses
the on-board SQL CE database.
| | 01:50 |
We've made a couple of minor changes to
the WMAP manifest, changing the title of
| | 01:55 |
the app to Sonnets plus FF.
And changing the title of the large
| | 01:59 |
background icon when you pin to the
homepage to Sonnets plus FF.
| | 02:04 |
Alright, so the first thing we're going
to do is we're going to add a class which
| | 02:09 |
is going to hold our data that we're
going to persist.
| | 02:12 |
So, we're going to add a new class and
we're going to call it Sonnets.
| | 02:18 |
And in Sonnets, we're just going to
create a collection of properties.
| | 02:21 |
Because if we're going to be serializing
and de-serializing this information back
| | 02:26 |
and forth with XML.
So we've added an ID property, which will
| | 02:29 |
allow us to connect to the sonnet by
number.
| | 02:32 |
Which is different than the title
property, which is the sonnet number in
| | 02:34 |
Roman numerals.
We've also added an OtherLines, a
| | 02:37 |
FirstLine property, which is the first
line that shows up in that list box, and
| | 02:41 |
an OtherLines property, which is all the
rest of our sonnet.
| | 02:44 |
And then finally, a Boolean to say
whether it's a favorite or not.
| | 02:48 |
So, the way we're going to do this in the
flat file version is we're actually going
| | 02:51 |
to read and write all 154 sonnets to and
from XML.
| | 02:55 |
And when we want to create our list of
favorites, we'll be looking at the
| | 02:58 |
Boolean flags iterating through the list
of sonnets to create a subset of our list.
| | 03:02 |
Save that.
Now, we're going to come and add some
| | 03:05 |
code into the main app C# file.
So, look at what we did here.
| | 03:13 |
We first of all added some additional
using statements, or System.IO,
| | 03:16 |
System.IO.IsolatedStorage, and
System.Xml.serialization.
| | 03:18 |
That's, so that we can serialize the data
back and forth using those stream readers
| | 03:26 |
and writers and text readers and writers
is why we need the System.IO.
| | 03:30 |
And the System.IO.serialization is so
that we have serialize and de-serialize
| | 03:35 |
against the XML model.
So, the name of our "database" here in
| | 03:39 |
isolated storage is going to be
SonnetsWithFavorites.xml.
| | 03:43 |
And, in the app constructor, after we go
through all the standard template stuff,
| | 03:48 |
we then say we want to look and see if
the "database" file exists.
| | 03:53 |
And if not, we're going to prepopulate it
with the contents of that
| | 03:56 |
ShakespeareSonnet.xml which is in a
format that is not exactly what we
| | 04:00 |
want to use in this app.
And so, instead of just reading that and
| | 04:04 |
creating the view module each time, we're
actually going to do it on a one time basis.
| | 04:08 |
Read that and create instances of our
sonnet class so that we can shuffle it
| | 04:12 |
back and forth.
Isolated storage is essentially all the
| | 04:16 |
read write file system that exits on the
Windows Phone device for you to save and,
| | 04:22 |
and load files.
The reason it's called isolated storage
| | 04:24 |
is because the set of files and folders.
For each app is isolated in a sandbox so
| | 04:30 |
that all of your files in sonnets plus
are separate from all of the pictures in
| | 04:35 |
the picture hub, are separate from all of
the mail stored by the mail application.
| | 04:40 |
There is no way for one app to see the
contents of isolated storage for another app.
| | 04:45 |
In order to get access to the isolated
storage directory for your app, you have
| | 04:49 |
to use this
IsolatedStorageFile.GetUserStoreForApplication.
| | 04:53 |
So we go and get that, we do it in a
using statement so that it actually gets
| | 04:57 |
disposed of at the end of the access to
isolated storage.
| | 05:00 |
Because the isolated storage implements
disposable, and this is a good way to
| | 05:05 |
have your app not leak memory.
So, we go get access to the user store
| | 05:09 |
for application, that's the isolated
storage.
| | 05:11 |
And from there we can create files,
delete files.
| | 05:14 |
First, think we're going to do is use
file exist to see whether or not our
| | 05:18 |
database file exist out there because we
only want to do this once.
| | 05:22 |
So, we look and see if it exists.
If it doesn't, we're then going to go and
| | 05:26 |
create a file.
So you use OpenFile, pass in the name,
| | 05:30 |
and use System.IO.fileMode.Create, and
you get a stream.
| | 05:35 |
Then, we have to have some data to put
into that stream, and so we have a
| | 05:38 |
modified version of the method we had in
our view model before that loads that the
| | 05:43 |
Shakespheresonets.xml file into a
observable collection of item view model instances.
| | 05:48 |
We'll look at that in just a second, but
that essentially looks like what our view
| | 05:52 |
model looked like before.
And now, we have this observable
| | 05:55 |
collection of item view model instances
and we use the standard XML serializer
| | 05:59 |
techniques to write it out to the file.
We create a serializer from that, create
| | 06:03 |
a text writer from the stream, serialize
it out and close everybody down.
| | 06:07 |
Now, we have this file in isolated
storage that anytime we need to load up
| | 06:12 |
the data to put into a list box or to add
a favorite or delete a favorite we can
| | 06:17 |
use that file.
This low database from XML, as I said, is
| | 06:21 |
essentially identical to the
implementation we had in the main view
| | 06:25 |
model of the basic Sonnets app.
The difference being instead of taking
| | 06:30 |
the items and adding them to the items
collection of the view model, we create a
| | 06:35 |
new observable collection of the items.
And at the end, as we create each one, we
| | 06:39 |
simply add it to that items list.
We also go through and prepopulate the
| | 06:45 |
two new things that we've added to the
view model, the sonnet ID and the, it's
| | 06:50 |
favorite property.
We set it's favorite property to False.
| | 06:54 |
Remember, this is happening only when
we're loading the static data from ShakespeareSonnets.xml.
| | 06:59 |
So, we don't have any favorites yet.
And we also set up the sonnet number, so
| | 07:03 |
that we can access things in this list by
index.
| | 07:07 |
So, now we've looked at the solution that
we've got.
| | 07:09 |
We added the sonnets class so that we
have a place to put our data that we're
| | 07:13 |
going to store in isolated storage.
And we've modified the app.zemble.cs file
| | 07:18 |
to include a 1 time code, to transfer our
static data from the
| | 07:22 |
ShakespeareSonnets.xml file into our file
and isolated storage so that the rest of
| | 07:27 |
our app has a known state to begin.
| | 07:29 |
| | 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 sonnets plus
flat file solution into a sonnets plus db solution.
| | 00:05 |
Let's talk about the overall architecture
of reading and writing to the database.
| | 00:10 |
Microsoft, on the Microsoft developer
network or MSDN, has a great article
| | 00:14 |
called Local Database for Windows Phone.
And there's lots of nuanced detail in
| | 00:18 |
here, which you'll probably want to
review after you complete this section.
| | 00:22 |
What we're going to talk about right now
is just the architectural considerations
| | 00:25 |
related to how we're going to use the
database and hook it up to our lists
| | 00:29 |
which are done with XML data binding.
The way that that's connected, you can
| | 00:33 |
see here in the right hand box inside
isolated storage you can now have SDF files.
| | 00:38 |
Which are files where the SQL CE
databases are contained.
| | 00:42 |
I previously mentioned that if you are
targeting only Windows Phone 8.
| | 00:46 |
You should use the API's in the
Windows.Storage namespace.
| | 00:49 |
However, if you are using SQL CE that
still requires using isolated storage.
| | 00:54 |
The arrow in the middle there says that
you use use LINQ to SQL to talk to the database.
| | 00:58 |
And the way that you use LINQ to SQL is
the System.Data.Linq name space.
| | 01:03 |
Which has a data context object that
implements the same kind of data context
| | 01:08 |
functionality required for the XML data
binding.
| | 01:10 |
What we're going to do is add a reference
to the system.data.linq assembly.
| | 01:14 |
And then we're going to go ahead and
start converting the bits and pieces of
| | 01:19 |
our Sonnets Plus DB app to use the
database.
| | 01:22 |
So now let's open Visual Studio and get
started.
| | 01:24 |
The first order of business is to open
the Solution explorer.
| | 01:28 |
Open up the references and add a
reference to system.data.linq, because
| | 01:33 |
that's what we need in order to be able
to talk to the database.
| | 01:35 |
Come down there, there we are.
System.data.linq.
| | 01:38 |
Now the next thing we're going to do is
go to our sonnets class.
| | 01:44 |
Now this is our sonnets class from the
flat file version.
| | 01:47 |
You see we simply have a collection of
properties that we used to read and write
| | 01:51 |
data from the XML.
When we convert that to the database version.
| | 01:56 |
It looks very similar except that there
are a number of attributes associated
| | 02:00 |
with each item.
First of all we edited a couple of
| | 02:02 |
additional using statements in order to
be able to bring in the assemblies that
| | 02:06 |
support these attributes.
And then this is the equivalent of the
| | 02:10 |
DDL to define the structure of the
database.
| | 02:13 |
We start out by saying sonnets is a table
in the database, and we define each one
| | 02:18 |
of our properties as a column.
Now because this is a database then we
| | 02:22 |
want to be able to do queries against it.
We also want to have a primary key.
| | 02:27 |
And so this collection of stuff right
here, is all the magic link stuff that
| | 02:34 |
says that we want this column Sonnet ID
to be a primary key.
| | 02:37 |
We want the database to generate it for
us.
| | 02:40 |
We want the database type to be integer
not null, and we want it to be an
| | 02:45 |
identity column.
Which means it's gotta be a unique value.
| | 02:48 |
We said can be null equal to false,
because there's no point in having a
| | 02:51 |
primary key that's null because we can't
search on it.
| | 02:54 |
And then we say auto sync equals auto
sync.on insert.
| | 02:58 |
Which means that when we insert
something, that's when the initial value
| | 03:03 |
of the primary key is generated.
But beyond that, our properties look the
| | 03:07 |
same, other than they say that they are
now columns in the database.
| | 03:11 |
So this is, in terms of database setup,
all that we need to do.
| | 03:15 |
We don't need to open up SQL server
explorer and go through wizards and
| | 03:20 |
dialog boxes and grids in order to be
able to create the data.
| | 03:24 |
Especially because this data is being
created in the SQL CE database on the
| | 03:29 |
phone inside your apps' private isolated
storage.
| | 03:33 |
We save that.
And now we need to be able to connect them.
| | 03:38 |
That table definition to the database
using a database context class.
| | 03:42 |
So we'll come back to the solution
explorer and add a new class.
| | 03:47 |
And we'll call it the Sonnets DB data
context and we fill that in.
| | 03:56 |
Here's what we got.
We got the (UNKNOWN) statements, which
| | 04:00 |
are similar to what we had before.
We had system.data.linq and
| | 04:02 |
system.data.linq.mapping and we have a
class which implements the
| | 04:04 |
system.data.linq data context.
It only has two things in it, ome of them
| | 04:15 |
is, is a declaration of a property which
represents the table.
| | 04:19 |
Which is a type, table of T.
And that specifies items so that we can
| | 04:24 |
use the existing data binding because
we're going to be using items.
| | 04:28 |
And the constructor, which is because
this is a system.data.linq data context
| | 04:34 |
also has to have a connection string.
And we have to pass the connection string
| | 04:37 |
to the base class during construction.
Now the item view model is going to
| | 04:43 |
remain the same.
But we need to make a few more changes to
| | 04:47 |
the app.xml.cs in order to be able to
support the initial process of using the database.
| | 04:53 |
So here's where we're going to actually
start accessing the database.
| | 04:56 |
Now let's take a look what we got.
If you remember, back in the previous
| | 05:03 |
version, we had a DB name property.
Well, that's gone now.
| | 05:07 |
We have replaced that with a DB
connection string property.
| | 05:10 |
And since this is actually SQL, it needs
to say datasource equals and then you see
| | 05:16 |
here isostore colon slash.
So this is a specific string format that
| | 05:21 |
tells the database that the connection is
in a database and in the isolated storage.
| | 05:27 |
And, in our case, we called it
sonnets2.sdf.
| | 05:28 |
Whatever databases you create have to
have a file extension of sdf.
| | 05:35 |
Then in order to be able to connect to
this data contacts from other parts of
| | 05:39 |
the application.
We define a private incidence variable of
| | 05:43 |
type Sonnets DB Data context which we
just looked at.
| | 05:46 |
And a property getter and setter that
allows us to know that we need to
| | 05:51 |
actually do the construction the first
time we access this and pass on the data
| | 05:55 |
base Connection String.
If we look at the rest of app.xml cs most
| | 06:01 |
of it is the same as we've seen before.
Except at the beginning of the app
| | 06:05 |
constructor, we initialize a variable of
type sonnets db data context.
| | 06:10 |
And call our property in order to
actually instantiate the data base and
| | 06:16 |
we'll use it down here a little bit
further on.
| | 06:17 |
And just as we did before, we need to
determine whether the database has been
| | 06:22 |
pre-populated by the Shakespeare sonnets
dot xml file.
| | 06:26 |
Here, unlike in sonnets plus flat file,
we use the database data context in order
| | 06:32 |
to be able to query whether the database
exists.
| | 06:35 |
Rather than, the isolated storage
manager, and trying to see whether the
| | 06:39 |
file exists.
So we first ask the
| | 06:42 |
system.linq.datacontext whether the data
base exists.
| | 06:48 |
If it doesn't exist, then we create it
with this db dot create data base that
| | 06:54 |
does introspection over the Table class
and actually creates the table and the
| | 06:58 |
data base with all the appropriate types.
Then Just as we did before, and this
| | 07:02 |
method hasn't changed.
Our load database from XML, which reads
| | 07:05 |
the Shakespeare sonnets.XML and creates
an observable collection of item view model.
| | 07:10 |
And then, instead of taking that and
writing it out as a serialized XML file.
| | 07:14 |
We're going to iterate over the
collection of item view model instances
| | 07:19 |
And ask the database to insert the items.
But it inserts them on submit.
| | 07:25 |
So, what happens here, as we say.
Database.items.insert on submit.
| | 07:30 |
And we create a new instance of that
sonnets class that has the data that we want.
| | 07:35 |
The one that was annotated by the
attributes that describe the columns and
| | 07:40 |
their data types.
You notice because we are using the
| | 07:43 |
default values, we don't set the sonnet
ID, that's the primary key which is auto generated.
| | 07:50 |
And we don't need to set the is favorite
value because it defaults to false.
| | 07:55 |
So, we say DB and items on insert submit,
we create a new instance of sonnets, fill
| | 08:00 |
it in.
And when we are all done with that then
| | 08:03 |
we say DB.submit changes.
And that actually takes all of those
| | 08:09 |
objects that were in the observial
collection and writes them out to the
| | 08:13 |
date base.
As always depending upon the size of the
| | 08:16 |
data your dealing with and the amount of
memory in the device that you're dealing with.
| | 08:21 |
It works great for 154 sonnets.
If you had ten thousand US census data
| | 08:26 |
items, you probably would want to call
db.SubmitChanges earlier than at the end
| | 08:28 |
of calling InsertOnSubmit ten thousand
times.
| | 08:34 |
So now we have the database set up.
We've got our sonnets class with the
| | 08:38 |
proper attributes, we've got our
DBDataContext class all set up and we've
| | 08:44 |
seen the first incidents of accessing and
writing data to the database.
| | 08:48 |
| | 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:04 |
There are one or more image sensors which
enables implementation of a camera capability.
| | 00:09 |
A GPS radio which implements location
awareness capability.
| | 00:13 |
And an accelerometer, which enables you
to determine when the device is actually
| | 00:16 |
physically moving in 3D space.
So let's look at how you use each one of
| | 00:20 |
these three capabilities in order.
First we'll take a look at our sample
| | 00:24 |
application, then we'll dig into the
code.
| | 00:26 |
So first of all, let's look at the
camera.
| | 00:28 |
The camera is connected in your code to
something called the Camera Task.
| | 00:32 |
And we launch it, the camera shows up.
Now, in the Windows Phone Emulator, all
| | 00:36 |
you see in the sample camera user
experience is this little square moving around.
| | 00:41 |
And buttons here at the bottom to
simulate whether or not you've got the
| | 00:44 |
flash, whether you're connected to the
front or rear camera.
| | 00:47 |
And whether you're capturing video or
still pictures.
| | 00:50 |
because there's no camera actually
connected to the emulator.
| | 00:53 |
When you click on the camera it takes a
simulated picture, and then pops up these buttons.
| | 00:58 |
To allow you to decide whether you want
to accept or retake the picture.
| | 01:01 |
When you click Accept, you get a white
square with a colored square inside it,
| | 01:07 |
depending upon the little image was
moving around the square.
| | 01:10 |
When the camera actually, took the
picture.
| | 01:14 |
Next up, let's take a look at the GPS.
And we can start tracking the location.
| | 01:19 |
The way we set the location is by using
this additional Tools fly-out and
| | 01:23 |
clicking on Location.
Let's pick Seattle, click right there.
| | 01:27 |
Now we click Start Tracking Location.
We can see the longitude, latitude and
| | 01:33 |
the accuracy within meters.
We can also change the location over
| | 01:37 |
here, so for example, if we want to say,
let's go look at London, we click here,
| | 01:44 |
and track location again.
Now you can see we're at latitude nearly
| | 01:49 |
zero, longitude 51, and again an accuracy
of five meters.
| | 01:53 |
We've also hooked up the Maps task here,
because In Windows Phone 8, it's
| | 01:57 |
incredibly easy to take a GPS coordinate
and map it.
| | 02:01 |
So let's click the Map It button.
Now you're going to get the full-on
| | 02:05 |
system mapping capability of Windows
Phone without having to write more than
| | 02:09 |
about four lines of code in your app.
Because it's a privacy consideration, you
| | 02:14 |
get this popup that says, will you allow
Maps to access your location.
| | 02:17 |
We'll say yes, and you can see now we
have a Windows Phone map which is
| | 02:23 |
actually quite a bit more detailed than
this big map of exactly where we clicked
| | 02:27 |
over here in London.
Finally in our Sensors app, there's an
| | 02:31 |
accelerometer where we can track the X Y
and Z position of the device.
| | 02:36 |
Over here in the additional tools,
there's a simulated accelerometer that
| | 02:41 |
allows you to move the device around in
3D space.
| | 02:45 |
We can click Start Tracking and as we do.
As we move the device around you can see
| | 02:49 |
the numbers over here on the left change.
For example, this is y almost straight
| | 02:54 |
up, I can get it completely y to zero.
But if I have the device face down or
| | 02:58 |
completely face up.
You can see how that moves.
| | 03:01 |
There are some prerecorded data for the
accelerometer, such as Shake.
| | 03:06 |
So if I play that, you'll see the numbers
over these change rapidly because it's
| | 03:11 |
simulating the user actually shaking the
device.
| | 03:14 |
So that's the sample app.
Now let's dig into the code behind the
| | 03:18 |
Camera task launcher.
So we've fired up Visual Studio, and
| | 03:21 |
we're going to take a look at the sample
implementation of the camera, GPS, and
| | 03:25 |
accelerometer that we just watched in the
demo.
| | 03:28 |
To start with what we have, just the main
page with three buttons.
| | 03:32 |
Each of those simply launches the camera,
GPS, or accelerometer page.
| | 03:36 |
Take a look at the code there.
You can see that each one of those simply
| | 03:40 |
has a call to NavigationService.Navigate
to go off to the proper page.
| | 03:45 |
Let's take a look at the camera page.
The camera page consists of two controls,
| | 03:49 |
a button to launch the camera task, and
an image control to display the result
| | 03:55 |
you get back from taking the picture.
So we take a look at the code behind this.
| | 03:58 |
The key thing is to make sure that you
bring in Microsoft.Phone.Tasks.
| | 04:05 |
This is how you get to the Camera Task.
In the constructor, we instantiate a new
| | 04:10 |
instance of the Camera task and we also
use this PhotoResult EventHandler.
| | 04:16 |
For when the camera takes the picture so
that we can capture the image.
| | 04:20 |
In our button handler, we simply call
CameraCaptureTask.Show.
| | 04:24 |
And just for good measure, we cache
invalid operation exception in that rare
| | 04:28 |
case where you might someday find a
Windows Phone device with no camera.
| | 04:32 |
In the cameraCaptureTask_Completed
handler, we look to see whether the photo
| | 04:38 |
result says the task result is okay.
Meaning the user actually took the
| | 04:42 |
picture, and if it did, we create a
BitmapImage.
| | 04:47 |
And then we set the source of that bitmap
to the chosen photo property of the photo
| | 04:51 |
result from the camera.
And then set the image source of our
| | 04:55 |
image bitmap, image1, to the bitmapImage
object we just created.
| | 05:01 |
Now, if you want to see this in action,
you can use the emulator, or you can
| | 05:04 |
actually connect up a device.
And unlike Windows Phone 7, Windows Phone
| | 05:09 |
8 now allows you to debug your camera
applications with a live device.
| | 05:14 |
So that if you take a picture on the
camera, you actually will be able to see
| | 05:17 |
the result, and debug the output in
Visual Studio.
| | 05:21 |
Now, Microsoft also has sample code that
allows you to access the raw camera data.
| | 05:26 |
So that if you wanted to create an
augmented reality-type app, or things
| | 05:30 |
which implement custom zoom features.
Or things which require raw access to the
| | 05:34 |
camera sensor or the flashlight, you can
dig into that at a much deeper level.
| | 05:38 |
Windows Phone 8 has additional camera
API's.
| | 05:42 |
You can create custom lenses.
There is new API's for getting a preview
| | 05:45 |
image for getting a path to where your
image is stored for sharing your media
| | 05:51 |
with social networks.
And you can also adjust the exposure,
| | 05:54 |
focus, and white balance as well as get
access to the uncompressed photo data.
| | 05:59 |
Which is something you couldn't do on
Windows Phone 7.
| | 06:01 |
Windows Phone 8 allows you to integrate
into the photo viewer and photo edit
| | 06:06 |
picker as well.
Now let's go on and take a look at the GPS
| | 06:11 |
| | Collapse this transcript |
| Exploring GPS| 00:00 |
Now let's take a look at the code behind
the GPS portion of this app.
| | 00:04 |
We have five controls on the screen here.
The first is a button named, start
| | 00:08 |
tracking location, and we have three text
blocks here for the longitude, latitude
| | 00:14 |
and accuracy.
Because when you ask for location, you
| | 00:17 |
say how much accuracy you want.
Like I want my location to be within say
| | 00:22 |
five meters.
Because location services can end up
| | 00:25 |
returning you numbers based on GPS radio
or WiFi or some combination of both.
| | 00:31 |
It may actually give you back an accuracy
that is either more accurate or less
| | 00:35 |
accurate than you actually requested.
And then we finally have a map it button,
| | 00:39 |
which allows us to invoke the map test.
Based on the data that we got from the
| | 00:44 |
longitude and latitude requests from the
GPS.
| | 00:47 |
So let's go look at the code.
In order to access location services we
| | 00:51 |
need System.Device.Location and
Windows.Devices.Geolocation.
| | 00:56 |
In order to access the map we need to use
Microsoft.Phone.Task.
| | 01:03 |
The thing which gets us the location is
something called a Geolocator.
| | 01:08 |
So, here is the declaration of our
Geolocator object and the location
| | 01:12 |
longitude, latitude and accuracy come
back in something called a Geoposition.
| | 01:16 |
So, here we allocate our Geoposition
object.
| | 01:19 |
We come into the page, we allocate a new
Geolocator and set our desired accuracy
| | 01:25 |
to ten meters.
We look at the start tracking location
| | 01:29 |
method here in button1_Click.
What we do is disable our existing
| | 01:35 |
buttons, so the user can't tap them
multiple times.
| | 01:39 |
We set the longitude and latitude text
blocks to the word locating with an
| | 01:42 |
ellipsis at the end, and then we attempt
to go get the current location.
| | 01:48 |
In order to do that we set up two
timespans.
| | 01:50 |
There's an API called
GetGeopositionAsync, that takes two
| | 01:56 |
timespan objects.
The first one max age is how old of a GPS
| | 02:01 |
location are we willing to accept.
In a real world situation, you're
| | 02:05 |
going to want to typically set this to
maybe one minute or five minutes.
| | 02:09 |
Because you don't necessarily have to
have the absolutely precise up-to-date geolocation.
| | 02:12 |
If you do that, it can be heavy on
battery usage.
| | 02:17 |
We've set it for the demo here to five
seconds so that, as we click on the map,
| | 02:21 |
we can get immediate feedback.
In real life, you probably want to set
| | 02:25 |
this to a timespan from minutes of one,
two, three, four, five.
| | 02:29 |
Timeout has to do with how long between
the time that you ask the GPS radio for a
| | 02:35 |
synch and when it's going to time out and
say, hey I can't find the satellite.
| | 02:40 |
Thirty seconds is a real world reasonable
number.
| | 02:42 |
GetGeopositionASync is a new Windows 8
style WinRT asynchronistic API.
| | 02:49 |
We're going to take one step backwards
here and look at the fact that we
| | 02:52 |
declared this method private async void.
The reason we did that is so that we
| | 02:57 |
could come down here and say currentLoc
equals await gl.GetGeopositionAsync.
| | 03:04 |
This is a much simpler solution than the
one you had to use for Windows Phone 7,
| | 03:07 |
in which you had to set up your own
custom event handlers.
| | 03:11 |
And deal with the callbacks.
Once we get back to our location, we take
| | 03:14 |
our currentLoc which is a geoposition and
we ask for a Coordinate, Latitude and
| | 03:18 |
then we turn it into a string.
Similarly we do the same things for
| | 03:24 |
Longitude and Accuracy.
And now that we have a geoposition we
| | 03:29 |
enable our map it button.
Now you noticed we didn't check to see
| | 03:33 |
whether or not the location was valid.
That's because the way
| | 03:36 |
GetGeopositionAsync works is that it will
throw an exception if it can't get a
| | 03:41 |
location for you.
So we have two separate exception
| | 03:45 |
handlers here.
We have a catch for Unauthorized
| | 03:47 |
Exception, which is what happens when the
user has disabled Access to location services.
| | 03:53 |
And we have a regular kind of exception
which is what happens when you can't get
| | 03:57 |
a GPS fix.
And finally, in our try catch finally, we
| | 04:01 |
reset our go button to true so you can
request a location over and over again.
| | 04:07 |
So that's how it happens that we update
the text blocks on the screen with the
| | 04:11 |
longitude, latitude, and accuracy.
Finally, let's take a look at how we map things.
| | 04:17 |
Down here in our button2_Click handler,
we have something simply that says, do we
| | 04:21 |
have a geoposition object in currentLoc?
If we have one, creating a map is as
| | 04:27 |
simple as instantiating a map task.
Setting the center point into the map
| | 04:32 |
equal to a geocoordinate and passing in
the latitude and the longitude, like this.
| | 04:38 |
The zoom Level is anywhere from 1 to 20.
1 represents vision of the entire world
| | 04:43 |
and 20 represents the highest accuracy
you can get, like 5 feet in front of a building.
| | 04:49 |
Somewhere between 10 and 12 is a
reasonable size for navigating around the
| | 04:52 |
city in terms of something similar to a
map you would have on paper.
| | 04:56 |
And once you set that up, the last thing
you have to do is simply say map test dot
| | 05:00 |
show and the operating system handles
everything else for you.
| | 05:04 |
Once again, this is way simpler than the
way it was in Windows Phone 7 where you
| | 05:08 |
had to use big maps and set up things.
And either host a web browser or use a
| | 05:13 |
seperate browser app.
This is something the system handles for
| | 05:16 |
you automatically.
Next up, let's take a look at how the
| | 05:19 |
accelerometer code works.
| | 05:20 |
| | 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.
| | 00:04 |
Including recording form a microphone,
playing back through the speaker from a
| | 00:08 |
recorded sound.
Playing back through the speaker from
| | 00:12 |
sound that's streamed over the network,
playing back video from local files,
| | 00:16 |
playing back video over the network.
And many Windows Phone, handsets also
| | 00:20 |
include an FM radio, which you have
software APIs to be able to tune the
| | 00:24 |
radio to specific channels.
This page right here is ground zero for
| | 00:28 |
all those technologies and is frequently
updated by Microsoft.
| | 00:32 |
In this chapter, we're going to dig into
using the microphone to record sound and
| | 00:37 |
play it back.
Store it to a file and be able to select
| | 00:40 |
one of many sounds we've recorded and
play it back.
| | 00:43 |
So, let's dig right into the code.
| | 00:44 |
| | 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.
When you pin an application to the start
| | 00:04 |
page by using pin to start, by default
Windows phone uses the static PNG files
| | 00:09 |
that were included in your solution as
the tiles image.
| | 00:12 |
On Windows Phone 7, there's only one tile
style which is commonly referred to as
| | 00:16 |
the flip tile.
By default, Windows Phone 8 uses the
| | 00:20 |
template Flip style which matches what's
used on Windows Phone 7.
| | 00:24 |
On Windows Phone 8, you must apply at
least two images for small and medium.
| | 00:28 |
And there are three choices to use for
the style of your Tile, Flip, Iconic, and Cycle.
| | 00:37 |
Flip works just like Windows Phone 7.
For an iconic tile, you use the iconic
| | 00:42 |
tile data API to supply a custom image.
If you choose to use the cycle tile
| | 00:47 |
feature, you must supply a set of from
one to nine images which will cycle
| | 00:51 |
through just like the built in pictures
app.
| | 00:54 |
You can update the title.
The background image and the count
| | 00:58 |
properties of all three tile styles,
using the shell title API.
| | 01:03 |
For Tweet monitor, we're going to use the
default flip tile behavior.
| | 01:07 |
Now, the count for this can only be from
zero to 99.
| | 01:10 |
Which is why in Tweet monitor we didn't
use the count badge.
| | 01:13 |
Because we wanted to show the full number
of Tweets not just the most recent Tweets.
| | 01:18 |
So, let's take a look at how you use a
flip tile, both staticly and programmatically.
| | 01:21 |
First, we'll open up our code, and we'll
come down here once we've got this string downloaded.
| | 01:23 |
And we'll add a little code here, that
says, get the tile and do some updating.
| | 01:28 |
However, you see we need to include
another using we need using Microsoft.pPhone.Shell.
| | 01:43 |
And now, when the tweets are in, we can
actually set the title of your live tile
| | 01:50 |
to the user's Twitter name.
We saw that when we saw the demo of the
| | 01:53 |
application that had my Twitter handle
over the Lynda.com Twitter handle on the back.
| | 01:58 |
So let's go ahead and run this, make sure
this works for us, we'll do an update.
| | 02:05 |
We'll come back to here, pin it to these
dart.
| | 02:08 |
And in a minute, when this flips over,
it'll be the default color, but it'll
| | 02:12 |
have our Twitter handle on the bottom,
and there we go.
| | 02:15 |
Now here, in this code, we could have
accessed any of the things that are
| | 02:20 |
inside standard tile data such as count,
title, background image, background
| | 02:26 |
content, back background image, and so
forth.
| | 02:29 |
All right, almost done with tweet
monitor.
| | 02:32 |
The next thing, and the final thing we
have to do is to add our background agent.
| | 02:36 |
Which will allow us to do some background
processing even when our app isn't
| | 02:39 |
running to update the tweet count.
| | 02:41 |
| | 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. Native DevelopmentHello World in C++| 00:00 |
Something you can do in Windows Phone 8
that you can't do in Windows Phone 7 is
| | 00:05 |
include native code.
Now, there's some restrictions and some
| | 00:08 |
interesting nuances in using native code
in a Windows Phone app, so let's take a look.
| | 00:13 |
First of all, if you want to have an app
that's all C++, that only works if your
| | 00:18 |
app is going to use Direct 3D or DirectX.
If you want to have an app that mixes C++
| | 00:23 |
and C# or VB.Net, you have to have a main
program of managed code and a library of
| | 00:31 |
native code.
You can also use native development to
| | 00:34 |
integrate exists libraries, for example
SQLite, into a managed C# or VB.Net application.
| | 00:40 |
And the way you do that is by creating
new Windows runtime components.
| | 00:45 |
And that's basically a managed native
code wrapper around existing native code libraries.
| | 00:53 |
When you build a Hello World in C++, as I
said, it can only be an app that's using
| | 00:58 |
Direct3D or DirectX.
But let's take a look and see what that
| | 01:02 |
looks like.
Now, let's switch over to Visual Studio.
| | 01:04 |
Now we're going to do new project.
And we're going to come down here to
| | 01:09 |
other languages, select Visual C++, and
we scrolld down here we can find Windows Phone.
| | 01:18 |
So now, we're going to pick Windows
Direct3D with XAML app.
| | 01:24 |
What we can see here if we look over our
solution is a solution that contains two
| | 01:28 |
projects, the Phone Direct3D XAML app 1
and a Phone Direct3D XAML app 1 component.
| | 01:35 |
The Phone Direct3D XAML app 1 is simply a
container for holding the Direct3D control.
| | 01:43 |
And in fact, if we look at our XAML,
which is already open here.
| | 01:46 |
Let's swap around the design surface and
the XAML XML.
| | 01:51 |
And then, let's make the design surface
go away so we can actually look at what's
| | 01:55 |
inside there.
All there is, is a drawing surface
| | 01:58 |
background grid.
These two lines right here.
| | 02:01 |
There's no grid.
There's no other XAML controls and there
| | 02:04 |
can't be.
This is simply a way of hosting that in a
| | 02:07 |
XAML environment.
We look at the phone Direct3D XAML app component.
| | 02:14 |
This is all the C++ code.
You can see C++ files and you can see H files.
| | 02:17 |
And when we run this in the emulator,
like this.
| | 02:25 |
And now you can see simply a multicolored
rotating 3D cube, which is being hosted
| | 02:30 |
by a XAML application.
Let's go ahead and stop this, and come
| | 02:35 |
back and stop the debugger.
And do one more File > New > Project.
| | 02:40 |
In this case, we'll pick Windows Phone
Direct3D App Native Only.
| | 02:45 |
In this case, there won't be a XAML
hosting app, it'll be simply C++.
| | 02:49 |
But again, you can't create an app that
is just C++ and XAML.
| | 02:55 |
You have to use that hosting structure
similar to the one we saw before.
| | 02:59 |
But, in fact, it's generally better to
start with a C# app and then add your
| | 03:04 |
libraries than it is to start with this
Windows Phone Direct3D with XAML app
| | 03:08 |
template, the one we used before.
This one here, because then you're going
| | 03:13 |
to actually want to put real things
inside the XAML portion.
| | 03:16 |
But in our exploration of Hello World in
C++, let's now go create a native only
| | 03:21 |
C++ app for Windows Phone.
So, we'll click OK.
| | 03:27 |
And you'll see now, if we look over in
the solution, we have just the same thing
| | 03:31 |
that we had in our previous solution.
But we only have the native project.
| | 03:35 |
And once again, if we run this, we now
get the C++ experience inside Visual Studio.
| | 03:41 |
Which always asks you if the projects are
out of date, unless you click this
| | 03:45 |
dialog, which I'm going to click here.
And this will build and run in the
| | 03:49 |
emulator once the C++ build is complete,
and once again we have our beautiful
| | 03:54 |
rotating cube.
But now you notice, we don't have our
| | 03:57 |
framerate counters, and we don't have the
phone bar at the top.
| | 04:01 |
Because this is a C++ only app, and the
XML shell is completely missing.
| | 04:06 |
If you're building a native game, you
don't need any of these xml functionality.
| | 04:11 |
This is the way to go.
And you can build with Direct3D and
| | 04:15 |
DirectX, but know that that' going to be
a native only mechanism.
| | 04:20 |
And you can't take advantage of and any
of the other features of Windows Phone 8,
| | 04:23 |
the required or managed interface.
That's how look at Hello World in C ++.
| | 04:28 |
Next step, we're going to look at
building a native library to connect them
| | 04:32 |
to a C# XAML app.
| | 04:35 |
| | Collapse this transcript |
| Libraries| 00:00 |
One of the big features added to Windows
Phone 8 is the ability to include native code.
| | 00:06 |
There's two kinds of native code you can
include.
| | 00:09 |
You can include a native DLL, for
example, like SQLite.
| | 00:13 |
Or you can include a Windows Phone
Runtime component.
| | 00:17 |
In order to be able to access a native
DLL from a managed app, you have to use a
| | 00:23 |
Windows Phone Runtime component to get to
the DLL.
| | 00:25 |
If you're building a C++ main app that
uses DirectX3D, you can use your native
| | 00:33 |
DLLs directly just as you would in any
other C++ environment.
| | 00:37 |
When you include a native DLL, you have
to compile it for both x86 and ARM CPU architectures.
| | 00:44 |
That's because there are two different
kinds of CPUs out there in the world
| | 00:48 |
running Windows Phone 8.
When you build a Windows Phone runtime
| | 00:52 |
component, it can automatically be
compiled to what's called Any CPU.
| | 00:57 |
Which is subsequently natively compiled
by the Windows Phone store infrastructure
| | 01:01 |
into the appropriate x86 or ARM
architecture that matches the user's device.
| | 01:07 |
When you build a Windows Phone runtime
component, you can use the async and
| | 01:11 |
await keywords and access WinRT and APIs.
You can also use manage compatible data
| | 01:17 |
formats such as String.
So let's go take a look, and we'll build
| | 01:22 |
a simple managed app.
We'll add a simple Windows phone runtime
| | 01:26 |
component, and be able to instantiate the
C++ from our C# code.
| | 01:30 |
And then, in the next video, we'll go
back and retool our Hello World app to
| | 01:36 |
include a call to a C++ module, inside
the process of hello world.
| | 01:42 |
So, let's switch over to Visual Studio.
Here in Visual Studio, with do file new
| | 01:46 |
project, and we'll come up to the visual
C++, we'll come down here to windows phone.
| | 01:54 |
And just select plain old Windows phone
app.
| | 01:56 |
And we'll call this one
ManagedPlusNative.
| | 02:01 |
Click on OK.
Now, this is a standard Windows Phone 8
| | 02:06 |
empty shell.
But what we want to do now is show the
| | 02:09 |
process you need to do to add a Windows
Phone runtime component in C++ and hook
| | 02:14 |
the two of them together.
You go to the Solution, you right-click,
| | 02:18 |
you come down to the Add Sub-Menu Item,
and select New Project.
| | 02:23 |
We'll come down here to Other Languages,
Visual C++, scroll down, select Windows Phone.
| | 02:30 |
And one of the templates we have
available to us is Windows Phone Runtime Component.
| | 02:36 |
So, we click on OK, and we now have a C++
Windows Phone Runtime Component.
| | 02:43 |
And you notice that we have one public
member which is the constructor.
| | 02:47 |
You might think, I can come back to my
main page, open up my C++ file, come up
| | 02:52 |
here and say using Windows.
And, wait a minute, I don't get
| | 02:57 |
Intellisense help for Windows Phone
Runtime Component 1, so let's erase that.
| | 03:01 |
And there's two reasons for that.
The first reason is I need to add a
| | 03:05 |
project reference.
So I'll come over to our Manage Plus
| | 03:08 |
Native Project, right-click, select Add
Reference, come to Solution, select our
| | 03:15 |
Windows Phone Runtime Component project,
and click OK.
| | 03:19 |
And now, I also have to come to the
solution and select rebuild.
| | 03:23 |
Because Visual Studio doesn't know about
the members in the methods inside the
| | 03:27 |
native library until its been build at
least once.
| | 03:31 |
And each time, you change it in the sense
of adding additional members or methods
| | 03:35 |
you have to rebuild before they're
visible to Intellisense.
| | 03:39 |
So, now I can come to my C# code and say,
using Windows, and there's our Windows
| | 03:43 |
Phone runtime component 1, namespace.
And, now I can come down into my code and
| | 03:48 |
say Windows Phone Runtime Component
because that's my class name, WRC equals
| | 03:54 |
New Windows Phone Runtime Component.
And now if I build this, this builds successfully.
| | 04:02 |
So, here we've instantiated an instance
of the WindowsPhoneRuntimeComponent in
| | 04:04 |
C++, and we could call methods on it from
our C# code.
| | 04:10 |
In our next video, we'll start with our
existing Hello World application and add
| | 04:14 |
some C++ code to it.
| | 04:16 |
| | Collapse this transcript |
| Managed plus managed| 00:00 |
Let's actually make a Managed C# and a
C++ Windows Runtime Component actually
| | 00:06 |
work together to do something.
I'm going to start out again with our
| | 00:10 |
Hello World application.
Let's run it again to remember how it works.
| | 00:15 |
Type here to say, what's your name and
I'll put in Michael and I'll click Say Hello.
| | 00:20 |
And it takes the name that you put into
this text box, puts the word 'Greetings'
| | 00:24 |
on the front and puts an exclamation
point on the back end.
| | 00:27 |
And if we look at the code, you'll
remember how it does that by down here on
| | 00:33 |
line 27, it says textblock2.Text equals
the string 'Greetings' plus the contents
| | 00:39 |
of the text box plus an exclamation
point.
| | 00:42 |
Now we're going to add a Windows Runtime
components that adds two exclamation
| | 00:47 |
points to the end of a string.
The reason for doing this is first of all
| | 00:51 |
to show you how you can manipulate data
from managed code inside unmanaged code.
| | 00:57 |
And also how you pass parameters,
particularly strings.
| | 01:00 |
Because Microsoft has a number of
examples about how to integrate managed
| | 01:04 |
C# or vb.net code with C++ code.
But they don't have any examples at all
| | 01:10 |
about how to manipulate strings.
So by taking this course you're going to
| | 01:13 |
get some secret information that even you
can't get from Microsoft.
| | 01:16 |
So as we saw before to add a Windows
Phone Runtime Component to our solution
| | 01:22 |
we'll right-click here, come down and
select Add, select New Project.
| | 01:27 |
Under Windows Phone we're going to pick
Windows Phone Runtime Component.
| | 01:31 |
Windows Phone Runtime Component One's a
big long name so we're going to call it
| | 01:35 |
Ex1, just to make it shorter.
So we're going to click OK.
| | 01:41 |
Now you see we have a .h file and a .cpp
file just like before.
| | 01:46 |
But in this case we're going to add a
method to our class here.
| | 01:49 |
Now our method's going to take in a
string, and return a string.
| | 01:53 |
So we begin by saying platform :: string^
and that's the way you reference a string
| | 02:00 |
in unmanaged code.
And then Windows Phone Runtime Component
| | 02:05 |
because that's the name of our class ::
Add exclamation points.
| | 02:09 |
And we're just going to say AddEx and it
take the string as an argument.
| | 02:12 |
Platform :: string^ and we'll call it
orig for our original string.
| | 02:20 |
Now you notice that AddEx has the red
squiggles underneath it saying that
| | 02:24 |
Windows Phone Runtime Component has no
member AddEx.
| | 02:28 |
That's because this is C++, we'll need to
copy this line, come back to our .h file,
| | 02:33 |
add it in here as one of our public
methods, there we go.
| | 02:36 |
And add a semicolon at the end of it.
And when we come back to our CPP files,
| | 02:39 |
you'll notice that the red squiggles are
gone.
| | 02:44 |
Now let's make it do something.
So the way we do that is we're going to
| | 02:48 |
allocate a static string that has the two
exclamation points we want to add.
| | 02:52 |
And then we're going to use the
concatenation method to concatenate our
| | 02:56 |
original value with that to create a
return value.
| | 02:59 |
So we'll say string^ return value equals
ref new string open brace, L quote two
| | 03:09 |
exclamation points close quote param
semicolon.
| | 03:14 |
Now doesn't that look fun for all of you
manage C# programmers.
| | 03:17 |
But that's the syntax you have to use in
order to be able to create a string in C++.
| | 03:22 |
Inside one of these Windows Runtime
components.
| | 03:25 |
Now that we've got that, we can say
return value equals returnValue.
| | 03:32 |
Invoke it's concat method and put in our
original string and returnValue itself,
| | 03:40 |
which is the two exclamation points and
then we'll return that.
| | 03:44 |
So that's our C++ code.
Now let's go back and do the process of
| | 03:48 |
adding a reference to this particular
class to our managed code, then we'll
| | 03:54 |
build everything and then we'll call this
method.
| | 03:57 |
So we'll come back to here.
We'll go to the references, we'll right
| | 04:01 |
click and say Add Reference.
Go to the solution and select Ex1 since
| | 04:05 |
that's the name of our project.
And then as you remember from the
| | 04:08 |
previous video, we right click here and
rebuild the soltuion.
| | 04:11 |
So we've got everything built.
Instead of putting it directly into this
| | 04:15 |
TextBlock we're going to say string s1
equals Greetings plus your textbox content.
| | 04:22 |
Take the exclamation points off.
Then we're going to allocate an instance
| | 04:25 |
of our Windows Phone Runtime Component.
But we don't have the using so we're
| | 04:31 |
actually going to say
ex1.windowsphoneruntimecomponent.
| | 04:37 |
Ex1 = new
ex1.WindowsPhoneRuntimeComponent.
| | 04:43 |
I'll click that.
Then we can say s1 = ex1.Addex passing
| | 04:50 |
our s1 string.
And finally we'll set into the TextBlock.
| | 04:55 |
TextBlock2.Text equals S1.
And the reason we did it this way is
| | 05:00 |
because when we were debugging and the
first time you do your debugging your
| | 05:03 |
with a Windows Phone Runtime Component.
You'll want to verify the things actually
| | 05:08 |
come back the way you expect them to.
In our that case, I'm confident this is
| | 05:12 |
going to run.
Let's give it a try.
| | 05:13 |
I come back here to our textbox.
Put in my name.
| | 05:18 |
I'll click Say Hello.
And you can see down here, not only does
| | 05:23 |
it say greetings Michael, it has two
explanation points at the end which came
| | 05:27 |
from our C++ Windows Phone Runtime
Component.
| | 05:30 |
Now obviously this is a trivial example
of a Windows Phone Runtime Component.
| | 05:34 |
But it gives you the sense of everything
you need to know to in order to be able
| | 05:38 |
to hook up some C++ code to your existing
or to your new C# managed code.
| | 05:44 |
So that's it for Windows Phone and native
code.
| | 05:47 |
Coming up in the next chapter, we'll talk
about exploring all the built-in controls
| | 05:51 |
and additional functionality of Windows
Phone.
| | 05:53 |
| | Collapse this transcript |
|
|
11. Beyond the Basics| Exploring built-in controls | Windows Phone Toolkit| 00:00 |
The first of the two open sourced and
free toolkits for windows phone, we're
| | 00:04 |
going to take a look at, it's called the
Windows Phone Toolkit.
| | 00:07 |
You can download both the binaries, and
the source code from this tool kit from
| | 00:10 |
here, phone.codeplex.com.
As of the time we're writing this course,
| | 00:15 |
you'll definitely want to get the Windows
Phone Toolkit, from October 30th, 2012.
| | 00:20 |
Is that version works with the latest
Windows Phone SDK.
| | 00:23 |
So let's switch over to Visual Studio and
take a look at what's in the toolkit.
| | 00:28 |
There's everything from the
AutoCompleteBox to a set a Date and Time
| | 00:32 |
Pickers all the way to a WrapPanel.
And all these controls allow you to do
| | 00:37 |
things that are either similar to or
functionally equivalent to some of the
| | 00:43 |
capabilities used in the native apps on
the phone such as mail and messaging.
| | 00:48 |
And the settings class allows you to do
those in your C Sharp written applications.
| | 00:54 |
So let's fire up this app and take a look
at in the emulator.
| | 00:58 |
So this is a sample application that
comes with the Silverlight for Windows
| | 01:01 |
Phone Toolkit that shows various
controls.
| | 01:04 |
As we saw in the solution explorer, the
samples in the Silverlight for Windows
| | 01:09 |
Phone toolkit ranged from
AutoCompleteText box to WrapPanel.
| | 01:10 |
Auto complete text box for example is the
kind of thing you see where you type here
| | 01:16 |
and start typing the word.
And a suggested list will show up the
| | 01:20 |
list of suggestions that's used here in
the sample is the well-known advertising
| | 01:24 |
gobbledygook text called lorem ipsum.
Which is a selection of latin.
| | 01:28 |
We'll start typing lo, we'll see there
and we'll click here, and it will
| | 01:33 |
automatically type in the rest of the
word for us.
| | 01:35 |
Contextmenu can be very handy, you click
on something and hold, and a menu shows
| | 01:42 |
up that's contextual to exactly the thing
that you were clicking on.
| | 01:46 |
The date and time pickers are very, very
valuable, because these are things which
| | 01:51 |
are available to the native apps on the
phone.
| | 01:54 |
But if you want to have this
functionality in the C Sharp app that
| | 01:57 |
you're writing, you have to use the tool
kit.
| | 02:00 |
For example here, this allows us to
select a date.
| | 02:03 |
We can select next Monday, or we can
change the time, we go to PM.
| | 02:10 |
And make it some time after noon.
One of the other things that's good in
| | 02:17 |
here has to do with the tilt effect.
Because you can see as you touch the
| | 02:21 |
button, it animates, it goes down and
tilts back up, or the same thing with the
| | 02:25 |
check box.
You can see it's sort of tilt back.
| | 02:27 |
It just gives a little bit of extra
visual feedback to your users that when
| | 02:31 |
they've tapped something then they've
actually physically pushed on something
| | 02:34 |
on the screen.
That's a quick tour of the Windows Phone Toolkit.
| | 02:39 |
Now, let's take a quick look at the
coding for fun toolkit.
| | 02:42 |
| | Collapse this transcript |
| | Introducing Coding4Fun | Reminders and notifications| 00:00 |
Windows Phone gives you the ability to
create scheduled actions for future times
| | 00:05 |
that display customized reminders even if
your app's not running.
| | 00:09 |
For this course, we've create a little
app called MoovZ that helps you remember
| | 00:12 |
to get up and move around when you're
taking one of these courses or in for a
| | 00:16 |
long coding session.
You can start a series of reminders
| | 00:19 |
anytime you want.
You can look at the reminders you've
| | 00:22 |
already got scheduled, and you can stop
the reminders anytime you want.
| | 00:25 |
So let's go ahead and take a look at it
action, and then we'll take a look at the code.
| | 00:29 |
We can see here we've got our app going,
up at the top here, we've got the app
| | 00:33 |
name MoovZ.
We've got the page name, Control panel,
| | 00:36 |
we have our two buttons, Start MoovZ and
Stop MoovZ.
| | 00:40 |
And we have the section down here at the
bottom where the list of moves is going
| | 00:43 |
to show up.
We go ahead and we tap on Start MoovZ.
| | 00:47 |
We get this popup here that says your
MoovZ are engaged and after we tap OK.
| | 00:53 |
You can see down here we have our lists
of times when our notifications are going
| | 00:57 |
to appear on our screen.
We don't have to be running the MoovZ on
| | 01:01 |
for the notifications to show up.
Let's just go back to the home screen,
| | 01:03 |
and we'll see what happens in a couple
minutes when the first MoovZ reminder is
| | 01:07 |
ready to come up.
And there we can see, on the home screen,
| | 01:13 |
we've got a notification here from our
app, MoovZ.
| | 01:16 |
That's the thing up here at the top the
next thing down is the title of this notification.
| | 01:21 |
In our case, MoovZ number one, and down
below that you can see when your next
| | 01:26 |
move is going to show up.
You can simply dismiss this by tapping on
| | 01:30 |
the Dismiss button or you can snooze it
by tapping on the Snooze 4 and selecting
| | 01:35 |
5 minutes, 10 minutes, an hour, 4 hours,
or a day.
| | 01:39 |
Those are things defined by the system
not by your app.
| | 01:42 |
In our case, we just click Dismiss.
Our next MoovZ is going to show up in
| | 01:46 |
another minute and a half, and we're
going to let that one show up.
| | 01:49 |
And then, we're going to let the one
after that show up, so that I can show
| | 01:52 |
you what happens when you have multiple
notifications on the screen at once.
| | 01:55 |
(SOUND) Here is our first notification,
MoovZ number 2.
| | 02:00 |
We're going to wait until the next
notification shows up so you can see what
| | 02:04 |
happens if you don't get back to the
device and dismiss or snooze.
| | 02:08 |
(SOUND) And here's our second
notification.
| | 02:12 |
You notice it says MoovZ number 3.
And it tells us when our next Moovz do.
| | 02:17 |
Now, it shows us that we have one of two
notifications so that if we come down
| | 02:22 |
here and we tap Dismiss, you can see the
previous one.
| | 02:26 |
Moovz number 2 is still there underneath
from Moovz that's not really significant.
| | 02:31 |
But for some applications, being able to
make sure you see every single
| | 02:34 |
notification might be crucial.
And that's why they stack up like that.
| | 02:38 |
Now let's go look and see how it's built.
You've seen MoovZ in action, now let's
| | 02:43 |
take a look at how it's built.
The UI is very simple, there's simply a
| | 02:48 |
Start MoovZ button, a Stop MoovZ button,
and a reminders text block, where we put
| | 02:53 |
in the list of times that reminders are
coming up in the future.
| | 02:57 |
Now, let's go and take a look at the
code.
| | 03:00 |
First of all, let's look at the Start
MoovZ.
| | 03:02 |
MoovZ are created using something called
the Scheduled Action Service, and every
| | 03:08 |
scheduled action has a name.
So, what we do is we get the current
| | 03:12 |
time, so we've got our root time.
We set our ReminderTextBlock to the empty string.
| | 03:17 |
And then, this is an arbitrary number, I
set it up to have 10 moves.
| | 03:21 |
Now, you notice that the four loop goes
from one to 11, as opposed to zero to 10,
| | 03:27 |
so we want the moves to be numbered one
through 11, not zero through 9.
| | 03:31 |
At the beginning here, on lines 51 and
52.
| | 03:34 |
What we do is go through and see if we
have any existing reminder that is set up
| | 03:38 |
with that name.
And if there is, we delete it.
| | 03:41 |
First up, let's make sure we don't have
an existing schedule of action with the
| | 03:45 |
same name we're trying to create right
now.
| | 03:47 |
Because you can come into the app and
just hit the Start MoovZ button again in
| | 03:51 |
order to create ten new reminders.
After we've deleted it, we create a
| | 03:56 |
reminder object.
And a reminder object can have three things.
| | 04:00 |
It has a title, it has a begin time, and
it has content.
| | 04:07 |
We set our title equal to moovz, pound
sign, and the id number of this
| | 04:11 |
particular reminder.
We set the begin time equal to the root
| | 04:15 |
time, and then we add 60 seconds times
our move time in minutes, times the
| | 04:20 |
number of this particular reminder.
Back at the beginning here, we've set the
| | 04:25 |
move time in minutes for the purposes of
demo to two.
| | 04:29 |
I'd recommend setting this to 15, 20, 30
minutes, however often you want to get up
| | 04:33 |
and stretch.
Then after we've created the reminder, we
| | 04:39 |
also go and fill in the reminder text
block.
| | 04:42 |
The one that's at the bottom below the
two buttons.
| | 04:45 |
In other words, we list the times as you
saw of the upcoming reminders.
| | 04:49 |
So, this code here simply says if the
reminder text block is empty.
| | 04:53 |
We put in this, the next time string.
If it's not, we concatenate a new line
| | 04:58 |
and then our next time string at the end
of that.
| | 05:00 |
And then finally, we simply call these
scheduled action servers Add Method to
| | 05:04 |
add our reminder.
And when we get done with all ten, we
| | 05:07 |
show a message box saying your moves are
engaged.
| | 05:11 |
If the user clicks the Stop button.
All we do is go through our loop of ten again.
| | 05:16 |
Look for the scheduled actions and if we
find them, we remove them.
| | 05:20 |
And then, we set the reminder text block
to that string whose removed.
| | 05:24 |
Don't forget your moves.
One last thing we did to fill in the
| | 05:28 |
reminder text block with the currently
pending moves when the app starts.
| | 05:32 |
Come back up here, is we set up a page
loaded event handler.
| | 05:36 |
And in there, we go through and iterate
through the scheduled actions.
| | 05:41 |
And try to find whatever moves are
already scheduled.
| | 05:44 |
If we can find that move, then we go and
ask, is this move in the past?
| | 05:50 |
If it's something that's already
happened, we don't put it into the list.
| | 05:53 |
Otherwise, we simply append it to the
reminder text block, showing you the list
| | 05:57 |
of reminders that are still yet to
happen.
| | 06:00 |
That's it, that's all there is to MoovZ.
And that's all there is to creating
| | 06:03 |
reminders in your apps in order to the
system to provide notifications, even
| | 06:08 |
when your app isn't running.
| | 06:09 |
| | Collapse this transcript |
| Wallet and In-App Purchase| 00:00 |
Windows Phone, in the version of Windows
Phone 8, allows you two ways to purchase
| | 00:04 |
things using your phone.
The first is called the Wallet.
| | 00:08 |
In the wallet, you can store, securely,
deals, coupons, memberships, and you can
| | 00:14 |
also store payment instruments like
credit cards and debit cards.
| | 00:18 |
You can even create background agents
which can debit from your payment instruments.
| | 00:22 |
Or add to your coupons based upon the
user taking the phone and swiping it near
| | 00:27 |
an NFC-compatible sticker.
The other way that you can purchase
| | 00:31 |
things using your phone is called in-app
purchase.
| | 00:34 |
This allows you to enable the user to buy
features or add content after they've
| | 00:38 |
purchased your app.
And there's two kinds of products.
| | 00:41 |
There's consumable products, which is
like points for a game or lives for a game.
| | 00:46 |
You can buy them over and over and over
again because the idea is that was in
| | 00:50 |
your app as the use uses the app.
Those products are consumed and then they
| | 00:55 |
can buy more.
Or there's the durable product.
| | 00:58 |
Now, a durable product is not really
something physical, but it means that
| | 01:02 |
once you bought it, you don't have to buy
it again.
| | 01:04 |
And typically that's used to enable more
features, because one business model you
| | 01:09 |
can use for Windows Phone 8.
Is to sell your app for free and then add
| | 01:14 |
the additional features as in app
purchase.
| | 01:17 |
This has been very successful on other
platforms, and now you can also do it on
| | 01:21 |
Windows Phone 8.
To find out more about how to set up apps
| | 01:25 |
for in app purchase, check out the
distributing Windows Phone apps through
| | 01:29 |
the Windows Phone Store course.
That's also available here on Lynda.com.
| | 01:34 |
| | Collapse this transcript |
| File and protocol associations| 00:00 |
Beginning in Windows Phone 8, you can add
your app to the list of apps that process
| | 00:05 |
particular file types.
In addition to that, you can also create
| | 00:08 |
a custom protocol that allows you to send
a link in an email message, for example.
| | 00:13 |
Or on a web page that causes your app to
launch.
| | 00:16 |
For file protocols, you can specify which
file types you open.
| | 00:20 |
And that allows you to specify that your
app can open different file types.
| | 00:24 |
So for example, if you have an Excel
spreadsheet viewer that understands xls
| | 00:29 |
files, you can now specify that your app
can also open them.
| | 00:33 |
An when the user tries to open one of
those files, it will be shown a list of
| | 00:36 |
apps that open those kind of files and
your app will be included in it.
| | 00:40 |
With custom protocols, you can specify,
not only that you want your app to open,
| | 00:44 |
you can even specify query parameters.
So that you could have a link that's in
| | 00:48 |
an email or a link that's on the web
page.
| | 00:51 |
That not only opens your app, but also
performs a specific function or goes to a
| | 00:56 |
specific place in your app.
Or is connected to a specific piece of
| | 00:59 |
data that then subsequently is downloaded
from the web by your app.
| | 01:02 |
This is a very powerful feature and it's
used in a variety of ways.
| | 01:07 |
Not only in connecting up your app to
data which can be downloaded from the web.
| | 01:11 |
But you can also use this as a way of
launching one app from another so that
| | 01:14 |
your users could prepare something in one
app.
| | 01:18 |
Touch a button in your app, you could
invoke the protocol with query parameters
| | 01:22 |
and open up a second app and get it to do
something for you.
| | 01:25 |
Something that's custom, so you could
have apps that trade data back and forth
| | 01:29 |
using the query parameters as a way of
communicating.
| | 01:32 |
You can also use the clipboard as a way
of communicating, what you can't do, is
| | 01:36 |
you can't use isolated storage to
communicate from one app to the other.
| | 01:40 |
So you'll have to think carefully about
how you're going to communicate between
| | 01:43 |
your apps.
But, for example, on IOS, this is used
| | 01:46 |
very frequently in audio processing apps.
To copy the audio data to the clipboard
| | 01:51 |
and then launch another app.
Which subsequently processes the audio on
| | 01:54 |
the clipboard, and sometimes even
relaunches the original app.
| | 01:58 |
| | Collapse this transcript |
| Bluetooth| 00:00 |
Beginning in Windows Phone 8, the
Bluetooth stack has been dramatically
| | 00:04 |
improved as well.
Now you can access Bluetooth
| | 00:07 |
functionality from your code using the
Bluetooth APIs.
| | 00:11 |
You can discover Bluetooth devices that
are nearby.
| | 00:14 |
You can use it for app-to-app
communication between two different
| | 00:17 |
devices, both running your app.
As well as you can use it for app to
| | 00:21 |
device communication If you have say
speaker or you have a keyboard.
| | 00:26 |
Or some other device which talks
Bluetooth inside your app.
| | 00:30 |
You can access the low level Bluetooth
protocols, pair up with the other
| | 00:34 |
Bluetooth devices and communicate
directly.
| | 00:36 |
And the operating system facilitates the
communication, so that you don't have to
| | 00:40 |
actually get down into the lowest levels
of the Bluetooth protocol.
| | 00:43 |
| | Collapse this transcript |
| Integrating speech| 00:00 |
Windows phone supports a variety speech
integrations.
| | 00:04 |
Built into the phone is the ability to
launch apps via speech.
| | 00:08 |
Beginning with Windows phone 8, you can
enable custom commands, so that you can
| | 00:12 |
not only launch your app.
But you can ask your app to do a specific thing.
| | 00:16 |
Let's say that your app was a camera and
your app was called Super Camera.
| | 00:21 |
And the command you wanted to do was
snap.
| | 00:23 |
You could actually say, launch Super
Camera, snap.
| | 00:27 |
And it would actually launch the app and
pass into you the fact that the user
| | 00:30 |
wanted to execute the snap command after
your app has launched.
| | 00:34 |
You can create custom dictionaries of
commands in addition to parsing regular
| | 00:38 |
English words.
The speech recognition APIs also allow
| | 00:42 |
you to do complete speech to text.
This is done using the Cloud, so you
| | 00:48 |
start dictating.
It listens to what you have to say.
| | 00:51 |
Sends the speech audio up into the
Microsoft Cloud, translates it into text,
| | 00:56 |
and sends it back to you.
When you get the data back, it not only
| | 01:00 |
has the text for what you spoke.
It has an indication of whether any of
| | 01:03 |
the things in the text represent words
that you might not want children to have.
| | 01:08 |
And you're allowed to say, I want
everything except I don't want the adult
| | 01:12 |
words in the text.
And finally, Windows Phone also supports
| | 01:16 |
the converse, speech from text.
You can ask Windows Phone to read textual
| | 01:21 |
information, AKA strings inside your app
in a variety of different human voices.
| | 01:27 |
| | Collapse this transcript |
| Near field communication (NFC)| 00:00 |
Some Windows Phone 8 devices, most
notably, the Nokia Lumia series, support
| | 00:06 |
what's called near field communication.
This is a set of radios that's built into
| | 00:11 |
your phone that allows you to have
encrypted communication with other
| | 00:14 |
devices that are 3 to 4 centimeters away
from your phone.
| | 00:17 |
This is used frequently, especially in
Europe, to allow you to pay for things
| | 00:22 |
using one of those things that we talked
about in your wallet.
| | 00:26 |
As a secure payment instrument, like your
credit card or debit card.
| | 00:29 |
You can talk to other phones by putting
the 2 phones very close together.
| | 00:33 |
There are smart billboards, you can
create an NFC sticker that allows you to
| | 00:37 |
simply swipe the phone next to the
billboard and collect things.
| | 00:41 |
Kind of like a radio frequency QR code.
You've probably seen some of the fast
| | 00:46 |
paid devices at certain retailers.
Those are implemented using NFC as well
| | 00:50 |
and with the appropriate software either
the wallet or your own custom software.
| | 00:55 |
You can implement solutions like fast pay
using your phone.
| | 00:58 |
API access to the near field
communications inside your apps is done
| | 01:03 |
by the ProximityDevice class.
And also, as I mentioned, NFC is
| | 01:08 |
connected up to the Wallet class so you
can use the Wallet subsystem to talk to
| | 01:12 |
NFC devices.
Without having to get at the lower level
| | 01:15 |
of NFC communication if what you really
want to do is purchasing.
| | 01:19 |
You can actually interact with the wallet
from your software.
| | 01:22 |
| | Collapse this transcript |
| WinRT and legacy Windows Phone APIs| 00:00 |
Windows Phone is an evolving platform.
On Windows Phone 8, the core level of the
| | 00:06 |
operating system was changed from Windows
CE to the Windows 8 core.
| | 00:10 |
This means that some Win Phone APIs from
Windows Phone 7, are deprecated and
| | 00:15 |
shouldn't be used beyond Windows Phone 8.
Except in a few key circumstances, most
| | 00:21 |
notably that is XNA.
And that means that building games for
| | 00:25 |
Windows Phone 8 and beyond, you shouldn't
use the XNA framework.
| | 00:28 |
You should also try to avoid isolated
storage.
| | 00:31 |
As we discussed earlier in the course,
you can still use the XNA framework for
| | 00:36 |
doing media capture and playback.
And you must use the isolated storage in
| | 00:40 |
order to support the built in sequel CE
system.
| | 00:43 |
Nokia in partnership with Microsoft, has
a great wiki page talking about code
| | 00:49 |
development for Windows Phone 7/8.
And Windows 8 talks about all the things
| | 00:53 |
that are compatible and which things are
compatible between which pieces of the
| | 00:57 |
operating system.
Windows Phone 8 also implements a major
| | 01:00 |
subset of the windows runtime, sometimes
called WinRT, from Windows 8.
| | 01:06 |
The most useful pieces of this are the
new storage model compatible with Windows 8.
| | 01:10 |
That means you can actually have code
that reads and writes your data files
| | 01:14 |
that you can use exactly the same between
Windows Phone and Windows.
| | 01:19 |
The only differences have to do with
exactly which folders are accessible.
| | 01:23 |
In Windows, sometimes you can access
things that are shared between apps.
| | 01:27 |
Whereas in Windows Phone you can never
access things that are shared between apps.
| | 01:31 |
WinRT brings the implementation of the
async and await keywords.
| | 01:35 |
This makes working with these new WinRT's
very simple and dramatically simplifies
| | 01:41 |
the way you do a synchronous processing
in a Windows Phone.
| | 01:44 |
WinRT also brings the Direct X API's for
doing media access but you must access
| | 01:50 |
those from C plus, plus.
Again, this is part of the reason why
| | 01:54 |
some of the XNA facilities for doing
audio recording and playback are still
| | 01:58 |
okay for using in a Windows Phone 8
application.
| | 02:01 |
Now, it's important to think about this
carefully because, beginning with the
| | 02:05 |
next generation, or perhaps the next
generation of that.
| | 02:08 |
Windows phone 8 will no longer support
those XNA APIs and will only allow you to
| | 02:13 |
use the media APIs.
The media APIs in Windows Phone 8 are a
| | 02:18 |
subset of what's available in Windows 8.
And hopefully by the time these two OS
| | 02:23 |
environments are merged together, the
managed APIs for capturing and playing
| | 02:28 |
back media will be robust and full
featured.
| | 02:31 |
In addition to WinRT, things that have
changed between Windows Phone 7 and
| | 02:35 |
Windows Phone 8.
Including fast application switching,
| | 02:38 |
reminders and alarms and an enhanced set
of live tile functionality, which we
| | 02:42 |
talked about briefly in chapter 9.
Next up, we're going to get into where to
| | 02:46 |
go from here.
Discussing how you publish your apps
| | 02:49 |
Learning from other apps in the market
place and staying in touch with new
| | 02:52 |
information from Microsoft.
| | 02:53 |
| | Collapse this transcript |
|
|
12. Where to go from herePublishing your apps| 00:00 |
In the process of developing this course,
we visited hundreds of websites, looked
| | 00:04 |
at hundreds of books, and read countless
articles.
| | 00:08 |
We've gathered together all the useful
links for websites, books, podcasts, and
| | 00:13 |
beyond to help you get from zero to hero.
We've also included them all in a
| | 00:18 |
document in the exercise files and the
free exercise files.
| | 00:22 |
So, you don't have to try to look at the
address bar here in the browser and write
| | 00:25 |
any of these things down.
You'll be able to click on them directly.
| | 00:28 |
So, let's get started.
First up, we're going to talk about
| | 00:31 |
publishing your apps.
The Windows Phone Developer tools are free.
| | 00:35 |
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
| | 00:45 |
App Hub.
You need to join the Microsoft Developer program.
| | 00:48 |
Now, the Microsoft Developer program is
$99 a year, as you can see for Windows Phone.
| | 00:54 |
That gives you the ability to make free,
paid or ad-funded apps, submit an
| | 00:59 |
unlimited number of paid apps to the
marketplace and up to 100 free apps.
| | 01:03 |
Now, if you want to build more than 100
free apps, you can see costs 20 bucks each.
| | 01:08 |
All apps that you submit are content and
code certified to make sure that they'll
| | 01:12 |
run on all the windows phone handsets out
there.
| | 01:15 |
To join the app hub program for
publishing, you come to this page and
| | 01:19 |
click on join now.
In case your wondering why we arent going
| | 01:23 |
through the whole submission process.
It's because Microsoft makes frequent
| | 01:27 |
changes to the certification and the
submission, so the page that you see here
| | 01:32 |
may not look like this by the time that
you get there.
| | 01:35 |
So, you'll want to look at the page the
way it looks when you get there and
| | 01:37 |
follow those instructions.
Microsoft has also provided a full how it
| | 01:42 |
works page for the app hub, describing
how the app hub works about the free tools.
| | 01:48 |
How to get special help, how to sign up
for the developer program, and about how
| | 01:53 |
to connect up once you've signed up for
the developer program.
| | 01:57 |
To be able to track the apps that you've
submitted to the marketplace.
| | 02:00 |
And watch your downloads in sales.
Finally, when you're completely ready,
| | 02:06 |
you're a member of the App Hub, you're a
certified developer, and you've got your
| | 02:09 |
app ready to go.
You need to follow through the
| | 02:12 |
instructions you see on the screen here,
these four steps, to submit your application.
| | 02:16 |
You've got to make sure that you've got
everything in your app package, a proper
| | 02:20 |
name for the App Hub, how it's set-up for
distribution.
| | 02:24 |
Actually, upload the app file from the
build that you did, make sure that you've
| | 02:28 |
got the proper version number.
And if you need a technical exception
| | 02:32 |
because there's some aspect of the
certification process, you can ask
| | 02:36 |
Microsoft for a specific exception.
And of course, on a case-by-case basis,
| | 02:40 |
they'll make that decision.
Microsoft has even included some best
| | 02:43 |
practices for application marketing.
They help you figure out how to get the
| | 02:47 |
most people to download your app.
| | 02:48 |
| | Collapse this transcript |
| | Learning from apps in the Windows Phone Marketplace | | Staying in touch with updates and new information from Microsoft | Looking at Windows Phone 7 app reviews| 00:00 |
Once you've shipped your app, the next
thing up is to learn what customers think
| | 00:05 |
of your app.
On windowsphone.com, they're going to be
| | 00:09 |
giving you direct feedback.
They're going to be giving you reviews
| | 00:11 |
and ratings.
So, you should read that regularly to
| | 00:14 |
connect with your customers.
WP App Info and WP Central are two
| | 00:19 |
independent third party sites where you
can submit your app for review.
| | 00:23 |
A good idea is to submit your app for
review either at the time you launch it.
| | 00:27 |
Or sometimes even before to give the
editors a chance to decide whether they
| | 00:31 |
would actually like to feature you app
and write an article about it.
| | 00:34 |
If your app is in the category of office
tools or productivity, you might also be
| | 00:40 |
able to interest Paul Thurrott over at
winsupersite.com.
| | 00:44 |
| | Collapse this transcript |
| | Exploring web sites books and other useful links |
|
ConclusionFarewell| 00:00 |
Well congratulations.
You made it to the end of Windows Phone
| | 00:03 |
SDK Essential Training.
This is just the beginning of your
| | 00:07 |
journey as a Windows Phone app developer.
The next best steps are, first of all, to
| | 00:12 |
review the additional Microsoft samples
that go into great detail on very
| | 00:16 |
specific technologies.
We cover the essentials in this course.
| | 00:21 |
There's lots and lots of tools and
technologies inside the Windows Phone
| | 00:25 |
ecosystem that you may need to use in
your apps that aren't covered in this course.
| | 00:28 |
So, go and make the Windows Dev Center
your friend.
| | 00:32 |
Next, I highly suggest that you build
yourself a series of four, five, ten what
| | 00:37 |
I call recipe apps, apps that have the
simplest infrastructure to to specific
| | 00:42 |
things, for example.
If you need to be able to remember how to
| | 00:46 |
do pivot apps, build yourself a simple
pivot app that has just a simple data source.
| | 00:52 |
And a couple of pivots that you can refer
to later when you need to remind yourself
| | 00:56 |
how to set up to do a pivot.
It's easier to have these apps built like
| | 01:00 |
we did with the sensors app, that have
the basics in there.
| | 01:03 |
Rather than try to go back and extract
the information and refresh your memory
| | 01:08 |
from a completed production app.
And when you're ready to share your
| | 01:11 |
masterpiece with the world, take the
distributing Windows Phone apps through
| | 01:15 |
the Windows Phone store course here on
Lynda.com.
| | 01:18 |
In which I'll take you step by step
through the process of signing up for
| | 01:22 |
your developer account, beta testing, and
shipping.
| | 01:25 |
Either you're paid, you're advertising
based, or you're in app purchase based,
| | 01:29 |
or free app through the Windows Phone
store, from beginning to end.
| | 01:33 |
| | Collapse this transcript |
|
|