IntroductionWelcome| 00:00 |
(music playing.)
| | 00:04 |
Hi, I'm Michael Lehman.
| | 00:05 |
Welcome to Building a Note-Taking App for
Windows Phone and Windows Store.
| | 00:09 |
This course will teach you how to build a
simple note-taking app from start to
| | 00:12 |
finish.
There are two related courses teaching you
| | 00:16 |
how to build this same app for iOS and Android.
| | 00:18 |
We'll begin by walking through a demo of
the completed apps, followed by an
| | 00:22 |
overview of some of the issues you would
encounter in building the same app across
| | 00:25 |
multiple platforms.
Then, after a review of the common design
| | 00:30 |
patterns used when building Windows Phone
and Windows Store apps, we'll move on to
| | 00:34 |
exploring how and where you can share code.
| | 00:37 |
And where you'll need to build portions of
the app specific to each platform.
| | 00:41 |
We'll build the common code first and then
alternate between Windows Phone and
| | 00:44 |
Windows Store as we build first the user
experience and then the code behind and
| | 00:48 |
then publish our apps and make them ready
to ship in the Store.
| | 00:53 |
So let's roll up our sleeves and get
started.
| | 00:55 |
| | Collapse this transcript |
| Using the exercise files| 00:00 |
In this course, we've included free
exercise files, which you can download in
| | 00:03 |
one of the other sections of this page.
I highly recommend you take the exercise
| | 00:07 |
files, unzip them and put them on the
desktop, because that makes them easy to
| | 00:10 |
find as you're working your way through
the data in the course and the challenges.
| | 00:15 |
Inside the exercise files for this course
are specific starting and stopping points
| | 00:19 |
for chapters 5, 6, 7, and 8.
As well as, completed versions of the note
| | 00:24 |
taking app for Windows phone and Windows store.
| | 00:27 |
In addition we've included a number of
graphic assets here in the assets folder,
| | 00:30 |
that you can use to enhance your apps and
make them look professional.
| | 00:34 |
| | Collapse this transcript |
| Using the challenges| 00:00 |
This course includes several videos called challenges.
| | 00:03 |
Challenges are activities that give you a
hands-on opportunity to practice and
| | 00:06 |
master what you're learning.
I'll start each challenge by describing
| | 00:10 |
your core objective for the activity.
If the challenge involves using any sample
| | 00:14 |
files, I'll tell you where to find them.
I'll also give you the rough estimate on
| | 00:17 |
how much time it took me to complete the challenge.
| | 00:20 |
When you completed the challenge, make
sure to watch the matching solution video.
| | 00:23 |
In each solution, I'll show you how I
solve the solution and give you some of my
| | 00:26 |
thinking along the way.
Again, this is an opportunity for you to
| | 00:30 |
roll up your sleeves and make what you've
been hearing real.
| | 00:33 |
And at the end of each challenge, you'll
have made the App you're building more and
| | 00:36 |
more complete.
| | 00:38 |
| | Collapse this transcript |
| Prerequisites and related courses| 00:00 |
What do you need to know to take this course?
| | 00:03 |
This course is for developers who want to
build Windows Phone and/or Windows Store
| | 00:06 |
apps.
And developers with experience in other
| | 00:10 |
mobile platforms who want to build for
Windows Phone and/or Windows Store.
| | 00:14 |
In order to make the most out of this
course, you should have a good background
| | 00:17 |
in C# and be familiar with Visual Studio 2012.
| | 00:20 |
If you need a refresher on any of these
topics, the Lynda.com online training
| | 00:23 |
library has courses in C#, Visual Studio,
Windows Phone SDK, and two courses on
| | 00:27 |
building your first Windows store app.
One focusing on C#, and the other on
| | 00:33 |
Visual Basic.
In this course, we'll be using exclusively
| | 00:37 |
C#.
| | 00:38 |
| | Collapse this transcript |
|
|
1. Cross-Platform DevelopmentDemoing the note-taking app| 00:00 |
As we're building two apps in this course
let's take a look at the features of these
| | 00:03 |
apps running on Windows Phone and on
Windows 8.
| | 00:06 |
Plain Ol' Notes is what we call the app
and it has common features between both of
| | 00:09 |
these apps as well as the features shared
with apps in this series the Creating a
| | 00:13 |
Note Taking App for iOS and Creating a
Note Taking App for Android.
| | 00:19 |
Creating and editing simple text based notes.
| | 00:21 |
Navigation and data sharing between
multiple pages of an app, and saving data
| | 00:25 |
to persistent storage.
Windows Phone app has two pages.
| | 00:29 |
A list of notes and an editor, and it
looks like this.
| | 00:32 |
It's got the title Plain Ol' Notes at the top.
| | 00:34 |
It's got the Page Name Notes, and it's got
a list of notes with a pencil at the end
| | 00:38 |
of each one.
Hinting to the use that if they tap on
| | 00:43 |
this, they can edit the note.
And in this list, there's a single
| | 00:48 |
individual entry for each note.
And to add a new note, we simply click the
| | 00:53 |
add button down here at the bottom and we
can type in a new note; this is a really
| | 00:56 |
nice note.
And there we go.
| | 01:01 |
We have our new note right here at the bottom.
| | 01:03 |
To delete, you simply hold the finger down
on one and select Delete Note.
| | 01:07 |
(SOUND) And we have a confirmation dialog.
Once you answer yes, the note goes away.
| | 01:12 |
With the Windows Store version of the app,
we have the same thing.
| | 01:15 |
Two pages; a list of notes and an editor
but it looks much, much different.
| | 01:18 |
Let's take a look.
Here's the Windows Store version of Plain
| | 01:21 |
Ol' Notes.
Running on a simulator that looks like a
| | 01:25 |
Microsoft Surface tablet, or one of many
touchscreen laptops that you might find
| | 01:28 |
running Windows 8.
The main page has a list of all the notes.
| | 01:33 |
And as you select each individual note,
you can click here and see a preview of
| | 01:36 |
what's in the note.
When you want to edit the note you click
| | 01:42 |
on the hand with the pencil here and we'll
make our camping trip for August.
| | 01:47 |
(SOUND) And we'll go back and see that
that's been updated and our note is still
| | 01:49 |
selected.
To add a new note, you have to bring up
| | 01:52 |
the App bar for a system with no
touchscreen you use the right mouse button
| | 01:54 |
to bring up the App bar.
If you have a touch screen, and we can
| | 01:59 |
simulate that with a simulator, you simply
swipe up from the bottom.
| | 02:03 |
Or swipe down from the top.
And the app bar shows up.
| | 02:07 |
We click the Add button, and here's our
new note.
| | 02:14 |
And there we go.
There's our new note.
| | 02:16 |
When you want to delete one, you can
either left-click or right-click.
| | 02:20 |
In this case, we'll just left-click swipe
up to bring up the App bar select Delete.
| | 02:26 |
You see, we have confirmation, we say yes
and the note goes away.
| | 02:29 |
And that's a quick look at the features of
Plain Ol' Notes that we're going to
| | 02:32 |
implement for both Windows Phone and
Windows Store in this course.
| | 02:36 |
| | Collapse this transcript |
| Issues in cross-platform development| 00:00 |
As this course is part of a series of
Building a Note-Taking App for iOS, for
| | 00:03 |
Android and for Windows Phone, Windows
Store, it's interesting to look at the
| | 00:07 |
issues surrounding cross-platform development.
| | 00:13 |
The issue is supporting multiple mobile
operating systems.
| | 00:15 |
If you want to deploy on an iOS, Android,
Windows Phone and Windows Store, and get
| | 00:20 |
the best possible performance and broadest
access to device features and direct
| | 00:24 |
support from your OS vendor, your decision
is use the native tools and languages.
| | 00:30 |
You can also consider using PhoneGap and
Sencha, which use HTML, CSS, and
| | 00:34 |
JavaScript with a unique library for each
device type.
| | 00:38 |
And there's more information on doing
cross-platform solutions at PhoneGap.com
| | 00:43 |
and Sencha.com.
There's even another way of thinking about
| | 00:47 |
alternative solutions.
If you'd like to write everything in C#,
| | 00:50 |
you can try Mono and Xamarin.
They use C# and they have a unique
| | 00:54 |
implementation of the .NET Base Class
Library for each device type.
| | 00:58 |
For iOS, you still use Xcode and Interface
Builder to build your interface.
| | 01:02 |
For Android, you still use Eclipse or
Android Studio to build your user
| | 01:05 |
interface, but you can put all of your
logic in C#.
| | 01:07 |
And of course, if you're building for
Windows Phone or Windows Store, you can
| | 01:11 |
use Visual Studio, which is what C# is
natively designed for.
| | 01:15 |
The challenges of using native tools are
that you have multiple programming
| | 01:18 |
languages.
For iOS, you have to learn Objective-C.
| | 01:22 |
For Android, you have to be an expert at Java.
| | 01:25 |
And for Windows phone and Windows Store,
you need to use either C# or Visual
| | 01:29 |
Basic.net.
And you also have multiple toolkits to
| | 01:32 |
take into account.
For iOS, there's Xcode.
| | 01:35 |
For Android, there's Eclipse or Android
Studio, which comes directly from Google.
| | 01:39 |
And for Windows, of course, there's Visual Studio.
| | 01:42 |
Going native is what I think is the best choice.
| | 01:45 |
You get the best performance, the best
access to unique device features, and
| | 01:48 |
direct support from the operating system vendor.
| | 01:51 |
And most importantly of all, you get the
cleanest upgrade path when a new version
| | 01:55 |
of the OS ships from either Apple, Google,
or Microsoft.
| | 02:00 |
| | Collapse this transcript |
| Managing source control| 00:00 |
Just a quick note about source control.
If you watched my course here on
| | 00:03 |
Lynda.com, Fundamentals of Software
Version Control, you'll know that I'm a
| | 00:06 |
big fan.
Visual Studio has built-in source control.
| | 00:10 |
We're working with Windows Phone and
Windows 8 here.
| | 00:12 |
And your options are Team Foundation
Server for Microsoft, Git, which is the
| | 00:16 |
most popular both close source and open
source, sourced control system, being used
| | 00:19 |
for mobile development right now.
Or you may have to use something that is
| | 00:24 |
chosen your corporation such as
Subversion, Mercurial or Perforce.
| | 00:29 |
But whatever you do, pick at least one and
keep your apps up to date in source code
| | 00:32 |
control.
| | 00:34 |
| | Collapse this transcript |
|
|
2. Understanding Windows Phone and Windows Store Design PatternsUnderstanding the app class structure| 00:00 |
As we're going to be implementing for both
Windows Phone and Windows Store, a brief
| | 00:04 |
look at the class structure of each app on
each operating system is in order before
| | 00:07 |
we begin.
On Windows Phone, our app has multiple
| | 00:12 |
pages.
Each page extends a class called Phone
| | 00:14 |
Application Page.
Navigation between pages is done using
| | 00:18 |
URI,s.
And parameter passing is done using query
| | 00:21 |
parameters on those URI's.
For example,
| | 00:25 |
/SecondPage.xaml?parm1=33&parm2=foo.
On Windows Store apps, you still have
| | 00:32 |
multiple pages, but each page extends a
class simply called page.
| | 00:37 |
And most pages extend to class called
LayoutAwarePage, which, in conjunction
| | 00:40 |
with the XAML emitted by the project
templates built into Visual Studio, gives
| | 00:44 |
you automatic handling not only of
orientation changes but the different
| | 00:48 |
split panes sizes that an app can have
when running on a Windows 8 device.
| | 00:54 |
Small pane to the left or right, or a big
pane on the left or the right, or taking
| | 00:58 |
over the whole screen.
Navigation uses types as opposed to URIs.
| | 01:05 |
For example, typeof(EditorPage)).
And parameter passing is done using a
| | 01:09 |
single object instead of query paratmeters.
| | 01:12 |
If you need to pass multiple parameters,
you have to create your own class and pass
| | 01:15 |
an instance of that class in.
Most often it's done like this, where you
| | 01:20 |
say, Frame.Navigate(typeof(EditorPage),item.ID)
| | 01:24 |
as a string or a number passing between pages.
| | 01:28 |
But you only get one object to pass
between pages, therefore, if you need to
| | 01:31 |
pass multiple pieces of information, you
have to declare your own class holding
| | 01:34 |
your multiple properties.
| | 01:37 |
| | Collapse this transcript |
| Understanding the app model used in these project courses| 00:00 |
Next, let's take a look at the app data model.
| | 00:02 |
One of the reasons we put both the Windows
Phone and the Windows Store version of
| | 00:06 |
these apps in the same course is that they
use the same data concepts called Model -
| | 00:09 |
View - View Model.
It's used by both Windows Phone Apps and
| | 00:14 |
Windows Store Apps.
It's an extension of model view
| | 00:17 |
controller.
It inter-operates with the XAML or the
| | 00:20 |
View in order to be able to pull data from
the view model.
| | 00:24 |
There's direct data binding to the XAML,
so it's done symbolically.
| | 00:28 |
And finally, it's based on
IObservableCollection and
| | 00:31 |
INotifyPropertyChanged interfaces.
The Observable Collection implies that the
| | 00:35 |
XAML will get notified when the collection
changes, because it can watch for changes.
| | 00:40 |
So you never have to tell your view, go
update yourself.
| | 00:42 |
You simply change the model, and the view
automatically follows, and the
| | 00:46 |
INotifyPropertyChanged interface is how
you do that notification.
| | 00:50 |
Every time you change a property on one of
your views, you call
| | 00:53 |
NotifyPropertyChanged, and raise a
PropertyChanged event, which causes the
| | 00:56 |
listener, in this case, the XAML, to wake
up and go oh, I need to do a layout of the
| | 00:59 |
user interface again based on the changed
data.
| | 01:04 |
| | Collapse this transcript |
| Understanding the app page flow used in these project courses| 00:00 |
We've looked at the class structure we've
looked at the data model now let's take a
| | 00:03 |
look at the visual flow between pages for
apps in both Windows phone and Windows
| | 00:07 |
Store.
Both Windows Phone and Windows Store apps
| | 00:11 |
have a battery-aware app lifecycle,
meaning your app gets started suspended
| | 00:15 |
and terminated at will by the operating system.
| | 00:19 |
Both use the page metaphor.
And Windows 8 also includes three specific
| | 00:23 |
screen states.
Full screen, Snapped large, and Snapped
| | 00:27 |
small.
Because in Windows 8, you can have two
| | 00:31 |
apps on the screen at once.
And when you have two on the screen at
| | 00:34 |
once, one is in the large state and one is
in the small state.
| | 00:37 |
And you can switch back and forth between
the large state and the small state for
| | 00:39 |
the two apps.
| | 00:40 |
| | Collapse this transcript |
| Understanding the code behind and why it is specific to this course| 00:00 |
Every mobile operating system has a way in
which the view, what the user sees on the
| | 00:04 |
screen is connected to the code, which is
the motivating factor that makes the view
| | 00:07 |
do something.
In Windows store and Windows Phone, this
| | 00:12 |
is called Code Behind.
This separates your code and your markup.
| | 00:16 |
The markup, the description of what the
user interface looks like Is done in an
| | 00:20 |
XML based variant called XAML.
The XAML specifies the base class which is
| | 00:24 |
how it knows which piece is the Code Behind.
| | 00:27 |
Code Behind is similar to the
ViewController in iOS and similar to the
| | 00:30 |
Activity in Android.
The Code Behind is an extension of the
| | 00:34 |
Page class and it's the Controller in the
MVC model.
| | 00:38 |
And it handles all the user actions.
And the code behind connects the data in
| | 00:42 |
the ViewModel, to the view, using a DataContext.
| | 00:45 |
This allows the XAML to symbolically
reference items in the Data Context
| | 00:49 |
without having to have a direct connection
into the code.
| | 00:53 |
This works because .NET implements
reflection, which allows the XAML engine
| | 00:57 |
to look inside of the properties of your
data objects and pull data out by name.
| | 01:03 |
| | Collapse this transcript |
|
|
3. Understanding Windows Phone SpecificsConcepts unique for Windows Phone| 00:00 |
Let's take a look at the concepts that are
unique for Windows Phone.
| | 00:04 |
Windows Phone App structure consists of
one or more pages.
| | 00:07 |
Each page is a pairing of XAML and code.
Navigation is handled by the
| | 00:11 |
NavigationService Method.
The equivalents for IOS and Android are
| | 00:15 |
View+ViewController, and calling API's to
show another view.
| | 00:20 |
And in Android, Layout+Activity and
invoking an intent to change from one
| | 00:24 |
screen to the next.
So, the basic app life cycle for Windows
| | 00:28 |
Phone will look at these green boxes here.
Application launching up here at the top
| | 00:33 |
right, a page gets launched.
It's OnNavigatedTo gets called and the app
| | 00:36 |
is running.
When the app get deactivated, say a phone
| | 00:39 |
call comes in, the pages on navigator from
method gets called and we end up in this
| | 00:43 |
lower right hand corner green box,
application deactivated.
| | 00:47 |
When you're done on the phone, if the
application hasn't been dormant for an
| | 00:50 |
extended period of time, it'll simply get
activated again, the pages on navigated to
| | 00:54 |
method will be called again.
And your app will be running and when the
| | 00:58 |
user hits the Windows button and quits the
app, the pages OnNavigated method will be
| | 01:01 |
called, and the application closing event
will happen as you see in the upper left
| | 01:05 |
hand corner.
For Windows, there's differences between
| | 01:10 |
phone and tablet.
There's a common OS core, but the phone
| | 01:13 |
has some phone-only API's.
And the phone has legacy Windows phone 7
| | 01:18 |
API's, which aren't present on Windows Store.
| | 01:21 |
In the Windows world, a tablet is the same
as a desktop.
| | 01:25 |
Every app that you build for a Windows
tablet form factor also can run with a
| | 01:28 |
keyboard and a mouse on the desktop.
The desktop and tablets have multiple
| | 01:33 |
modes, full plus the two snapped sizes we
mentioned earlier.
| | 01:37 |
| | Collapse this transcript |
| Android developers beware| 00:00 |
If you're a developer coming from the
Android platform, here are a few things to
| | 00:03 |
be aware of when moving to Windows Phone
and Windows Store apps.
| | 00:07 |
No layout sharing.
No intents.
| | 00:10 |
There are some launchers and choosers
built into the operating system, but
| | 00:12 |
there's no way to build something that
works between multiple apps, to perform a
| | 00:15 |
single function.
Many OS access points that are available
| | 00:19 |
to you in android, are not available.
There's no access to the phone.
| | 00:23 |
There's no access to SMS, there's no task
manager for the user to be able to force
| | 00:27 |
close apps, or manage memory.
And finally there's no shared files.
| | 00:32 |
Every app lives in it's own sandbox.
| | 00:34 |
| | Collapse this transcript |
| iOS developers beware| 00:00 |
If you're a developer coming from iOS,
there's a few things you might want to be
| | 00:03 |
aware of as you begin your Windows Phone
and Windows Store app journey.
| | 00:09 |
Everything in Windows is dynamic screen layout.
| | 00:11 |
There's no interface builder.
If you want to create something that has
| | 00:14 |
an exact layout, you can do it but, it's
done using the Windows designer inside
| | 00:18 |
Visual Studio or the Blend tool.
And it's highly discouraged, because there
| | 00:23 |
are lots of different device sizes for
Windows Phone, and especially for Windows
| | 00:26 |
Store.
Windows Phone is definitely less
| | 00:29 |
skeuomorphic than every version of iOS
from Version 1 to Version 6.
| | 00:34 |
Meaning, things don't look like they look
like in physical real world instances.
| | 00:40 |
Things look very clean.
There are square boxes for buttons.
| | 00:44 |
They're simple black and white user
interfaces, or simple colors.
| | 00:48 |
Windows Phone navigation has unique
support built into the operating system.
| | 00:52 |
There's a Pivot control, which allows you
to look at the same data set from multiple
| | 00:56 |
different viewpoints, such as, a list of
sonnets and you're favorite sonnets.
| | 01:01 |
You can find a description of that in my
Windows Phone SDK Essential Training
| | 01:05 |
Course.
And the Panorama, where you're looking at
| | 01:08 |
a large collection of data, more like a
magazine where as you flip from page to
| | 01:12 |
page, you see a common background across
the pages and different kinds of
| | 01:15 |
information.
For example, a weather app, might have a
| | 01:20 |
panorama with a set of clouds or sunshine
in the background and on one page have
| | 01:23 |
temperatures, on another page have maps.
And on a third page have a list of
| | 01:28 |
forecast data.
And finally, Windows Phone 8 has similar
| | 01:32 |
but much different launchers and choosers
for things like Compose an Email or Pick a
| | 01:37 |
Date or Send an SMS message.
| | 01:41 |
| | Collapse this transcript |
|
|
4. Understanding Windows Store SpecificsUnique concepts for Windows Store apps| 00:00 |
If you're coming from iOS or Android,
there's a few unique concepts for Windows
| | 00:03 |
Store Apps.
An app consists of one or more pages.
| | 00:06 |
Each page is a pairing of XAML and code.
Navigation is handled by the
| | 00:11 |
Frame.Navigate method and the equivalents
for iOS and Android are View +
| | 00:14 |
ViewController and calling API's to show
another view, and on Android, layout plus
| | 00:18 |
activity.
And invoking an intent to change screens.
| | 00:23 |
The app life cycle for a Windows Store App
is pretty simple.
| | 00:27 |
It gets activated when the user starts the
app and its in the running state.
| | 00:30 |
It can get suspended when the user
switches to another app, when the user
| | 00:33 |
minimizes the app, and then it can come
back and be resumed at any time.
| | 00:38 |
And finally, it can end up in the not
running state when the user quits the app.
| | 00:42 |
| | Collapse this transcript |
| Android developers beware| 00:00 |
If you're coming from Android, there's a
few things you might want to be aware of,
| | 00:02 |
when building Windows Store apps.
There's a separate UI scheme for phone
| | 00:06 |
versus tablet, unlike Android where you
simply have a different screen size.
| | 00:11 |
There's nothing like intents.
But there are contracts instead.
| | 00:15 |
There's a sharing contract and a search
contract, which operate in somewhat
| | 00:18 |
similar manners.
And many OS access points are not
| | 00:21 |
available.
For example, there's no task manager
| | 00:24 |
access for apps and shared files are
optional and must be justified.
| | 00:28 |
You're encouraged to keep all of your data
inside your app Sandbox.
| | 00:32 |
| | Collapse this transcript |
| iPhone developers beware| 00:00 |
If you're coming from the iOS platform
there's a few things you might want to be
| | 00:03 |
aware of as you move to building to apps
for Windows store.
| | 00:06 |
There's a number of major differences
between iOS and Windows pone 8 and Windows
| | 00:11 |
8.
Its not the same OS as on the phone
| | 00:13 |
Windows store is Windows 8 and Windows
phone is Windows phone 8.
| | 00:18 |
There are some core components but they're
not the same OS.
| | 00:21 |
It's always dynamic screen layout, there's
no interface builder.
| | 00:24 |
It's like using the layout mechanisms in
iOS all the time.
| | 00:28 |
Navigation is very different, there's 3
screen states.
| | 00:32 |
You can have snap to the left, snap to the
right, small and large, as well as full
| | 00:36 |
screen.
There's no stack navigation support.
| | 00:40 |
You have to build in your own support.
The templates provide the equivalent of
| | 00:43 |
stack navigation support with a go back
button but, there's no navigation
| | 00:46 |
controller that allows you to inspect the
stack of pages and manipulate things that
| | 00:50 |
way.
And there's quite different launchers and
| | 00:53 |
choosers on Windows Phone 8 than there are
on iOS.
| | 00:56 |
And on Windows 8 for Windows Store apps
there's a whole different concept called
| | 01:00 |
contract which are much more like the
intent system available on the Android
| | 01:03 |
operating system.
| | 01:05 |
| | Collapse this transcript |
|
|
5. Creating the Data ModelUnderstanding the data model| 00:00 |
In this chapter, we're going to talk about
the data model.
| | 00:02 |
And we're going to build a common data
model to use in both the Windows Phone and
| | 00:06 |
the Windows Store version of plain old notes.
| | 00:10 |
In both Windows Phone and Windows Store
apps, the ViewModel convention is used
| | 00:14 |
where the model holds the data structure
for the app.
| | 00:18 |
the view holds the user interface definition.
| | 00:21 |
And the view model handles data
manipulation and persistence.
| | 00:25 |
Things like adding an item to a list of
items and storing and retrieving data from
| | 00:29 |
external devices.
So first we're going to take a look at the
| | 00:34 |
raw out of the box templates for a windows
phone app and a windows store app.
| | 00:39 |
And take a look at what the data model
looks like as provided initially by
| | 00:42 |
Microsoft.
And then, we're going to look at the data
| | 00:45 |
model which is both a model and a view model.
| | 00:47 |
That were going to build in this chapter
and then we'll look at how that's
| | 00:50 |
different than what's in the Windows Phone
and Windows store app and how we're going
| | 00:54 |
to create a common one.
So, let's go off to visual studio and
| | 00:59 |
build a out of the box, from the template,
symbol application, for Windows Phone and
| | 01:03 |
for Windows Store.
And take a look at the codes that's
| | 01:07 |
generated from the template.
So first let's go build a out of the box
| | 01:11 |
Windows Phone app.
I'm going to go to Templates > Visual C# >
| | 01:15 |
Windows Phone > Windows Phone DataBound app.
| | 01:19 |
This is an app that has not only the View
already preconstructed, but also a sample
| | 01:23 |
model and view model for us to use.
And so we're going to call this OOB in
| | 01:29 |
phone.
And if we take a look at what's in the
| | 01:35 |
solution, since we're looking just at the
data model at this point, we'll see two
| | 01:38 |
things in the View Models folder, an Item
View Model and a Main View Model.
| | 01:43 |
Now, the Main View Model is that view
model that I was talking about where it
| | 01:45 |
contains the collection of items and
maintains the individual items in your
| | 01:48 |
data model.
The item view model is the information for
| | 01:53 |
a single individual item.
So first of all let's go take a quick look
| | 01:56 |
at what the item view model looks like.
And the way XAML works with data binding,
| | 02:00 |
for those of you coming from the iOS and
Android platforms, this is similar to
| | 02:04 |
maintaining the data in your model and
handling the way that you notify.
| | 02:10 |
The user interface, the things have
changed in the model.
| | 02:12 |
In an iOS app, this is something like how
things happen when you want to reload the
| | 02:16 |
table data after you've changed the data
model underneath the table.
| | 02:20 |
And similarly, in an Android app, when
you've changed data in the table and you
| | 02:23 |
need to inform the adapter that the data
has changed.
| | 02:27 |
The way that's done in Windows Phone and
Windows Store is by using this basic
| | 02:30 |
interface called I notify property changed.
| | 02:34 |
And basically the infrastructure uses
introspection to bind the data from the
| | 02:38 |
data model to the user interface.
And then every time you make a change in
| | 02:42 |
the data, you have to call a method in the
I notify property changed interface in
| | 02:46 |
order to tell external watchers that the
data inside this data model has changed.
| | 02:51 |
So if we look at this very simple data
model, we can see.
| | 02:54 |
That we have our item view model, which is
the name of our class.
| | 02:58 |
And it extends, INotifyPropertyChanged.
And every data property in here has two
| | 03:00 |
parts.
It has a backing variable.
| | 03:01 |
In this particular case, string _id.
And a public property, which has a getter,
| | 03:06 |
which simply returns the value of that ID
and a setter, which checks to see if the
| | 03:11 |
new value is different than the value of
the id, if the value is different than
| | 03:16 |
that of the underbar id backing variable.
It not only sets the value, here on line
| | 03:24 |
30, it also calls this method notified
property change, and passes in the string
| | 03:29 |
name of this property.
This is how, when the user interface is
| | 03:34 |
bound in a property, if there were any,
that when the data item is changed, the
| | 03:38 |
user interface can automatically change.
In the out of the box template for the
| | 03:44 |
item view model in a Windows phone there
are three properties here.
| | 03:48 |
There's line one, line two, and line three.
| | 03:51 |
They have their corresponding backing
variables here line one, line two, and
| | 03:55 |
line three and their corresponding getters
and center properties, line one.
| | 04:00 |
Line two and line three.
Now we take a look at line three here and
| | 04:03 |
you can see it looks just like line one
except that the backing variable is
| | 04:06 |
underscore line three, instead of
underscore line one.
| | 04:11 |
But they all share this same notify
property changed method, so let's take a
| | 04:14 |
look at the notify party change method
because it's shared by every single
| | 04:17 |
property.
The way it works is that there's a .net
| | 04:22 |
event here, a property changed event.
And the way the system works underneath
| | 04:27 |
the covers is when you do a binding from
XAML to this data property it adds a
| | 04:30 |
listener in this event handler.
So that they can find out when properties
| | 04:36 |
have changed, and then the method notify
property changed, which is part of that
| | 04:39 |
interface that I mentioned.
Top, I notify property changed, takes in a
| | 04:43 |
property name and looks to see whether or
not anybody's listening.
| | 04:48 |
If the handler isn't empty, that means at
least one other piece of the code is
| | 04:51 |
listening.
Then we raised a property changed event
| | 04:54 |
and pass it a property changed event args
structure, which is passed in the property
| | 04:58 |
name and that's how, when the Xaml says,
this field is bound to the line 1
| | 05:02 |
property, when line 1 changes, it's
listing for changing on the model.
| | 05:08 |
The model says, hey line 1 changed.
The Xaml binding logic can then go
| | 05:12 |
retrieve the value of the line 1 property.
And change the way it looks on the user
| | 05:16 |
interface.
Now, let's take a look at the view model
| | 05:19 |
here in main view model.
Similarly, it's an I notify property
| | 05:23 |
change based class as well but instead of
representing a single data item, it
| | 05:27 |
represents a collection of data items.
In this case, a collection as you can see
| | 05:32 |
here on line 12.
Of item view model objects and that's how
| | 05:35 |
when we look at our app we'll come back
here to the main page and take a quick
| | 05:39 |
look you can see our app has my you know
item one item two item three item four and
| | 05:43 |
the way that works is that the main view
model serves up a collection of items.
| | 05:50 |
And similarly this collection of items can
be observable that way when someone
| | 05:54 |
meaning in your code in your code behind
adds an item to the collection or deletes
| | 05:57 |
an item in the collection.
The zammel run time can automatically
| | 06:02 |
update the list so that the data that you
changed in the background either
| | 06:05 |
disappears from the user interface or
appears in the user interface.
| | 06:10 |
Now in this audio box code, they've
provided a sample property in this view
| | 06:14 |
model in order to have a single data item
view model on the main view model.
| | 06:19 |
Nothing really uses this in the code.
And they just show this in order to be
| | 06:23 |
able to show you how you would hear.
Localize this.
| | 06:26 |
What's important in terms of looking at
this code from our point of view is that
| | 06:29 |
there's this Boolean property, is data
loaded, which is used to determine, when
| | 06:32 |
the app starts up, whether the data has to
be loaded from some external backing store
| | 06:36 |
or whether the data's already loaded And
you can simply just use it.
| | 06:42 |
And there's another method here called
load data, which in this particular sample
| | 06:45 |
out of the box automatically creates, as
you can see, a bunch of items of type item
| | 06:49 |
view model.
Fills them with the various properties,
| | 06:53 |
and then adds them to the items collection
for this main view model.
| | 06:57 |
It's just the way you can have the data
bound app have some data when you
| | 07:00 |
initially fire it up.
The ting that's important to understand
| | 07:04 |
here is that a view model oftentimes has
multiple layers.
| | 07:07 |
A view model is implemented on top of i
notify property changed.
| | 07:11 |
And oftentimes, at least in terms of the
out of the box template, The view model
| | 07:14 |
will have some code that's just
automatically created for the developers
| | 07:17 |
so that they can see something on the
screen when they just run the app right
| | 07:21 |
out of the box.
So, just so that we can see what this
| | 07:25 |
looks like, let's go ahead and run this app.
| | 07:27 |
And we're running it on one of the Windows
phone emulators.
| | 07:30 |
In this case the WVGA emulator.
For those of you coming from iPhone and
| | 07:35 |
Android Similarly to iOS and similar to
Android, there are multiple configurations
| | 07:39 |
for the Windows Phone emulator, such as
there are for three and a half inch iOS
| | 07:42 |
device, four inch iOS device, and iPad,
and different sized screens for Android.
| | 07:49 |
Unlike the iOS emulator, the Windows Phone
emulator is actually a full-blown virtual
| | 07:54 |
machine.
So sometimes it takes a while to start up.
| | 07:58 |
So the emulator's now started up, now
we're deploying our simple app to the
| | 08:01 |
emulator and you can see here now we have
a list of things.
| | 08:05 |
We can scroll our list of items, and if we
pick one we can look at the data for a
| | 08:09 |
specific item.
And that's interacting with this view
| | 08:13 |
model that's created.
Now that we've taken a look at how a eye
| | 08:16 |
notify property changed view model was
used in Windows phone.
| | 08:20 |
Let's go take a look at the same exact
thing in Windows store and then we'll take
| | 08:23 |
a look at the common data model that we're
building for the plain old notes apps for
| | 08:26 |
this course.
Now let's do the second part.
| | 08:30 |
Let's build an out of the box Windows
store app using the template provided by
| | 08:34 |
Microsoft Inside Visual Studio.
So we'll start out the project We're still
| | 08:39 |
in templates, visual C#.
We're going to go to Windows Store now,
| | 08:42 |
and we're going to create a split app.
A split app, as it says over here in the
| | 08:47 |
description, is a two page project that
has a set of grids at the beginning, this
| | 08:51 |
area down here, and then an individual
list of items with details.
| | 08:56 |
And we're going to use that because we're
going to look at this.
| | 08:59 |
Out of the box data model when we actually
build (UNKNOWN) nodes we're actually going
| | 09:02 |
to delete the grid at the front because
we're not doing groups of notes, we're
| | 09:05 |
just doing a single list of notes and then
we're going to add an additional page to
| | 09:07 |
allow you to edit your notes on the end of this.
| | 09:12 |
But we're going to start with this split
app template and we'll call this
| | 09:16 |
OOBWindows Store.
The reason we're looking at this again,
| | 09:21 |
remember, is we're going to go and look at
the data model and how the data model is
| | 09:24 |
used by the application.
So, I'm going to close this and look
| | 09:29 |
inside the data model folder, you know
it's not called view models anymore, it's
| | 09:32 |
called data model in Window's store, but
it essentially has the same thing in it.
| | 09:37 |
So let's go take a quick look at this.
And the first thing you notice is that
| | 09:41 |
it's not based on i notify property changed.
| | 09:44 |
Except that it really is.
Let's go take a look at what this bindable
| | 09:47 |
base class actually is.
This is just a class provided by Microsoft
| | 09:51 |
to make it easier to create I notify
property changed based.
| | 09:55 |
Objects without having to write a bunch of
code over and over again.
| | 09:58 |
If we take a look at bindable base, you'll
see it only has three things.
| | 10:01 |
It has an on property changed method, a
property changed event, and a set property
| | 10:05 |
using generics that allows you to set the
property and automatically file the
| | 10:08 |
property changed.
So we take a look and we see on line 17
| | 10:12 |
here, there's our event handlers, just as
we saw on Windows phone.
| | 10:18 |
Here's the set property method.
The set property method looks very much
| | 10:21 |
like what we saw on Windows phone, except
that this is automatically then says did
| | 10:25 |
we have to change anything because the
values are the same or different.
| | 10:29 |
And then automatically calls on property
change in order to be able to change the
| | 10:32 |
name of the property And then finally our
own property change looks very similar to
| | 10:36 |
the one we saw in Windows Phone.
It simply says, go get the event handler.
| | 10:41 |
If the event handler does not equal null,
then raise a property changed event,
| | 10:44 |
passing in the name of the property as the argument.
| | 10:47 |
So now having seen that behind the scenes,
you can see that when you build a common
| | 10:50 |
data model, because we're going to build
one that looks more like the one in
| | 10:53 |
Windows Phone.
Because it implements the same i property
| | 10:57 |
changed, again remember up here, I notify
property changed interface because it
| | 11:01 |
implements that.
It's equivalent to the way the data model
| | 11:04 |
is implemented in the template for a
Windows store app.
| | 11:07 |
So let's go back and take a look at that
sample data source, which is based on this
| | 11:11 |
common bindable base class that we just
looked at.
| | 11:15 |
So the way they've got it set up, very
similar and straightforward.
| | 11:18 |
But it's slightly different because of the
way the data is created in this template.
| | 11:23 |
There's a few classes in here.
There's Sample Data Common, Sample Data
| | 11:27 |
Item, Sample Data Group and Sample Data Source.
| | 11:30 |
Now, similar to Windows Phone, the Sample
Data Item is the individual item that the
| | 11:35 |
app uses.
In the Windows store template, and we'll
| | 11:38 |
take a look at that in just a second
before we carry on with all the more
| | 11:41 |
detail of this, it's actually set up as a
two level data store.
| | 11:45 |
There's groups, and inside each group
there's items, and then of course inside
| | 11:49 |
each item there's data.
So in our Plain Ol' Notes we're only
| | 11:52 |
going to have one level, so when we
actually start building our data model.
| | 11:55 |
We're only going to have one level, so
we'll have items in a data source.
| | 11:58 |
And sample data common, is simply
something they created in order to be able
| | 12:02 |
to use it, to be able to share between
data group and data item for the purpose
| | 12:05 |
of this template.
So that each individual group and data
| | 12:10 |
item can share the fact that they each
have, as you can see here, a title, a sub
| | 12:13 |
title, a description, and a path.
And if we go look at sample data item,
| | 12:18 |
you'll see that that's based on sample
data common, it has one additional
| | 12:21 |
property beyond the items in the common,
which is the content for the actual
| | 12:24 |
content of the item, this method right
here, this property.
| | 12:29 |
And it also has a group property that
indicates which groups this data item
| | 12:33 |
belongs to.
Now in Plain Old Notes, we don't have
| | 12:36 |
groups.
So we don't have that.
| | 12:38 |
But you get the idea.
There's basically this simple data item
| | 12:41 |
which has a title, and some contents in
the Windows Store implementation.
| | 12:46 |
And then down here when we look at sample
data source, this looks very much like the
| | 12:50 |
main view model that we saw.
In Windows Phone.
| | 12:54 |
It has an observable collection of sample
data groups, and it has a method to allow
| | 12:58 |
you to get the particular individual
group, or to get all the groups.
| | 13:03 |
It also has methods because this is a
two-level data store, to allow you to get
| | 13:06 |
a specific item based on that item ID.
And finally, as we saw before, there's
| | 13:12 |
code here which initializes the groups and
items putting some initial data in there.
| | 13:17 |
Let's take a look at this app in action.
When you're running a Windows Store app,
| | 13:21 |
you have two choices.
Because, unlike Windows Phone, you don't
| | 13:24 |
have to have a separate virtual machine
because the machine you're running on,
| | 13:28 |
developing using Visual Studio 2012 Has to
be a Windows 8 machine.
| | 13:33 |
Therefore you're guaranteed to able to run
the machine on the same OS that you're
| | 13:36 |
developing on.
Very similar to the way you've always done
| | 13:39 |
it in Windows 7 and before.
But there's two ways to do that.
| | 13:43 |
You can either run it on the same machine
as if it were the same machine, in other
| | 13:46 |
words if your development machine.
Has the facilities that you need.
| | 13:50 |
For example, you want to test, touch, and
swipe, and different orientation changes,
| | 13:54 |
that's great.
If you're machine doesn't actually have
| | 13:57 |
those capabilities you can run it on
what's called the simulator.
| | 14:00 |
So, we're going to run it first on the
local machine, then on the simulator, and
| | 14:03 |
you'll see that even though local machine
and simulator are different.
| | 14:07 |
The differences are not that they're
pointing to different machines, they're
| | 14:10 |
actually portals to the same machine.
They're just different ways, of allowing
| | 14:14 |
you to experience the user interaction.
So, first of all, we'll run it on the
| | 14:17 |
local machine and you see here's our groups.
| | 14:19 |
We click into a group and we can see the
list of items, as we change items, you see
| | 14:23 |
that the item detail, shows up over here.
Now let's go ahead and go back to the
| | 14:28 |
desktop, stop that, notice that quitting
the app and going back to the desktop,
| | 14:31 |
does not automatically stop the debugging.
So often times in Windows Store you'll
| | 14:36 |
have to hit the stop button if you don't
want to wait for it to time out.
| | 14:39 |
Now, let's look at the same thing on the simulator.
| | 14:42 |
The simulator is essentially a
miniaturized version of the user
| | 14:45 |
interface.
You'll notice it's exactly the same
| | 14:48 |
machine that you had when you were running
on your actual desktop.
| | 14:52 |
But it looks more like a surface.
It has a home button to stop the image.
| | 14:57 |
You come back to the desktop.
See, it's the same desktop as we have on
| | 15:00 |
our development system.
If we come back to the Windows screen, and
| | 15:04 |
we scroll over here to the right, you can
see we have our out-of-box Windows store
| | 15:07 |
icon, and we can bring the app back up again.
| | 15:12 |
Also, you'll notice, over here in the
simulator, you have the mouse mode, which
| | 15:15 |
is what we've been using here, or you can
also have the Touch mode, that allows you
| | 15:19 |
to do things for example swipe in from the
right to bring up the charms as well as
| | 15:22 |
tap.
You can see that the way the visual
| | 15:27 |
highlightings done just as it does on a
Windows Store device with a touch screen.
| | 15:32 |
You can also take screen shots, you can
Change the orientation to make sure that
| | 15:36 |
your app supports multiple orientations.
Rotate left and right.
| | 15:40 |
You can also do pinch and zoom, and do
rotation in touch mode.
| | 15:46 |
All right, that's a quick look at the out
of the box template for Windows Phone, and
| | 15:49 |
the out of the box template for Windows Store.
| | 15:52 |
Next up, we're going to go look at the
actual data model we're going to build
| | 15:55 |
beginning with the properties that are in
our data model.
| | 15:59 |
| | Collapse this transcript |
| Exploring the public properties| 00:00 |
We're going to have a single data model, a
single set of View Model files, for both
| | 00:04 |
our Windows phone and Windows store app.
Since that is going to exist in both apps,
| | 00:09 |
we can look at one of the apps.
In this case, we're going to look at the
| | 00:12 |
Windows phone app, and take a look at how
the data model is built.
| | 00:15 |
When we get on to building the Windows
Store app we're simply going to copy these
| | 00:18 |
files over change some namespaces and use
them again.
| | 00:21 |
Let's take a look at the View model which
we know is going to be in the View Models
| | 00:25 |
folder here inside the Windows Phone solution.
| | 00:28 |
As we saw before there's a single model
which contains an individual data item, in
| | 00:31 |
our case, a note and then another model
which contains the collection of notes.
| | 00:36 |
So let's take a look at the Note model.
Right now we're just going to take a look
| | 00:40 |
at the Properties.
We'll take a look at the methods in the
| | 00:42 |
next movie.
When you look at the properties on a .net
| | 00:45 |
class, you'll notice that the properties
are denoted by this little wrench icon
| | 00:49 |
over here.
And so we can take a look at the
| | 00:52 |
properties in our model here easily by
looking at the items which have the little
| | 00:55 |
wrench icon.
And for our individual note, there's going
| | 00:59 |
to be three properties.
There's an ID property which will uniquely
| | 01:03 |
identify each note.
There's a Note property, which has the
| | 01:06 |
full text of the note including all of the
carriage return line feeds and multiple
| | 01:09 |
lines as long as you want your note to be.
And then a separate property called the
| | 01:14 |
first line property.
And the reason this is done this way is so
| | 01:18 |
that we combine the first line to the data
display in our list on a main page of our
| | 01:21 |
application and then we can separately bind.
| | 01:26 |
The note property to the editor in our
Windows Phone App, or into the separate
| | 01:29 |
side display in our Windows Store App, and
where we want to display the entire
| | 01:33 |
contents of the note.
So let's take a quick look at the
| | 01:37 |
implementation of those three properties.
As we saw before when we were looking at
| | 01:41 |
the out of the box templates, we have a
single backing variable, has an underscore
| | 01:44 |
in front of it, and then we have a
property that has a getter.
| | 01:48 |
And a setter, wherein the getter simply
returns the value of the backing variable.
| | 01:52 |
And the setter checks to see whether or
not the value being set is different.
| | 01:56 |
If it is, it sets the value and calls
NotifyPropertyChanged in order to be able
| | 02:00 |
to cause the UI to update if anyone is
listening for that particular property to
| | 02:04 |
be changed.
In our particular data model here, as I
| | 02:08 |
said, we have two additional properties.
We have Note and we have First Line.
| | 02:13 |
And the way that works is that the note
property has the same structure, backing
| | 02:17 |
variable, getter.
But it has the setter with a little bit
| | 02:20 |
more logic in it which says that if the
value of the backing variable's different
| | 02:23 |
than the value we're setting into the
note, we copy the whole note.
| | 02:27 |
And then we split the note in the
individual lines.
| | 02:30 |
And if our first line has something in it,
then we set our FirstLine property equal
| | 02:33 |
to the first line of our note, so that we
can combine that to our data model.
| | 02:38 |
And then we set the NotifyPropertyChanged
for the note.
| | 02:42 |
All right.
And our last property In our single item
| | 02:44 |
data model is the first line property.
And as you've seen before, we have a
| | 02:48 |
private backing variable, a public string
property declaration, a public getter.
| | 02:53 |
But in this case, we have a private setter.
| | 02:54 |
Now, why did we do that?
That's because the first line property is
| | 02:57 |
always a derived property of the data
inside the note property.
| | 03:01 |
So you don't want anyone outside this
class setting the first line independent
| | 03:04 |
of the copy of the data in the note.
So we set this to private so that the only
| | 03:09 |
time this property can be called is from
the note public setter that we saw up
| | 03:12 |
above.
Otherwise it has exactly the same
| | 03:15 |
structure.
Checks to see if the value's changed if it
| | 03:18 |
has set the backing variable and then call
notify property changed in order to get
| | 03:22 |
the user interface to update.
All right now, let's go take a look at the
| | 03:26 |
notes model which aggregates our
individual notes in a way that we can use
| | 03:28 |
them in our Windows Phone and Windows Store.
| | 03:32 |
List user interface elements.
So let's open up the Notes Model Class.
| | 03:36 |
And you'll see, as we saw in both the
out-of-the-box templates, the aggregated
| | 03:39 |
class, the view model also implements I
notify property changed.
| | 03:44 |
In our class here, we have a, some methods.
| | 03:47 |
We're looking only at properties in this
particular movie.
| | 03:49 |
So we're going to look at our items property.
| | 03:51 |
Here's an observable collection of items
of type Note model, and you'll notice,
| | 03:55 |
just like we saw in the Note model itself.
We have a public getter and a private
| | 03:59 |
setter, because you can only set the items
Through this notes model class.
| | 04:03 |
You can't add an item to the note model
here directly, without calling one of the
| | 04:06 |
methods of this class.
There's a IsDataLoaded property, which is
| | 04:10 |
used to determine whether or not the data
model's already been loaded from a backing
| | 04:14 |
store.
And when we get into implementing the
| | 04:17 |
actual loading and saving of data.
We'll be, be using this in order to not go
| | 04:21 |
out to the disk, and load the data twice.
because it could be voluminous and once we
| | 04:25 |
already have it in memory.
We don't have to do that, and that's the
| | 04:27 |
properties on this class.
There's some additional methods which
| | 04:30 |
we'll take a look at in the next movie,
but again the properties here are Items
| | 04:33 |
and IsDataLoaded.
And so, that's the properties that we have
| | 04:37 |
in our aggregator class.
You'll bind in things like the Long List
| | 04:41 |
selector in Windows phone and your Grid
and Stack Panel items and List Items in
| | 04:44 |
Windows Store to the items property here.
And use the IsDataLoaded method to
| | 04:50 |
determine whether or not when you start
accessing the view model, whether you have
| | 04:54 |
to go and load the data from the backing store.
| | 04:57 |
All right.
Now, let's go take a look at the methods
| | 04:59 |
that implement our other pieces of the
data model.
| | 05:02 |
| | Collapse this transcript |
| Exploring the class methods| 00:00 |
We've looked at the properties on our data model.
| | 00:02 |
Now, let's go take a look at the methods
that actually make the data model come
| | 00:05 |
alive.
So, once again back to Visual Studio and
| | 00:07 |
first of all we'll look at the note model
our individual item note model and you'll
| | 00:11 |
notice that we only have one method here.
Methods are represented by this little
| | 00:16 |
cubed shape here and in our case it's
simply notify property changed.
| | 00:21 |
And here we are at the standard notify
property changed, as we saw right out of
| | 00:24 |
the box in the template for Windows Phone.
And since this notify property changed is
| | 00:29 |
also functionally equivalent for Windows
Store, we can use the data model on either
| | 00:32 |
Windows Phone or Windows Store.
As we saw before, it has an event handler
| | 00:36 |
public member.
Notice it's not a property, there's no
| | 00:39 |
getter and setter.
It's just a public member variable that
| | 00:41 |
people can use to attach to the property
changed event here.
| | 00:45 |
To listen for property changes, and that's
done by the zamo infrastructure.
| | 00:50 |
And it's based on the fact that this code
implements this I notified property
| | 00:53 |
changed interface.
And the fact that this variable is called
| | 00:56 |
property changed.
And then the notify property changed
| | 00:59 |
method, which we call every time we change.
| | 01:01 |
One of our properties which goes and gets
the handler if its not null it then
| | 01:05 |
invokes the handler by effectively then
erasing the event passing it a property
| | 01:09 |
changed event args with the name of our
property thus completing the
| | 01:12 |
implementation of the I notify property
changed infrastructure.
| | 01:18 |
As we said at the individual data item
level there's only one method notify
| | 01:22 |
property changed.
Now this changes dramatically when we get
| | 01:25 |
up to the next higher level item.
Which is the notes model the implements
| | 01:28 |
the aggregation of our individual notes
and manages the list.
| | 01:33 |
So let's take a look at that.
Here you can see we have five methods,
| | 01:35 |
we'll go through them each individually,
create new note, load data, in notes model
| | 01:39 |
constructor the notify property change,
which is going to be the same as we saw in
| | 01:42 |
the individual note model and the update
notes methods, what happens when we've
| | 01:45 |
actually made a change to one of the notes.
| | 01:50 |
So let's take a look.
The NotifyPropertyChanged method is
| | 01:53 |
exactly the same as we just saw inside NoteModel.
| | 01:57 |
Next up, let's take a look at the constructor.
| | 01:59 |
Before we look at the code for the
constructor, notice that we have an
| | 02:02 |
integer member variable here called
nextNoteNumber, which will, once we have
| | 02:05 |
it hooked up to DataPersistence, contain
the ID number of the next note to be
| | 02:09 |
created in the sequence, so that we can
automatically add new items to our list of
| | 02:12 |
notes.
If we look at the constructor now here,
| | 02:17 |
this set of code right there, you'll
notice that the constructor creates the
| | 02:20 |
empty data structure for the items, this
new observable collection, and also
| | 02:23 |
initializes this next note number to four.
That's because as you'll see in a moment
| | 02:29 |
in our load data method, until we
implement persistence we're preloading out
| | 02:32 |
data with three items so therefore those
are items one, two, three and four.
| | 02:38 |
And the next note number when we add a new
note's going to be number four.
| | 02:41 |
The next method we're going to look at is
the load data method.
| | 02:44 |
This is the method called by the data
infrastructure in order to load data from
| | 02:47 |
a backing store if you have such backing
storing implemented, or to pre-initialize
| | 02:50 |
the view method so that you can have
something to work with.
| | 02:54 |
In our case, until we get to the point
where we're implementing the backing
| | 02:57 |
store, our load data method is simply
going to pre-initialize.
| | 03:01 |
Our notes model with three individual notes.
| | 03:03 |
You see we've got notes 1, 2, and 3.
It simply initializes a note model object
| | 03:07 |
and calls the ID property setter and the
note property setter.
| | 03:12 |
You can see in the first item there on
line 53, our note has multiple lines.
| | 03:19 |
There's carriage return line feed in
between each lines.
| | 03:21 |
And for line 54 and line 55, there are
only single line notes.
| | 03:25 |
So we only have the data and no carriage
return line feeds.
| | 03:29 |
You'll note that there's no call here to
the first line property.
| | 03:32 |
Remember the first line property is a
derived property.
| | 03:36 |
It has a private setter.
And it's only set by the fact that you
| | 03:38 |
actually initialize this data.
So let's go ahead and take a look at what
| | 03:42 |
else we do here.
We initialize the IsDataLoaded property to
| | 03:45 |
true.
That causes us, as we go through various
| | 03:47 |
different paths of the app life cycle on
Windows phone And Windows store not to
| | 03:50 |
reload the data when we come back to spend
if we can come back and say oh we already
| | 03:54 |
have the data model loaded we don't have
to load it again.
| | 03:59 |
So by saying the is data loaded property
is true later on during the portions of
| | 04:02 |
the app that initialize the data model we
can say oh the data's already loaded.
| | 04:08 |
Now let's look at the createnewnote method.
| | 04:10 |
You'll notice that the createnewnote
method returns a note model.
| | 04:13 |
And you'll notice that it's on this class,
not on the individual note model class.
| | 04:17 |
And the reason for that is two-fold.
Number one, when we create a new note, we
| | 04:21 |
want to make sure that we can initialize
its ID property.
| | 04:24 |
And this note's model class has the notion
of what the next ID is supposed to be.
| | 04:29 |
And so we initialize it here.
And, we also want to make sure that we add
| | 04:33 |
it to the observable collection, because
we're creating a new note, and it's
| | 04:36 |
already a note that's going to be in our list.
| | 04:40 |
Now, in our logic, when you press the
create new note button, it's going to
| | 04:43 |
automatically take you to the editor, so
you'll never see the empty note in the
| | 04:47 |
list.
But it will be in the list so that it can
| | 04:51 |
be found and updated and will
automatically have a presence in the list
| | 04:54 |
so that the note model item, the
individual one, can be passed to the
| | 04:58 |
editor page as a fully formed object.
Therefore the note model editor page won't
| | 05:04 |
have to know whether the note is a new
note or a preexisting note, because by the
| | 05:08 |
time it gets to the editor it will
automatically look the same.
| | 05:13 |
And then finally, of course, we return the
new note that we just created.
| | 05:15 |
And finally we have our update notes method.
| | 05:17 |
This is what we're going to call when we
leave the editor page and go back to the
| | 05:20 |
list page.
When we implement persistence, this is
| | 05:23 |
where the data's going to be saved to our
backing store.
| | 05:26 |
But in order to make this view model
complete in terms of structure, those are
| | 05:28 |
the structured pieces that you want.
You want the ability to create a new
| | 05:32 |
model.
The case of our notes model constructor.
| | 05:36 |
We want the ability to load data into it.
We want the ability to create a new
| | 05:39 |
instance and add something to that collection.
| | 05:41 |
And then finally we want a method to be
able to save out changes to the collection
| | 05:45 |
when the data's updated.
All right, it's going to be time for you
| | 05:48 |
to roll up your sleeves and build these
two classes on your own.
| | 05:51 |
So let's move on to the first challenge.
| | 05:53 |
| | Collapse this transcript |
| Challenge: Building the data model from scratch| 00:00 |
Alright we've come to our first challenge,
building the data model from scratch.
| | 00:04 |
The way we're going to do that is we're
going to start with the Windows phone data
| | 00:08 |
bound template then we're going to replace
the main view model on item view model
| | 00:12 |
classes with empty versions of our note
model and note model classes.
| | 00:18 |
Then you'll populate the note model class
with the three properties, ID, note, and
| | 00:22 |
first line and its notify property changed
method and then you'll go on to the notes
| | 00:26 |
model class and implement the notify
property changed method.
| | 00:31 |
Implement the items observable collection
and then implement the load data update
| | 00:36 |
notes, constructor and create note methods
to complete the view model.
| | 00:43 |
Following that, we'll make a very small
change to the App.xaml.cs, and the main
| | 00:47 |
page xaml so that we can test drive our
new data model in the context of this
| | 00:50 |
Windows phone data-bound template, out of
the box.
| | 00:56 |
Alright, that's the challenge, good luck
building your notes model class and
| | 01:00 |
hooking it up to the app dot zamel dot cs
or you can try it out.
| | 01:05 |
If you want some help, you can watch the solution.
| | 01:07 |
I'm going to go through that step by step
exactly as I made out in the challenge.
| | 01:11 |
| | Collapse this transcript |
| Solution: Building the data model from scratch| 00:00 |
Alright, here's the solution for our first challenge.
| | 00:03 |
Building the data model.
Since this is the first challenge in this
| | 00:06 |
course, I'm actually going to go ahead and
build the project, which is going to
| | 00:09 |
become the final Windows phone
application, in the end.
| | 00:12 |
So I'm going to say new project.
In my case, I'm going to browse to the
| | 00:17 |
Example files fo, Exercise Files folder.
And in here chapter five, create the new
| | 00:24 |
project.
I'm going to call it bon for wp final
| | 00:27 |
notes for Windows phone and I'm going to
come up and select templates, visual c
| | 00:33 |
sharp, Windows phone.
Windows phone data bound app.
| | 00:39 |
So that's the template I want to use to
begin starting this particular app.
| | 00:43 |
I'm going to go over here and I'll click OK.
| | 00:46 |
Select that I want Window Phone H and now
we got the standard set up as we talked
| | 00:51 |
about earlier when we look at how the view
models are set up in Windows phone.
| | 00:58 |
So, step one is creating this particular solution.
| | 01:02 |
Step two, I'm going to come down here, and
I'm going to delete the item view model,
| | 01:05 |
and the main view model from my solution.
I'm simply going to say exclude from
| | 01:10 |
project.
And now I'm going to add two new classes.
| | 01:13 |
Add new item class.
First class is going to be called note
| | 01:18 |
model singular.
And the second class is going to be called
| | 01:25 |
NotesModel.
Alright, there's our two base classes,
| | 01:29 |
that's step two of our challenge.
Alright, now I'm just going to go and
| | 01:33 |
start filling in Note Model.
Alright, remember we said Note model is
| | 01:36 |
going to implemnet, iNotify property changed.
| | 01:38 |
And you'll notice that iNotify property
changed isn't recoginized because it's in
| | 01:43 |
a different name space.
So if we type in the middle there and use
| | 01:47 |
control period, it will tell us which
particular name space we need to bring in.
| | 01:53 |
With this case, system.componentmodel.
Alright there,now we've got the inotify
| | 01:57 |
property changed interface.
We can right click here and select
| | 02:01 |
Implement Interface, and that
automatically tells us what we have to
| | 02:05 |
implement in order to be able to be
completely implementing inotify property
| | 02:09 |
changed.
And in this particular case it's simply
| | 02:13 |
the event handler so that's how we get the
event handler in there.
| | 02:16 |
Now let's implement our notify property
changed method private void notify
| | 02:20 |
property changed and type in the string
with our property name.
| | 02:27 |
And then we're going to do we'll have our
handler property changed event handler and
| | 02:31 |
we'll see if the handler has anybody listening.
| | 02:35 |
Then we'll fire off the property. (SOUND).
| | 02:43 |
Now pass in our property name.
That's the implementation of that method.
| | 02:47 |
Now we need to do our three properties.
So remember, we have backing store for
| | 02:51 |
each one.
First one is private string_id.
| | 02:55 |
And we have private.
String _note and private sting _firstline.
| | 03:05 |
Now we'll implement the getters and
setters that go along with each one of
| | 03:07 |
those.
So public string I.D.
| | 03:12 |
get return backing store set.
Say if the value is being passed in here
| | 03:18 |
is not equal to the backing store, then we
set the backing store and we call notify
| | 03:23 |
property changed and pass in our string
that represents this property, in this
| | 03:28 |
case id.
And we want to have this string always
| | 03:34 |
match this variable up here.
Because the name of the property is how
| | 03:39 |
things are bound in XAML to the user interface.
| | 03:42 |
And in order to make sure that the user
interface gets updated when the properties
| | 03:45 |
get updated the string you pass into
notify property changed has to be the same
| | 03:48 |
as the name of the property that you're in.
| | 03:51 |
Alright and one more brace to close that
out and we'll format that.
| | 03:57 |
One more brace alright there's our
property again.
| | 03:59 |
Public property name, public getter,
public setter, check the value, if it's
| | 04:03 |
not the same set the value and call notify
property changed.
| | 04:08 |
Now we need to implement the remainder of
our public properties so they're going to
| | 04:11 |
look just like this.
I'm going to copy and paste that and brave
| | 04:15 |
the copy and paste demons that are going
to make sure that I don't accidentally
| | 04:18 |
forget to do something here.
So I'm going to set Change it to Note,
| | 04:23 |
change the backing thing to underbar note,
and change the NotifyPropertyChanged to
| | 04:29 |
Note.
Now, it's very important, remember that we
| | 04:33 |
needed to do something else inside this.
In addition to simply setting the value,
| | 04:37 |
we wanted to call our first line property.
So take the value, look, we forgot to
| | 04:42 |
change these.
Even though that ID property is private,
| | 04:45 |
it's still public to the whole class we've
got here.
| | 04:48 |
So we got to make sure we do that.
So there.
| | 04:51 |
Now that looks functional.
Now let's go add the additional code.
| | 04:54 |
Let's get the lines.
And do a string array and break it it all
| | 04:59 |
the return characters.
And then we'll say if line's dot length,
| | 05:05 |
is greater than 0.
Meaning there's any lines in there.
| | 05:09 |
Then we're going to set the first line
property equal to lines subzero dot
| | 05:14 |
replace.
Because we're going to replace all of the
| | 05:17 |
line feed characters, which it should only
be one, with an empty string.
| | 05:22 |
Because we don't want our first line
property to have a line feed at the end of
| | 05:25 |
it.
And then finally, we've got our notified
| | 05:27 |
property changed and we're passing in note.
| | 05:30 |
Now you noticed our first line property
setter says it doesn't exist because we
| | 05:32 |
not have to go and implement that.
So once again let's go copy our property
| | 05:37 |
code here, and we'll come back down here
underneath first line and implement it.
| | 05:44 |
Change the property name to first line and
copy this variable name and replace it
| | 05:49 |
every place we see id.
And then change this to say FirstLine.
| | 05:56 |
Alright, that's the implementation of the
note model.
| | 05:59 |
Let's do a build and see what happens.
What you're going to see is that the main
| | 06:04 |
view model, which we excluded from our
project, can no longer be found.
| | 06:08 |
We're going to go ahead and implement the
notes model.
| | 06:10 |
And then we'll go back and substitute the
places where it's looking for main view
| | 06:13 |
model.
To make it look for our notes model to
| | 06:16 |
make sure that the UI's wired up to our
data model to try it out.
| | 06:19 |
So we're done with the note model let's
open up the notes model class and
| | 06:23 |
implement that.
So as before its I notify property changed
| | 06:28 |
and as before we need system.componentmodel.
| | 06:33 |
Now, we need that same notify property
changed method.
| | 06:38 |
So I'm simply going to come back to the
notes model and copy out the event handler
| | 06:41 |
variable and the method and come to the
notes model and paste that in.
| | 06:47 |
So there, now I've got that.
And then, you might recall that I wanted
| | 06:49 |
to have a variable to tell me what the
next ID number of the next note that I'm
| | 06:52 |
going to.
The hand out is.
| | 06:55 |
In this case, I'm going to just simply say
int nextNoteNumber.
| | 06:59 |
And I'll initialize that in my load data method.
| | 07:01 |
All right, now we've got that set of infrastructure.
| | 07:04 |
Now we need to create the items collection.
| | 07:06 |
So this is public, because the items
collection needs to be bindable by your
| | 07:11 |
XAML, ObservableCollection of type NoteModel.
| | 07:18 |
And it's called items because we're
going to use that name in our Zambo so it
| | 07:21 |
has to match the name.
And it has public getter and a private
| | 07:26 |
setter.
In order to get observable collection,
| | 07:30 |
once again we'll select Ctrl + Period and
get systems.collections.objectmodel.
| | 07:36 |
Alright, now that all resolves.
Now, let's build a constructor for this
| | 07:39 |
class, public notes model.
And in that, we'll say, this.items equals
| | 07:43 |
new observablecollection note model.
And that's all we need to do with the
| | 07:48 |
constructor.
But we needed to make sure that the item's
| | 07:50 |
property is built in the constructor.
Because the XAML code might very well call
| | 07:54 |
a reference to the item's property, even
before we get a chance to fill it in.
| | 07:59 |
So it has to be there, and not null when
that call happens.
| | 08:02 |
Next up, we want our IsDataLoaded property.
| | 08:06 |
Again public get, private set, then we
want to have our methods.
| | 08:11 |
We want to be able to create a note,
public note model, create new note, and
| | 08:18 |
there we say note model result.
Equal to new note model.
| | 08:26 |
And we're going to initialize it with ID
equal to next note number to string and
| | 08:32 |
note equal to empty string.
And then we'll say next note number, plus,
| | 08:40 |
plus.
Because we've used one.
| | 08:42 |
Go onto the next one.
Add this new item we just did.
| | 08:46 |
This .items.add to our items collection
and then we'll return it.
| | 08:51 |
Alright that's our create new note method
remember we wanted to have a public void
| | 08:57 |
update model method.
And finally we wanted to have a load data
| | 09:02 |
method.
Actually, as I recall that's supposed to
| | 09:05 |
be called update notes not update model.
Alright, that means we've changed
| | 09:10 |
something in one of those items we wanted persistent.
| | 09:13 |
Remember, we're going to be coming back to
persistance later.
| | 09:15 |
Finally, the last thing we need is load data.
| | 09:17 |
So we say public void LoadData.
And we're going to create three new items
| | 09:25 |
and add them to the items collections, so
this.items.add, new note model, ID = '"1"
| | 09:32 |
for the first one.
Note, it's going to be the beginning of a
| | 09:39 |
lyric of a song I wrote, so this is life
new line, I often say new line.
| | 09:46 |
It's something other then what was
advertised in the brochure.
| | 09:55 |
And then we have brace and a closed paren,
and semicolon, and another closed brace.
| | 10:01 |
Well actually we don't need that final
closed brace.
| | 10:03 |
Alright and now we're simply going to copy
this and duplicate it three times, copy
| | 10:08 |
one, two, three.
So we can have note number two and note
| | 10:13 |
number three.
Note number two, wants to say plan camping
| | 10:19 |
trip for April.
And note number three , something from the
| | 10:24 |
Bard.
But soft, what light through yonder window
| | 10:30 |
breaks.
Alright, and now our data's loaded, so we
| | 10:35 |
say this.IsDataLoaded = true.
because our data's now loaded.
| | 10:41 |
Alright, that's the implementation of our
data model.
| | 10:44 |
Once again, let's build it and make sure
that we haven't gotten any typos in there,
| | 10:48 |
alright?
We're still sitting here, we still have
| | 10:50 |
our two errors because we got rid of Main
View Model, and now we need to hook this
| | 10:53 |
up to our user experience, our XAML and
our code in order to try this out and make
| | 10:56 |
sure that our data model seems to work.
Alright, let's try out our data model by
| | 11:02 |
fixing these two errors.
So we'll come into App.xaml.cs.
| | 11:07 |
We'll just double click on the error, and
where it says MainViewModel we're going to
| | 11:11 |
make that be NotesModel, one place there
and one place here.
| | 11:14 |
Now that's pretty straightforward.
There's another place here we need to fix.
| | 11:18 |
And that makes everything we needed to
change in the code.
| | 11:20 |
But there's one other thing we need to
change the XAML because we no longer have
| | 11:23 |
Line one, line two, and line three properties.
| | 11:26 |
Let's go to the zamo for the main page.
And look at this particular list box.
| | 11:31 |
And let's flip these around.
Make this big enough so we can see
| | 11:35 |
everything here.
And put all of our attributes on a
| | 11:38 |
separate line so we can see what we're doing.
| | 11:41 |
And you can see we have binding the items
That's how we get connected to our data
| | 11:45 |
model.
For right now there's two items in this
| | 11:47 |
long list selector item template for line
one and line two of the data model that
| | 11:51 |
was originally in this template.
We're going to come in here, delete this
| | 11:57 |
text block and change this binding from
line one to say note so that we retrieve
| | 12:01 |
note property from our data.
So let's go ahead and give this a whirl.
| | 12:06 |
First of all, let's build it and make sure
it builds.
| | 12:08 |
All right.
And that means we forgot to put the word
| | 12:11 |
public some place.
Notes model.
| | 12:16 |
needs to say public class.
And make sure, pardon me, note model needs
| | 12:20 |
to be public class.
And let's make sure that notes model, it's
| | 12:23 |
already a public class.
All right.
| | 12:25 |
Let's do a build again.
And what have we got, the same kind of
| | 12:28 |
thing probably?
Items, there says Note model is less
| | 12:33 |
accessable than Note model items.
Well, let's go take a look, right.
| | 12:38 |
Public.
because I didn't actually get public on
| | 12:41 |
the right one.
I got public on the Notes model to start
| | 12:43 |
with, and now the Note model also has to
be public.
| | 12:46 |
So let's build again, and now item view model.
| | 12:49 |
Alright, because our item view model is no
longer called item view model, it's now
| | 12:53 |
called, note mode.
And that has to do with when we navigate
| | 12:57 |
from the first page to the detail page.
And our build succeeded.
| | 13:02 |
Let's go ahead and give it a shot and see
what we see.
| | 13:04 |
Up comes our emulator, And there's our data.
| | 13:09 |
And notice, because we're using the note
property, we see the entire note in our
| | 13:13 |
list selector.
What we really want to do here is have
| | 13:16 |
just the first line.
So, let's come back here to our main page
| | 13:20 |
(UNKNOWN) and instead of saying Binding to
Note, let's bind to First Line.
| | 13:28 |
Try it again and there now you can see
that it has only the first line of each
| | 13:32 |
one of our notes.
Okay and that's the solution to this
| | 13:37 |
challenge.
Let's take a quick look and review just
| | 13:40 |
what we did.
We created the note model class which
| | 13:43 |
included our first line I.D.
and note backing variables.
| | 13:46 |
Our first line I.D.
and note properties.
| | 13:49 |
And an implementation of NotifyPropertyChanged.
| | 13:52 |
Then we created our NotesModel class,
which contained our Items and IsDataLoaded
| | 13:57 |
properties and the methods CreateNewNote,
LoadData, NotesModel,
| | 14:00 |
NotifyPropertyChanged, and UpdateNotes.
And then finally, we came to the
| | 14:06 |
app.xaml.cs, and changed the class of the
view model that was implemented by the
| | 14:10 |
original template, from main view model to
notes model.
| | 14:15 |
And then, finally, we came into the main
page, xaml.cs.
| | 14:17 |
And changed the type of the selected item
in our list selector to be note model.
| | 14:25 |
Instead of ItemViewModel.
And then, last but not least, we came into
| | 14:28 |
our MainPage.xaml, and left only one text
block inside of our ItemTemplate for the
| | 14:32 |
list selector, and pulled out first the
Notes and then the FirstLine property.
| | 14:38 |
To show our list of notes in our
application adjust the first line of each
| | 14:42 |
and that's the end of building the data model.
| | 14:46 |
Next up we're going to talk about how to
build the user experience for the final
| | 14:49 |
app for Windows phone and then we'll talk
about the same thing for Windows store.
| | 14:53 |
| | Collapse this transcript |
|
|
6. Creating Screen Markup for Windows PhoneBuilding the XAML for Windows Phone| 00:00 |
In this chapter we're going to talk about
building the XAML, create the user
| | 00:03 |
experience we want for the Windows phone
version of Plain ol' Notes notes.
| | 00:07 |
We've built a data model and we use the
standard template out of the boy from
| | 00:10 |
Visual Studio to hook it us so we could
tell that our data model was in fact
| | 00:12 |
feeding us the right kind of data.
But we have a few customizations we
| | 00:18 |
want to do that, and some changes, because
of course, instead of just the details
| | 00:21 |
page that shows the details of something
you've picked from the list selector, we
| | 00:24 |
actually want a text editor so that you
can edit the notes, and we also want a
| | 00:27 |
button at the bottom w-, that has an add
button so that you can create new notes.
| | 00:33 |
So, let's go over to Visual Studio, and
take a look at what we've got.
| | 00:36 |
Okay, this is our completed solution from
the solution at the end of this chapter.
| | 00:42 |
And it has all the features that we're
going to add and so I'm going to point
| | 00:45 |
them out to you and show you the bits and pieces.
| | 00:48 |
First of all let's take a look at the app
in action as its going to be at the end of
| | 00:51 |
this chapter.
You'll see that we now have.
| | 00:55 |
Plain Ol' Notesis the app title you can
see that we have notes as the name of the
| | 00:58 |
page and that each one of our lines has
one line instead of multiples and that if
| | 01:02 |
the text goes more than one line there's a
dot dot dot or an ellipses here at the end
| | 01:05 |
of the line that show ups after the last
word that will fit.
| | 01:12 |
So this is called word ellipses.
You could also choose to have character
| | 01:14 |
ellipses in which it would show up after
the last character that would fit, but
| | 01:17 |
word ellipses is more appropriate for this
kind of an app.
| | 01:21 |
In addition you can see over here on the
right hand side that there's a pencil icon
| | 01:24 |
hinting to the user that each time they
tap on one of these they'll be able to go
| | 01:27 |
and edit it.
And finally at the bottom of the screen
| | 01:31 |
we've got an app bar which is the way in
which you invoke commands on Windows
| | 01:34 |
phone.
And if we tap on the ellipses here you can
| | 01:37 |
see that our app bar has the word add
underneath it.
| | 01:41 |
And when we click on that we'll be able to
add a new note to our plain old notes
| | 01:44 |
collection.
Something that we'll get to when we get
| | 01:47 |
into the creating the code behind for
plain old notes.
| | 01:51 |
Now, it's not hooked up yet, so I'm
going to stop the app, and show you the
| | 01:55 |
editor page.
So you notice the detailspage.xaml is
| | 01:59 |
gone.
We've created a new page called Editor
| | 02:02 |
Page, and our Editor Page, as with our
main page, has the proper app title, it
| | 02:06 |
has the proper page title And it has a
text editor here in which the text, for
| | 02:09 |
existing notes will appear and where you
will edit new notes.
| | 02:15 |
Now one thing to note here is this is a
text box, there is no real good solution
| | 02:19 |
in windows phone that's the equivalent of
say, an IOS text area.
| | 02:25 |
In which you can have a scrollable text area.
| | 02:27 |
Where you can enter text at the bottom.
You can scroll up.
| | 02:30 |
You can do selections.
But you need to use a third party control
| | 02:32 |
for that.
So we're not going to do that in this
| | 02:34 |
course.
But our text box here will handle text as
| | 02:37 |
large as you want to put in it.
But you'll only be able to add at the end
| | 02:41 |
of the text, due to the limitation that's
in the Windows Phone SDK.
| | 02:44 |
That's the look at this user experience.
Now, we're going to explore a couple of
| | 02:47 |
other things about Windows Phone
development, before we get on to the
| | 02:49 |
challenge.
| | 02:50 |
| | Collapse this transcript |
| Handling orientation changes| 00:00 |
By default, windows phone pages have a
specific orientation.
| | 00:04 |
If we wanted to add another page to this
app, and we selected add new item, you'll
| | 00:07 |
notice that we have choices for our
windows phone portrait page or windows
| | 00:10 |
phone landscape page.
And if we run the app, if we rotate it,
| | 00:15 |
you'll notice everything turns sideways.
If we want to have it automatically do the
| | 00:22 |
xaml adjustments which works pretty well
in this particular app.
| | 00:27 |
All we do is we'll stop the app, we'll
come to the MainPage.xaml.cs and here
| | 00:31 |
we'll add something.
We'll say the supported page orientation
| | 00:36 |
in this is supported page orientation,
portrait or landscape.
| | 00:41 |
And now if we run the app again when we
rotate it automatically adjusts.
| | 00:48 |
You'll note that the app bar always shows
up right next to the hardware windows
| | 00:51 |
button regardless of the orientation of
the device.
| | 00:55 |
This works pretty well for some things if
you want to do specific orientations and
| | 00:59 |
force it we could for example.
Stop our app here and change it and say it
| | 01:05 |
only works in Landscape mode.
And now, we fire up the app, you notice
| | 01:10 |
it's already in Landscape mode and it will
stay that way no matter what our
| | 01:13 |
orientation is.
And you do that through this code.
| | 01:20 |
There's no declarative way of specifying
what orientations are as there are for
| | 01:24 |
iOS.
Alright the only thing you have to be
| | 01:28 |
concerned about is for example in our
editor page where we set the height of the
| | 01:33 |
text editor down here to 524 pixels.
Because we specified a specific height for
| | 01:39 |
the text box our text box will operate
differently in portrait and landscape
| | 01:42 |
mode.
If you want to adjust the height of the
| | 01:45 |
text box as the orientation changed,
you'll need to include a handler for the
| | 01:48 |
orientation changed event.
And then you can adjust that so that the
| | 01:52 |
text box shows up at the right height,
depending upon which orientation your
| | 01:55 |
device is in.
Alright, that's how we handle orientation
| | 01:59 |
changes for Windows Phone.
Next up, let's talk a little bit about
| | 02:02 |
debugging apps on Windows Phone.
| | 02:03 |
| | Collapse this transcript |
| Emulators and testing on a device| 00:00 |
For Windows Phone, unlike iOS, you have a
number of different emulators you can try
| | 00:04 |
your app in, because there are multiple
defined screen sizes as opposed to one
| | 00:08 |
emulator.
For example, like the iOS simulator where
| | 00:12 |
you can change the screen size dynamically.
| | 00:15 |
For Windows Phone, there are three defined
screen sizes.
| | 00:17 |
WVGA, WXGA, and 720.
And there's also an emulator marked WVGA
| | 00:23 |
512MB, because there are some Windows
phone devices which have less than a GB of
| | 00:27 |
memory, AKA 512MB, and so if you want to
test and make sure your app is going to
| | 00:30 |
run on those low memory devices you'll
want to test with that particular emulator
| | 00:34 |
as well.
All the things we're doing in plain old
| | 00:39 |
notes, you'll be able to test on the emulator.
| | 00:41 |
There are some things such as reminders,
and use of obviously the real GPS, and
| | 00:45 |
real accelerometer that you can't test on
the emulator.
| | 00:50 |
There are simulations for them in the emulator.
| | 00:52 |
But you want to test with those with a
real Windows phone device.
| | 00:55 |
To find out more details about emulators
and debugging on devices and all the
| | 00:59 |
intricacies involved in that you can check
out my two other courses.
| | 01:04 |
The Windows phone SDK essential training
and the distributing Windows Phone Apps
| | 01:08 |
through the Windows Phone Store both
available here in the online training
| | 01:11 |
library.
| | 01:13 |
| | Collapse this transcript |
| Challenge: Building the Windows Phone UX| 00:00 |
Now that we've looked at the user
experience for the Windows Phone version
| | 00:03 |
of Plain Ol' Notes, it's your turn.
Your challenge to build the UX from the
| | 00:06 |
exisitng solution we started with at the
end of chapter five.
| | 00:11 |
So what do you need to do?
First of all make a copy of the solution
| | 00:14 |
from the end of chapter five of the
Exercise Files.
| | 00:17 |
Second we're going to delete the
details.XAML page that came from the.
| | 00:21 |
Data bound template for Windows Phone from
Visual Studio.
| | 00:23 |
And we're going to replace it with an
EditorPage.xaml that has not only the
| | 00:26 |
proper titles at the top, but also a text
editor box in the middle.
| | 00:30 |
Then we're going to add some assets to our solution.
| | 00:32 |
These assets are provided for you in the
Exercise Files in the Assets Directory
| | 00:36 |
inside the Exercise Files.
And then we're going to add an app bar, so
| | 00:40 |
that we have a plus button at the bottom
in order to be able to hook it up to the
| | 00:43 |
add new note functionality we're going to
do when we get to the code behind.
| | 00:47 |
And then finally we're going to edit the
MainPage.xaml to trim up the lines, so
| | 00:51 |
that you only get one line, not multiple
lines for each line in the list box.
| | 00:56 |
And you have the pencil icon at the end of
each line, so that it hints to the user if
| | 00:59 |
it you tap on this, then you can edit the note.
| | 01:03 |
And finally, we'll put the XML for the app
bar in at the end of the page.
| | 01:08 |
And make sure it's connected up to our
Plus icon that we added into our assets.
| | 01:12 |
Should take you about 15 minutes.
We'll see you on the other side.
| | 01:15 |
And of course, as always, the solution is
there for you in the next movie if you
| | 01:17 |
want to see how I did it.
| | 01:19 |
| | Collapse this transcript |
| Solution: Building the Windows Phone UX| 00:00 |
Alright.
Here's my solution to the challenge.
| | 00:02 |
We're starting with the Visual Studio
solution in the state that we left it at
| | 00:05 |
the end of the last chapter after we've
built the data model.
| | 00:08 |
And now we're going to delete the details
page that came from the template.
| | 00:12 |
Add the Editor Page, add a couple of
assets, so that we can get pencil on the
| | 00:15 |
end of the line for each note that we have
to make it look nice to indicate to the
| | 00:18 |
user that they're going to tap to edit.
And we're going to edit the main page in
| | 00:23 |
order to establish the navigation between
the main page and the editor page.
| | 00:28 |
So step one, delete the details page, is
as easy as coming over here and saying,
| | 00:31 |
right-click and saying Delete. (MUSIC).
| | 00:35 |
And it will say delete it permanently?
And we say, OK.
| | 00:37 |
Now we're going to create the editor page.
We're going to right-click here and say
| | 00:41 |
Add New Item.
And we're going to pick Windows Phone
| | 00:45 |
Portrait Page.
And we're going to call it
| | 00:49 |
EditorPage.xaml.
Now, our page, as you can see here, once
| | 00:53 |
it loads up in Designer, looks very generic.
| | 00:57 |
That's because even with the main page,
which we're going to edit in a couple
| | 00:59 |
minutes, we haven't edited even the Chrome
around the application.
| | 01:03 |
So let's do that right now.
First of all, let's come over here and I
| | 01:07 |
haven't mentioned this earlier in the
course, but I'll show it to you now.
| | 01:14 |
I always go to Tools > Options > Text
Editor > XAML > Formatting > Spacing >
| | 01:18 |
Attributes Spacing > Position each
attribute on a separate line.
| | 01:24 |
I do that for two reasons.
One, because I like to be able to see each
| | 01:27 |
attribute on a new line.
And second, it makes it easier when you
| | 01:30 |
see it in the large font that we're using
here while we're recording the course.
| | 01:34 |
So then we can simply come up to the Edit
menu and say Edit > Advanced > Format
| | 01:38 |
Document.
And now you can see that each one of these
| | 01:41 |
attributes is on a separate line.
And we'll start with the Title panel here,
| | 01:46 |
we'll scroll this over here, I'll show you.
| | 01:48 |
Let's swap these guys around and minimize
the designer, since we don't need to see
| | 01:52 |
that right now.
And for my application, we're going to say
| | 01:56 |
plain, oops, it's got to be all capital
letters because it's Window's Phone Style.
| | 02:02 |
Plain Ol' Notes.
And for page name, we're here on the
| | 02:05 |
editor page, so we're just going to say editor.
| | 02:09 |
(SOUND) Alright.
So now we've done that.
| | 02:11 |
Let's take a look at what that page looks like.
| | 02:14 |
It's very simple.
Has our app title at the top, has our page
| | 02:16 |
title here.
Now, of course, we need to add an editor.
| | 02:21 |
We've got this grid, the content panel.
And inside there, what we're going to do
| | 02:24 |
is we're going to add a stack panel and
then a text box inside it.
| | 02:28 |
And while I'm doing that, I'm going to
mention something that is a conundrum, for
| | 02:31 |
Windows phone developers.
It's different than what you are going to
| | 02:34 |
find on ISO and Android.
There isn't a single simple control, that
| | 02:38 |
will give you a scrollable, text editor box.
| | 02:42 |
You can scroll, text, in a text block.
You can have the text box, that' we're
| | 02:46 |
going to use here.
Scroll automatically from the bottom as
| | 02:50 |
you're adding new text.
Once you're done adding new text, you
| | 02:53 |
can't easily scroll up and down without
having it not be able to go to the bottom
| | 02:56 |
on auto scroll.
It's really a deficiency of the Windows
| | 03:01 |
Phone SDK.
So, effectively, Plain Ol' Note for
| | 03:04 |
Windows phone, unless you use a third
party control for this and it's things
| | 03:07 |
that fit inside the text box.
So we'll add a StackPanel (SOUND) and
| | 03:12 |
we'll say Orientation=Vertical.
And we'll say VerticalAlignment is Stretch
| | 03:18 |
and HorizontalAlignment is Stretch and
inside our stack panel we'll put a
| | 03:22 |
TextBox.
And we have to give this text box a name
| | 03:26 |
because we're going to use this with our
code behind later, x:Name="editorTextbox"
| | 03:31 |
and then you say VerticalAlignment is
Stretch for it as well.
| | 03:36 |
And horizontal alignment is stretched.
And accepts return, we're going to set
| | 03:41 |
that to true because we want to have a
multi-line textbox.
| | 03:45 |
And then we're going to say height equals 5.4.
| | 03:48 |
Because this just happens to be a nice
height for a standard Windows Phone screen
| | 03:51 |
size.
And we're going to say text wrapping
| | 03:54 |
equals wrap, because of course we want it
to look like a multi line text box, and if
| | 03:58 |
your line is too long, you want that to
wrap to the next line.
| | 04:03 |
Alright, and then we'll do slash, close
bracket, and that's our text box.
| | 04:07 |
So let's take a look at what that looks
like, and we'll select this to say Fit all
| | 04:12 |
and there we go.
We've got our title for our app.
| | 04:17 |
Our title for our page and a text box.
Alright, so that's, that step, now we've
| | 04:22 |
added the editor page.
Now let's add a couple of assets.
| | 04:27 |
In the exercise files folder, we've added
an Asset folder and inside the Assets
| | 04:31 |
folder we've added two icons.
An add icon.
| | 04:35 |
Because we're going to use that in Windows
phone to add an app bar at the bottom to a
| | 04:37 |
lot of the add new notes.
We're going to add that editor icon at the
| | 04:42 |
end of every line on our main page to
indicate to the user that if they tap on
| | 04:45 |
the line with the first line of text they
can edit it.
| | 04:49 |
So what we're going to do is we're going
to go over to the Assets folder, we're
| | 04:51 |
going to right click, we're going to right
click here and say Add Existing Item.
| | 04:55 |
Now, I put my exercise files on the
desktop to make it convenient while
| | 04:59 |
recording.
I suggest you put the exercise files on
| | 05:02 |
the desktop or someplace very simple.
To make sure that you can easily get there
| | 05:05 |
while you're working through the course.
So we'll go into the Assets and we're
| | 05:09 |
going to select both add, I'm going to
hold down the Shift key and select edit,
| | 05:12 |
and then select Add here, and with Visual
Studio, when you add files like that, they
| | 05:15 |
get added, in this case, because they're
PNG, as content, but they don't get marked
| | 05:19 |
as copy into your binary, so you have to
do that manually.
| | 05:25 |
So I'm going to click on add, press the F4
key to get to Properties, and under Copy
| | 05:28 |
to Output, I'm going to select Copy Always.
| | 05:31 |
And similarly, I'm going to come back to
the solution, select edit, press F4 to get
| | 05:35 |
to Properties, and once again, select Copy Always.
| | 05:39 |
Just as a hint, if I was, left it here on
Do Not Copy, I can just double-click on Do
| | 05:42 |
Not Copy and it switches to Copy Always.
So that you don't have to use that drop
| | 05:47 |
down every single time.
In addition, you could have selected this
| | 05:50 |
and hold down the Control key and select
that and then press F4 and change them
| | 05:53 |
both at the same time.
All right, back to our solution.
| | 05:59 |
So, now we've got our assets edit, we've
got our Add button and we've got our Edit
| | 06:03 |
icon.
So finally let's go to the main page and
| | 06:06 |
update the main page Zemmel to look like
what we want it look.
| | 06:10 |
We'll put up the main page Zemmel and
we'll swap these around so we can easily
| | 06:13 |
do what we did before.
First step we're going to do is hide that,
| | 06:18 |
come down here, edit advanced format document.
| | 06:22 |
So that we get our attributes on a
separate line.
| | 06:25 |
And once again we'll change my application
to plain ol' notes.
| | 06:31 |
And this, page name, to notes.
Alright, now the next thing we want to do
| | 06:37 |
is to add this icon at the end of every
little line in our list selector, so that
| | 06:41 |
there's the pencil icon there.
Indicating that if you tap on one of the
| | 06:47 |
items in that list You'll get the editor.
So the way we do that is in our grid in
| | 06:52 |
our content panel, we've got a data
template here for our long list selector.
| | 06:59 |
And inside the data template we've got a
stack panel.
| | 07:02 |
But what we really want is we really want
to be able to have our first line over on
| | 07:05 |
the left, and our icon, always on the
right hand side.
| | 07:09 |
So what we're going to do is inside here
we're going to add a grid.
| | 07:12 |
I will put the end of that grid, cut it
from there, and put it here inside the
| | 07:15 |
stack panel.
And then inside the grid we're going to
| | 07:18 |
say grid dot column definitions, because
we're going to define two columns here.
| | 07:22 |
And the first column will say column
definition width equals star.
| | 07:26 |
Because that's going to be The first line
of our note.
| | 07:30 |
And secondly we're going to say column
definition width equals 40.
| | 07:33 |
because that's the number of pixels that
we have for our pencil icon, because we
| | 07:36 |
always want it to be the same size on the
right hand side.
| | 07:40 |
Alright, now we've got our column
definitions into our text block, we need
| | 07:44 |
to add one more item here that says Grid
dot column equals zero.
| | 07:49 |
So that it shows up in the right place.
And then after the text block, we need to
| | 07:53 |
add an image control.
Image grid dot column equals one.
| | 07:59 |
And source is going to be slash assets
slash edit dot PNG.
| | 08:07 |
Now if we go take a look at our main page.
Put it back to fit all.
| | 08:13 |
Since we don't have a design time data
source, we can't see everything at design
| | 08:16 |
time.
But when we run this, we'll see our icon
| | 08:18 |
at the end of each line.
Alright, we're not going to change any of
| | 08:22 |
the code behind right now, but this is
what we're going to do to set up the UI.
| | 08:26 |
So let's go ahead and run this.
And now you can see that we have the icon
| | 08:30 |
on the right hand edge of each field.
One of the other things we want to do to
| | 08:35 |
the main page is make this show up as one
line only not multiple lines.
| | 08:39 |
And we also have to add the app bar button
to add our new notes.
| | 08:43 |
So, let's add those last 2 things.
Come back to the Xamile for the main page.
| | 08:47 |
Put the Designer away.
In our text block, we're going to say
| | 08:50 |
TextWrapping equals NoWrap, and that will
cause that to not give us multiple lines.
| | 08:56 |
And then we'll also add one more property,
TextTrimming, and we'll set that to
| | 09:01 |
WordEllipsis.
Let's run that again, see what just those
| | 09:05 |
two changes do for us So you can see, our
first line is short enough.
| | 09:10 |
Our second line, is too long to fit all
the way on here, so it puts an ellipsis at
| | 09:13 |
the end of the last word that it can fit
and similarly with our Shakespeare quote
| | 09:17 |
here.
For developers, who are coming from ISO or
| | 09:21 |
Android, this set of number over here on
the side, is the frame rate counter, which
| | 09:24 |
is very useful when developing.
Games or high interactive applications.
| | 09:30 |
If we want to turn that off, let's go
ahead and do that because we don't need
| | 09:33 |
that for Plain Old Notes.
The way you do that is you come back to
| | 09:37 |
the solution and you go into the app dot
zammel dot CS.
| | 09:42 |
And you come down here to line 61, this
line right here.
| | 09:46 |
And just comment that out, or set it to fault.
| | 09:49 |
In this case I'm just going to comment it out.
| | 09:50 |
Now notice that's in a block marked if
debugger that is attached.
| | 09:55 |
So, this only shows up when you're using
the debugger however, as you're doing this
| | 09:57 |
course we're going to be using the
debugger a lot.
| | 10:00 |
So, we're going to turn that off.
So, once again take a quick look at that
| | 10:03 |
without the frame rate counters there.
So, there we go.
| | 10:06 |
Now, our UX looks pretty much like what we
wanted except we don't have the add button
| | 10:09 |
at the bottom.
So let's add that.
| | 10:12 |
That's one more step.
Go back to the main page (UNKNOWN).
| | 10:14 |
We come down here to the bottom.
And after the grid, but before the phone
| | 10:19 |
application page.
We need to add an application bar.
| | 10:23 |
And so you do it this way.
Phone, colon, phone application page dot
| | 10:28 |
application bar.
And inside the application bar, now we're
| | 10:32 |
going to put a shell.
Application bar item is visible, true,
| | 10:37 |
because we want to have our button visible.
| | 10:40 |
And is menu enabled equal true, because we
want it visible all the time.
| | 10:44 |
And now inside our show application bar,
we're going to put an item, shell,
| | 10:48 |
application bar button icon.
Our icon URI is slash assets.
| | 10:55 |
Slash add.png.
The other graphic that we added to the
| | 10:59 |
assets file.
And text is going to be add.
| | 11:04 |
Now we'll also have to say click.
And this is going to be add button.
| | 11:09 |
In fact, you can see the visual studio
here offers us the opportunity to create a
| | 11:11 |
new event handler.
So I'm just going to come up here and
| | 11:14 |
click this new event handler.
And you can see it creates application bar
| | 11:18 |
button icon click.
And if we right click on this and say
| | 11:21 |
navigate to event handler, you can see it
added an empty method for us already.
| | 11:26 |
So we'll come back to the main page XML.
And I will bring back the XML when we see
| | 11:31 |
it tells us we have an error.
So let's take a look and see what that
| | 11:34 |
error is.
Our error is we have an attribute name
| | 11:37 |
missing somewhere.
Let's get this out of here.
| | 11:40 |
And it says an attribute name is missing.
And I can guess that that is because I
| | 11:44 |
haven't closed this guy here.
So let's do slash close bracket.
| | 11:50 |
And there.
That closes that out.
| | 11:51 |
Because now at this particular.
Application bar button icon button wasn't
| | 11:55 |
complete.
All right.
| | 11:56 |
So let's go give this a run.
And we'll see that we now have an
| | 12:01 |
application bar at the bottom in Windows Phone.
| | 12:03 |
For iOS and Android developers, the way
you see the text that goes along with that
| | 12:07 |
button is you click these three dots.
We'll tap that and now we can see the add
| | 12:10 |
button.
And if we click the add button.
| | 12:13 |
It will go off to our event handler and
drop the application bar back down.
| | 12:16 |
When we get to the code behind section,
then we'll learn how to put code inside
| | 12:19 |
that event handler so that we can create a
new note and navigate off to the editor so
| | 12:22 |
that you can fill it in.
All right.
| | 12:26 |
That's the solution.
If you have any questions, go back to the
| | 12:28 |
beginning and watch it again.
It's very straightforward.
| | 12:31 |
We went through the following steps.
We deleted the details page.
| | 12:34 |
We added a newEditorPage.xaml and change
the title and the subtitle of that page
| | 12:39 |
and add it in Text Editor.
Then we added our assets, our add button,
| | 12:44 |
and our pencil icon, and then we edited
the main page.
| | 12:49 |
What we did in the main page was we made
these lines single lines, with the
| | 12:52 |
trailing ellipses.
We added the title and subtitle for the
| | 12:56 |
page.
We added two columns for this list so that
| | 12:58 |
we could have the first line and the
pencil icon at the end of each one.
| | 13:01 |
And then we added, in the second column, a
call out to the asset for the Edit button
| | 13:05 |
that we put into the assets folder.
And then, finally, we added the
| | 13:10 |
application bar at the bottom and added
the single button here to add a new note.
| | 13:15 |
Alright, that's the end of building the UX
for Windows Phone, now we'll move on to
| | 13:18 |
building the UX for Windows Store.
| | 13:21 |
| | Collapse this transcript |
|
|
7. Creating Screen Markup for Windows StoreBuilding the XAML for the Windows Store app| 00:00 |
Alright, moving on to creating the screen
markup for the Windows store version of
| | 00:03 |
PlainOlNotes.
Before we get into everything else, let's
| | 00:06 |
take a look at PlainOlNotes in action,
running on Windows.
| | 00:09 |
So this is Plain Ol' Notes, there's the
title of our app, up here at the top.
| | 00:12 |
Each one of our notes, as we've seen
before when we looked at the Windows phone
| | 00:15 |
version.
And the note over here on the right hand
| | 00:17 |
side, with an edit button that allows us
to edit the note in a text editor.
| | 00:21 |
We'll come over here and say (SOUND) Add a
little bit of text, and come back and find
| | 00:25 |
out that that's updated in our text.
But of course, since we didn't change the
| | 00:30 |
first line, that didn't change.
We come over here and change the first
| | 00:33 |
line, put a comma in, for example, and
come back.
| | 00:35 |
You'll notice that the title of the note
is changed.
| | 00:37 |
And, so this is derived from a template
called the split app template.
| | 00:41 |
This page called the split page, has a
list of items over here on the left hand
| | 00:44 |
side, a preview of the item on the right
hand side, and then we've added, specific
| | 00:47 |
call outs for the, date and time and when
the note was last modified.
| | 00:51 |
And an Editor button.
And as we saw, you click the Editor
| | 00:54 |
button.
We go to an editor page that has a nice,
| | 00:56 |
big text editor here that allows you to
edit your notes.
| | 01:00 |
So next up we'll take a look at the split
app out-of-the-box template.
| | 01:04 |
And understand what its moving parts are.
And then we'll look at what we've done to
| | 01:07 |
this template to turn it into Plain Ol' Notes.
| | 01:10 |
Following that, we'll take a look at
issues related to orientation and size
| | 01:13 |
changes, and then we'll get into the two
challenges for this chapter, building the
| | 01:16 |
XAML for Windows Store app part one and
part two.
| | 01:20 |
| | Collapse this transcript |
| Exploring the split-app template| 00:00 |
Let's create a new Windows store app using
the split app template and explore its
| | 00:03 |
moving parts until we understand what's
there for us to begin with and what is it
| | 00:06 |
we need to change in order to turn it into
plain old notes.
| | 00:11 |
Start with a new project, pick Split App
and we'll put this back in the Visual
| | 00:15 |
Studio's project area because we're not
going to include this in the exercise
| | 00:18 |
files.
This is something you can easily do by
| | 00:21 |
saying file new project.
And creating split app, and we'll put it
| | 00:25 |
in here and we'll call it split app
(SOUND) review.
| | 00:28 |
If we take a look at the solution, you can
see that there's two pages.
| | 00:35 |
There's the items page, and there's the
split page.
| | 00:37 |
Take a look at the items page.
The items page has the app title at the
| | 00:41 |
top and a bunch of group items because the
data model for this has Data groups with
| | 00:44 |
data items inside of it, so the user
experience of this, let's just take a
| | 00:48 |
quick look at this app running in the simulator.
| | 00:55 |
So there's a bunch of groups, group 1,
group 2, and so forth.
| | 00:58 |
We click on a group, we see a bunch of items.
| | 01:00 |
As you select each item, you notice that
the preview area over here changes.
| | 01:03 |
But each one of these items has things
that we don't need for plain old notes.
| | 01:07 |
It has subtitles, it has an image.
It doesn't have an edit button, so that we
| | 01:11 |
can edit it.
And, so we need to change all these
| | 01:13 |
templates to match the way we want.
And make some changes to this section of
| | 01:17 |
the user experience over here to add our
edit button.
| | 01:20 |
We also don't even need to have groups.
So what we're going to do is we're
| | 01:24 |
going to actually cause the app to start
directly at the items page.
| | 01:28 |
And then we're going to add another page
for our editor.
| | 01:30 |
Alright.
So let's go ahead and quite the simulator.
| | 01:32 |
And take a look at the structure of this app.
| | 01:34 |
In terms of how it's put together, so we
can get an idea, what we're going to have
| | 01:36 |
to change.
So, the app, here at app dot (UNKNOWN) dot
| | 01:39 |
CS, begins with a whole bunch of boiler
plate code, that comes from this visual
| | 01:43 |
studio template.
But the way things actually work, in
| | 01:47 |
determining what's the starting page.
Is this line right here line 80, and what
| | 01:52 |
it does is basically say, oh, navigate to
the items page and pass in a parameter
| | 01:56 |
called all groups.
In Windows store apps as opposed to
| | 02:00 |
Windows phone apps, you don't navigate
with a URI, you navigate with a type.
| | 02:04 |
So you can only have one item of type
items page.
| | 02:07 |
You specify the page type you want to go
to, and you can pass a single object.
| | 02:11 |
Now in our case we just happen to be
passing a string which the sample data out
| | 02:14 |
of the box.
Knows to return back all the group items.
| | 02:18 |
So that the page will take a look at the
load state for the page.
| | 02:22 |
So you can see how it uses this particular data.
| | 02:24 |
But you could put any object here,
including a complex object with lots of
| | 02:27 |
parameters.
But you can only pass one object.
| | 02:30 |
So that means unlike Windows Phone, where
you can pass any number of query
| | 02:33 |
parameters on a URI, here you have to
create your own object and put the
| | 02:36 |
multiple parameters inside of it.
So what we're going to do when we start
| | 02:40 |
building plain old notes, we're going to
change this type of from items page to
| | 02:43 |
split page, and we're going to change the
argument here so that it grabs the first
| | 02:46 |
group in terms of our first phase of
updating this.
| | 02:51 |
And then eventually we don't even need to
pass an argument because we're going to be
| | 02:54 |
getting our data from our persistent data store.
| | 02:57 |
All right, that's the rough look at what's
in the app xx.
| | 03:01 |
There's other pieces in here that have to
do with how suspending is handled.
| | 03:05 |
We mentioned the different life cycle
states of a Windows store app earlier in
| | 03:09 |
the course and these methods here on
launch, on suspending get called at the
| | 03:12 |
appropriate times as you app changes state.
| | 03:16 |
Now, let's go take a look at the split
page, because the items page is something
| | 03:20 |
that we're going to completely delete from
our solution.
| | 03:24 |
And we're going to edit the split page.
First of all let's take a look at the
| | 03:26 |
split page example.
And as you can see we have a list view
| | 03:31 |
over here, and we have a text box, and an
image, and some title boxes up here.
| | 03:37 |
Along with a title up here for the group,
and a back button.
| | 03:40 |
Now in Windows store apps, of course
there's no hardware back button on
| | 03:44 |
devices.
But the back button here shows up if
| | 03:46 |
there's actually something on the back stack.
| | 03:49 |
And it's all done XAML binding.
So let's go ahead and swap these guys and
| | 03:53 |
get rid of the designer and take a look at
what's in the code.
| | 03:56 |
And we'll do the standard thing we always
do here.
| | 03:59 |
We'll reformat it so that all of the
attributes of the XML are on separate
| | 04:02 |
lines so we can take a look and see what's there.
| | 04:06 |
So, this particular page uses a collection
view source and it's called items view
| | 04:09 |
source, and it's bound to items in the
data source for the page.
| | 04:14 |
And as you probably know, if you're
existing Silverlight or WPF programmer,
| | 04:17 |
you can also specify a design group
source, so that's why you see when we look
| | 04:20 |
at it in the designer, there's data there.
So what this has done is it says it's
| | 04:26 |
binding to this item view source.
The all groups property, the first item in
| | 04:31 |
that all groups property and those items
and so forth.
| | 04:34 |
So, is building Plain Ol' Notes, we're not
going to create a design view source,
| | 04:37 |
since our data is so simple.
Once we get it going, we'll be able to
| | 04:41 |
just initially fire up the app and see the
data, but in terms of adjusting the user
| | 04:44 |
experience as we manipulate the XAML,
we're going to keep this.
| | 04:48 |
Predefined data with the lower midsum text
inside of it.
| | 04:52 |
As we adjust the templates as we can
actually know we've got them looking
| | 04:55 |
roughly the way that we'd want them before
we hook up our data source.
| | 04:59 |
Alright.
The top section here defines the page,
| | 05:02 |
which is a 140 unit bar at the top.
That's where the title and the back button
| | 05:08 |
go.
And then the remainder of the page.
| | 05:10 |
And inside that top button There's the
primary column for the back button and so
| | 05:14 |
forth, and then there's everything else.
So we take a look at the standard boiler
| | 05:19 |
plate stuff, that's the back button and
the page title.
| | 05:23 |
So here's the back button, which is bound
to the default view model, a particular
| | 05:26 |
thing called can go back And that's
basically handled by the infrastructure
| | 05:29 |
again, since there's no hardware back
button on a Windows store app.
| | 05:34 |
You let the infrastructure in the system
keep track of whether or not a back button
| | 05:38 |
should show up there, kind of like you
might do on a web page, looking to see if
| | 05:41 |
the History is empty or not.
And you'll notice another thing here,
| | 05:46 |
which is a lot of styles called out as
static resources.
| | 05:49 |
Here in the common folder, there's a huge
file here called Standard Styles.
| | 05:53 |
If we look at that, that is 1830 lines of
standard XAML that breaks up in everything
| | 05:57 |
from the root style of the page to a bunch
of different buttons, to different-sized
| | 06:02 |
item templates for use in full size mode,
in split-pane mode, and that's used
| | 06:05 |
extensively throughout the boilerplate code.
| | 06:11 |
And when we want to create any special
styles we'll actually include them in our
| | 06:15 |
pages.
But you might want to look through here
| | 06:18 |
just to see the wide variety of standard
things that Microsoft has already provided
| | 06:21 |
for you. Alright.
| | 06:23 |
In this particular case, in the split view
page, we have our ListView here, item,
| | 06:26 |
this view, the items for this list view is
bound to something called ItemsViewSource,
| | 06:30 |
and that's done with a particular
dictionary, and we'll take a look at that
| | 06:33 |
in just a minute.
More importantly, the item template, the
| | 06:38 |
one where we saw, if I can just bring
Designer back up here, you can see that
| | 06:42 |
this, this view item template has an
image, a title, a subtitle, and a
| | 06:46 |
description.
For Plain Ol' Notes, we're simply going to
| | 06:51 |
have a item title, and that's it.
So we'll need to have a different item
| | 06:55 |
template than the one that's used a
standard template.
| | 06:58 |
So what we're going to do, and we'll look
at the in the next movie As we're going to
| | 07:00 |
create our own item template.
Now, you might wonder, why does this say
| | 07:04 |
standard 130 item template?
Well, it turns out that there's two
| | 07:07 |
different item templates you want to provide.
| | 07:10 |
One is basically for when you are in full
screen mode, and the other is for when you
| | 07:14 |
might be in rotated mode, say, in portrait mode.
| | 07:18 |
Or, when you're in snapped mode.
When you're in a snap view.
| | 07:20 |
And so you actually create two different templates.
| | 07:23 |
And the infrastructure of the page.
Notice over here in the common folder,
| | 07:26 |
there's something called layout aware page.
| | 07:29 |
Microsoft's provided a full infrastructure
to handle.
| | 07:32 |
Rotation and awareness of your snap versus
full views.
| | 07:36 |
And it automatically switches between the
templates that you need to have.
| | 07:39 |
And we'll look in terms of what we
actually have to change when we start
| | 07:42 |
building plain old notes.
In the next movie we look at how it's been
| | 07:45 |
changes.
But just be aware that this particular
| | 07:47 |
template here.
Is found in that standard styles, and
| | 07:50 |
we're going to copy it out and make some
changes and put it directly inside of our
| | 07:53 |
xaml for this page.
And, the next half of our page is done
| | 07:57 |
inside the scroll viewer.
The display for the selected item, the
| | 08:00 |
thing that we see on the right hand side
of the page, over here, is broken up into
| | 08:03 |
a number of pieces.
Scroll up here.
| | 08:07 |
You can see that there's an image, there's
a title panel, right here.
| | 08:11 |
And inside that title panel, there's a
title, there's a subtitle and then there's
| | 08:17 |
a text block down here for the content.
And we're going to make some changes to
| | 08:23 |
that and we're also going to add our edit
button, our button with, the hand with the
| | 08:26 |
pencil you saw in the walk through, that
will allow us to then switch to our editor
| | 08:29 |
page.
Let's take a look at the code behind for
| | 08:33 |
this just so that you can get one other
sense of things before we start looking at
| | 08:36 |
the UX for plain old notes.
We look at the spit page, code behind.
| | 08:42 |
The main thing to understand is that
there's two methods that you care most
| | 08:46 |
about and they're here in page state
management and they are load state And
| | 08:49 |
save state, so in our case, load state is
where that navigation parameter, when we
| | 08:53 |
saw the all groups, got passed in here.
When we get to plain old notes, load state
| | 09:00 |
is where we're going to actually go load
the notes and set up this default view
| | 09:03 |
model, items member, to point to the items
in our data model.
| | 09:08 |
This boil plate code right here has to do
with if you've already been working on a
| | 09:11 |
particular item when you got to the
editor, when you return it will
| | 09:14 |
automatically re-select the thing that you
had edited.
| | 09:18 |
Otherwise it will jump to the beginning.
So this is if it's null, it selects the
| | 09:22 |
first.
And if it's not it looks to see whether
| | 09:25 |
the page state contains a key for selected item.
| | 09:28 |
And if it does then it moves to that
particular item.
| | 09:31 |
And similarly, save state, in this
particular case, for the boilerplate coe
| | 09:34 |
for Visual Studio, says if we are leaving
the page, and there is a selected item,
| | 09:38 |
then go ahead and set that page state
selected item property, so that you can
| | 09:41 |
know when we come back, when the load
state gets triggered again, which item to
| | 09:44 |
select.
Alright, that's a look at things that we
| | 09:50 |
need to care about about the split app
template straight out of Visual Studio.
| | 09:55 |
In the next video, we're going to take a
look at plain old notes and see what we
| | 09:58 |
did to that, which is the challenge for
you, is to perform that transformation
| | 10:01 |
between this out of the box template.
And Plain Ol' Notes, the XAML to be set up
| | 10:06 |
the way that we need it for Plain Ol'
Notes, in order to be able to then get
| | 10:08 |
ready to put the code in there.
| | 10:11 |
| | Collapse this transcript |
| Exploring the XAML for PlainOlNotes| 00:00 |
All right, your challenge in this
particular chapter is going to be to
| | 00:03 |
transform a version of that split app
template from its effectively raw state
| | 00:06 |
with our data model added.
Which is where we ended up at the end of
| | 00:10 |
the last chapter, to a version where the
XAML, the user experience interface code
| | 00:14 |
looks like what we want for this
particular chapter.
| | 00:17 |
So let's take a look at what we did to the
split app template raw code, in order to
| | 00:21 |
turn it into Plain Ol' Notes.
You'll notice two things to start with.
| | 00:26 |
One, the Items page is missing, we simply
deleted that.
| | 00:29 |
And two, we have a new page, called Editor page.
| | 00:32 |
Now, let's take a look at what we did to
Split page.
| | 00:35 |
And I'm going to split this off this way,
and tell this to fit all.
| | 00:41 |
Just because we can just take a quick look
at the overall structure.
| | 00:44 |
So you can see that we have the back
button, and the title, just as you would
| | 00:48 |
normally have except that we've changed
the title to be hardwired to be Plain Ol'
| | 00:52 |
Notes.
Because the Split page is no longer an
| | 00:56 |
item from a group.
It is really just our starting page.
| | 01:00 |
Now, we don't need to worry about deleting
the back button, because as I mentioned in
| | 01:04 |
the previous video, the back button has a binding.
| | 01:07 |
Is enabled is bound to the default view
model, CanGoBack element here.
| | 01:12 |
And since that's never true.
For this particular page it simply
| | 01:16 |
disappears.
Over here in our List view, we've adjusted
| | 01:19 |
the item template.
And I'll show you that in a minute.
| | 01:22 |
We've also made some changes over here.
We still have the content text block, and
| | 01:26 |
we have a title text block.
But now, we also have our Editor button.
| | 01:31 |
So let's put away the designer and take a
look at the bits and pieces.
| | 01:34 |
Let's start with the List view.
So you can see in the list view, I've
| | 01:37 |
changed the item template to say PONItemTemplate1.
| | 01:39 |
So that's Plain Ol' Notes item Template 1.
What I did was up here in the Page
| | 01:42 |
Resources, I added a data template.
What I did was I went to the standard
| | 01:49 |
styles.
And I looked for Standard130, because I
| | 01:55 |
needed to get to Standard130 in the
Standard80 template.
| | 02:02 |
What I did was I simply found them here.
They're one after the other.
| | 02:05 |
Here's the Standard130 template.
Here's the Standard80 template.
| | 02:09 |
I simply copy them like so, and I pasted
them into the Split page XAML and then
| | 02:12 |
made changes to them.
So I brought them in here and I renamed
| | 02:16 |
them pon item template one and pon item
template two and made a number of changes.
| | 02:22 |
I got rid of the image.
I got rid of the references to subtitles.
| | 02:26 |
I changed the default height on this from
actually 130 to 60 for the item Template
| | 02:31 |
1.
And I took as I said, I took out the other
| | 02:34 |
text block so that only the text block for
the first line is actually showing there.
| | 02:39 |
Similarly for item Template 2, I took out
the image and I took out a few of the
| | 02:42 |
other things and made a much more compact
template for item Template 2.
| | 02:48 |
All right, you'll notice there were a
couple of other things here in the Page
| | 02:51 |
Resources.
And we'll talk about those when we
| | 02:54 |
actually get into the nuts and bolts of
updating our data model to be really a
| | 02:57 |
production data model.
And that has to do with how we have a
| | 03:01 |
button to be able to add and delete notes.
And these are styles that define what the
| | 03:07 |
buttons look like and when we get there,
down here at the bottom of the page.
| | 03:11 |
We added a Bottom App bar to reference
those two things in order to implement the
| | 03:14 |
add button and the delete button.
Otherwise, within our page, the main
| | 03:19 |
changes we've made were here to change the
text of the title to Plain Ol' Notes,
| | 03:22 |
instead of being a data source reference.
We came down here to the list view and
| | 03:27 |
changed its item temple to PONItemTemplate1.
| | 03:31 |
And then if we go and look down here in
the visual state updates for filled or
| | 03:35 |
narrow when we're in our snapped view we
change this used to say standard 80 item
| | 03:40 |
template and we change it to be PONItemTemplate2.
| | 03:45 |
And there's two of those we had to update.
And the last thing we had to do is down
| | 03:50 |
here In this section, where it says
Snapped detail, there were pieces of
| | 03:54 |
object animation at the bottom here that
were referring to other properties.
| | 04:01 |
Let me scroll this to the right here.
You can see that this refers to item
| | 04:04 |
title.
There was another property here that
| | 04:07 |
referred to item subtitle.
And since we took item subtitle out of the
| | 04:10 |
item template, when you tried to use this
in Snapped mode, it would crash.
| | 04:15 |
So if you forget to do that, this is where
you'll want to come down and delete it.
| | 04:19 |
If we look at our standard, out of the
box, split up template, there'll be two
| | 04:22 |
items at this spot right here near the
bottom of the XAML for the page in the
| | 04:25 |
object animation using keyframes.
because they're trying to animate the bits
| | 04:30 |
and pieces of this to make it look like
the page is transforming as it rotates.
| | 04:35 |
All right, that's the changes we have to
make to split page XAML.
| | 04:39 |
Then we wanted to add a new page.
So the way we added our editor page was we
| | 04:42 |
came up to the project, we said
right-click, add new item.
| | 04:46 |
And we just picked Basic page.
We'll preview here, but all the basic page
| | 04:50 |
has on it is the Back button, a title for
the page, and an empty area.
| | 04:55 |
So we added our basic page, we called it
Editor page.
| | 04:58 |
What we did to this was very simple.
We simply added this grid item, here, for
| | 05:02 |
our Text Editor.
There's a bunch of properties here.
| | 05:06 |
Let's take a look at the ones that are
really significant.
| | 05:08 |
I made the font size 24 because, for a
touch-enabled device, you want the font
| | 05:12 |
size to be big enough to be able to allow
the users to do selections with their
| | 05:15 |
finger.
If you're building a Windows store app,
| | 05:18 |
you need to be thinking about that, you
think about somebody using it on a
| | 05:21 |
surface.
Or somebody using it on the simulator.
| | 05:24 |
I set the font family to Segue UI, because
that's Microsoft's recommendation for data
| | 05:28 |
input fields.
I set the vertical alignment, horizontal
| | 05:31 |
alignment to stretch.
Because it's just a good practice to do
| | 05:34 |
so.
I want our Text Editor to be able to
| | 05:36 |
scroll vertically, so I made the vertical
scroll bar visibility to Auto.
| | 05:40 |
And it doesn't scroll horizontally, so we
set the horizontal scroll bar visibility
| | 05:43 |
to Disabled.
I added a little border around it because
| | 05:46 |
it looks good, not because it's functional.
| | 05:48 |
You wouldn't have to do border thickness
or border brush if you don't want to, I
| | 05:51 |
just thought it looked good and made the
app look a little more polished.
| | 05:55 |
The background can be any color you want
but I set it to light gray here.
| | 05:58 |
So that it looks more like a piece of paper.
| | 06:00 |
And just like we did in Windows phone, you
want to have TextWrapping equals Wrap and
| | 06:03 |
AcceptReturn equals True because you want
this to be a multi-line text box, and then
| | 06:07 |
we have a couple of event handlers.
One for text changed, one for selection
| | 06:12 |
changed.
And because the grid in the whole page has
| | 06:16 |
two pieces to it, we just told it to span
both pieces so that the text editor fills
| | 06:20 |
the entire page.
And that's all we did to make the Editor
| | 06:24 |
page.
There's a little bit of code in the code
| | 06:25 |
behind it.
We'll get to that later, when we actually
| | 06:27 |
look.
In the future chapter about connecting
| | 06:29 |
this to our data source, but that's all
the examples that we had to do for that.
| | 06:33 |
So, your challenge, after we talk a little
bit about orientation and size changes and
| | 06:37 |
the debugging using the debugging system
or using the simulator, is to replicate
| | 06:41 |
these XAML changes that I just showed you
in the Plain Ol' notes for Windows Store
| | 06:44 |
app as we're building it up.
So, it will have a data model in it, we've
| | 06:51 |
already started to build and now you need to.
| | 06:53 |
Delete the Items page, modify the Slit
page, and add the Editor page.
| | 06:58 |
Let's carry on to talking about
orientation and size changes, and then a
| | 07:00 |
little about debugging, and then we'll get
to your challenge for this chapter.
| | 07:04 |
| | Collapse this transcript |
| Handling orientation and size changes| 00:00 |
Windows store apps like Windows phone
apps, can work on a variety of devices,
| | 00:04 |
with a variety of screen sizes, and also
orientation changes, as well as split
| | 00:08 |
change pages.
So you can test your app on your local
| | 00:12 |
machine.
Example, we'll run PlainOlNotes here, and
| | 00:15 |
it using the full screen of my debugging machine.
| | 00:18 |
Or you can test your apps on what's called
the Windows store app simulator.
| | 00:24 |
What this really is, is simply a window
into your existing machine.
| | 00:27 |
And I'll show you that by the fact that if
I click the Windows button, I'm back here
| | 00:31 |
to the same exact desktop that I get if I
click the Windows hardware button on my
| | 00:34 |
machines.
So it isn't really a seperate virtual
| | 00:38 |
machine as it is with Windows phone.
Its really just a windowed version into
| | 00:42 |
your existing machine which means that you
have access to.
| | 00:46 |
All of your files and all of the
infrastructure that exists on your
| | 00:48 |
debugging machine.
So we can do things like this.
| | 00:52 |
Currently we have touch mode turned on.
You can also have mouse mode so that you
| | 00:56 |
can just use your cursor like the user
would test the app when he's running it on
| | 00:59 |
a machine without a touchscreen.
You can handle rotations.
| | 01:04 |
And you can see that the app automatically
transitions, because that stuff is built
| | 01:08 |
in to the template that we used, the split
app template.
| | 01:12 |
Now you want to know that later on, when
you become more proficient at this, that
| | 01:15 |
there are a number of things and you'll
see some of this in the challenge, that
| | 01:18 |
are referred to in the item templates by
virtue of the split app template.
| | 01:23 |
That if you delete those things from the
item templates.
| | 01:25 |
You also have to delete some of the
declarative XML in your pages that attempt
| | 01:29 |
to do some of that transition, like we
just saw.
| | 01:32 |
For example, if we switch back here,
you'll notice that these things have a
| | 01:35 |
visual transition to them.
Some of that visual transition is
| | 01:39 |
specified in XML, which tries to do
various graphical transitions.
| | 01:44 |
And you need to make sure that those things.
| | 01:47 |
That are being referred to, actually exist.
| | 01:49 |
Or the app'll crash, and you'll be able to
figure that out in the de-bugger.
| | 01:52 |
In addition to a full size, you know that
Windows apps have split sizes.
| | 01:57 |
So you can have small on the right, small
on the left.
| | 02:00 |
Or fitting in the middle.
And you can test this by holding down the
| | 02:03 |
windows key, the shift key, and using the
right angle bracket key which is above the
| | 02:06 |
period.
In addition to testing on your native
| | 02:10 |
device and on the simulator, if you have a
second windows machine that you want to
| | 02:13 |
test on, for example a surface, you can
come up here and say remote machine.
| | 02:19 |
And when you specify remote machine, you
can either put in the ip address and the
| | 02:22 |
appropriate authentication.
Or it will actually search your sub-net
| | 02:26 |
for Windows 8 machines that have the
debugging monitor already turned on.
| | 02:31 |
And that's how you work with debugging an
app on the Surface.
| | 02:34 |
You turn on the remote debugger host and
then you'll be able to find your app and
| | 02:37 |
connect it up.
And you'll actually be able to debug your
| | 02:40 |
app wi-fi on the Surface.
That's a little overview of orientation
| | 02:44 |
changes and Size changes and debugging
Windows store apps let's dig into building
| | 02:48 |
the UX for our Windows store version of
plain old notes broken up the challenge
| | 02:52 |
into two pieces to make it more easily manageable.
| | 02:57 |
The first piece we're going to change the
first page of the split app template to
| | 03:01 |
look like our main page.
This here and then, we're going to in the
| | 03:04 |
second challenge we're going to go through
and add the editor page and connect it up
| | 03:08 |
to the data on the main page so that when
you click something in the list view it
| | 03:11 |
shows up in the editor here on the editor view.
| | 03:17 |
Ready for a challenge?
Let's go.
| | 03:18 |
| | Collapse this transcript |
| Challenge: Building the Windows Store UX, part one| 00:00 |
Alright.
We've taken a look at the UX for the
| | 00:02 |
Windows Store version of Plain Ol' Notes.
Talked a little bit about handling
| | 00:06 |
orientation and size changes.
And talked a little bit about debugging
| | 00:09 |
Windows Store apps.
So now it's your turn.
| | 00:11 |
This challenge is broken into two parts.
The first part, building the Windows Store
| | 00:15 |
UX part one, you're going to create a new
project using the split app template from
| | 00:18 |
Visual Studio.
Trim out the items page, make it start at
| | 00:22 |
the split page and adjust some of the
items and the templates in the split page
| | 00:25 |
so that it looks more like plain old notes
rather than just the default template that
| | 00:29 |
comes out of Visual Studio.
The steps you'll go through to do that
| | 00:34 |
are, create a new project using the Split
App template.
| | 00:37 |
In my solution I did it in the Chap 07
file in the Exercise Files.
| | 00:41 |
So, you can find my solution there but,
you can create it where ever you want but,
| | 00:43 |
just remember you're going to need to find
it again in order to be able to complete
| | 00:45 |
part two of the challenge.
Then, once you've got your solution
| | 00:49 |
created, you'll delete the items page.
And modify the app.xaml.cs to make the app
| | 00:53 |
start with the split page.
Then, you'll copy the standard 130 item
| | 00:57 |
template, and the standard 80 item
template out of the standard styles.
| | 01:02 |
And put them into the local page resources.
| | 01:04 |
And make some adjustments to them.
So that the app looks more like Plain Ol'
| | 01:07 |
Notes.
And not just the standard app that comes
| | 01:09 |
out of the template.
And finally you'll update the
| | 01:12 |
itemDetailXAML so that the fields we
want to have displayed there are
| | 01:16 |
displayed.
And there's also an Edit button,
| | 01:19 |
indicating to the user what they need to
do in order to be able to edit the text in
| | 01:22 |
the note.
This challenge should take you about 15
| | 01:25 |
minutes.
Good luck.
| | 01:26 |
I'll see you on the other side.
| | 01:28 |
| | Collapse this transcript |
| Solution: Building the Windows Store UX, part one| 00:00 |
All right.
The solution for part one begins with
| | 00:02 |
creating a new project using one of the
standard templates from Visual Studio.
| | 00:06 |
So we'll fire up new project.
And we're going to pick the split app
| | 00:09 |
template.
Now if you notice over here on the right
| | 00:12 |
hand side the way the split app is
designed to work is it starts out by
| | 00:14 |
having a set of groups and then shows you
detail for the items in that particular
| | 00:18 |
group.
What we’re going to do is use that
| | 00:21 |
template, we’re going to get rid of the
groups, we’re going to leave the items,
| | 00:24 |
and customize the way that looks and then
in Part 2 we’re going to add the editor
| | 00:27 |
page for editing notes.
So let’s go ahead and select that
| | 00:31 |
split-out template, and then we’re going
to browse to the right spot inside of our
| | 00:34 |
exercise files, in this case Chapter Seven.
| | 00:39 |
And we’re going to call this, plain old,
notes for Windows Store, select OK.
| | 00:47 |
Now if we just run this, just straight out
of the box, we'll see that have the
| | 00:50 |
groups, you click on one of the groups,
you get the various items, and as you
| | 00:53 |
change that, it automatically changes the
item content over here.
| | 00:59 |
So what we want to do is stop this and
start making some changes to the UX, to
| | 01:03 |
the xaml.
But the way we're going to do that to
| | 01:06 |
begin with is we need to get rid of the
items page and start directly at the split
| | 01:09 |
page.
During the UX challenge, we're not
| | 01:12 |
going to go ahead and hook up our data model.
| | 01:14 |
We're going to do that during the code
behind session.
| | 01:16 |
So we're going to continue to use the
default data model that came with the
| | 01:19 |
template.
But the first thing we have to do is to
| | 01:22 |
delete the items page.
(SOUND) Then go into the app.xaml.cs.
| | 01:29 |
And down here, on line 80, this is how a
Windows Store app determines what's the
| | 01:34 |
first page.
It's all done in code.
| | 01:37 |
Which is different than the way a Windows
Phone app determines what's the start
| | 01:39 |
page.
So what we want to do here is to say split
| | 01:42 |
page And I happen to know that the name of
the first group is called group dash one
| | 01:46 |
from looking at the data model.
If you want to dig in to the default data
| | 01:50 |
model here, you can go ahead and look in
the sample data source.
| | 01:54 |
But if we do that and now run the app, you
can see we start at the item's page.
| | 01:59 |
And there's one more thing we need to do
down here at line 370.
| | 02:03 |
Because we deleted item sub-title from our
item template.
| | 02:06 |
We can't use that in one of these object
animations in order to be able to handle
| | 02:10 |
when we move from full view to split view.
So, we'll come over here and we'll just
| | 02:15 |
delete that item right there, lines 370
through 374, and now, let's hit F5 and
| | 02:19 |
give it a whirl.
looks better except that this is really
| | 02:23 |
huge and we still have some images and
things over here so once again let's stop
| | 02:27 |
we're almost done with this.
We'll come back up to the top we're here
| | 02:32 |
line 16 I think it was so the grid height
here probably only need about 60 pixels
| | 02:35 |
for each one of those.
So we'll change that and let's take a look
| | 02:40 |
at that item detail over on the right hand side.
| | 02:43 |
That doesn't have a template but it is
down here.
| | 02:45 |
Inside of the data grid for this
particular page.
| | 02:48 |
So there's our item list view, and inside
the item list view, there's a scroll
| | 02:52 |
viewer marked item detail, and inside
there there's a item, and again it's got
| | 02:56 |
an image, we don't need the image.
Get rid of that image.
| | 03:02 |
For item title we're going to leave the
binding to say title.
| | 03:05 |
And for item subtitle, we don't need that
any longer.
| | 03:09 |
And we'll still have the item content,
almost there, let's run this that looks
| | 03:12 |
much better doesn't now?
Now The only thing that's missing is some
| | 03:16 |
way of being able to edit this text over
here, so let's add an edit button.
| | 03:20 |
Once again, back to our XAML, and there's
a number of things built into the Segoe UI
| | 03:25 |
symbol font that you can use in your apps.
All kinds of icons that make it very easy
| | 03:31 |
so that you don't have to actually create
custom icons for a lot of things, and in
| | 03:35 |
our case, we're going to create a button
with a item from that ui sego font that is
| | 03:39 |
our hand with a pencil that indicates.
We can go ahead and edit that.
| | 03:45 |
So now figure out where we're going to add
that button, we're going to go down to our
| | 03:48 |
item detail title panel, and we can see
that that is here at line 127.
| | 03:53 |
And right now it just has this text block,
and we're going to add the edit button in
| | 03:56 |
here.
So we're going to say button, and we
| | 03:58 |
better have a name for it.
Name, we'll call it edit button And this
| | 04:04 |
has a margin of zero, zero, zero, twenty.
Cause we want a little space underneath
| | 04:10 |
it.
And then the content, the content for this
| | 04:12 |
button is going to be a hex code,
ampersand, pound sign, x, two, seven,
| | 04:16 |
zero, d, semicolon.
That is the hand with the edit button,
| | 04:20 |
which you'll see in just a minute.
We're going to set our font size equal to
| | 04:23 |
40.
because we want it to be nice and big for
| | 04:25 |
touch applications.
And we're going to set our font weight to
| | 04:29 |
bold. Alright.
| | 04:32 |
And if we look at the xaml, you can see
that it's gotta regenerate everything.
| | 04:36 |
So we'll go ahead and do a build.
And there's our edit button right there.
| | 04:39 |
Now, let's see what that looks like in
real life.
| | 04:42 |
Run the app one more time. There.
| | 04:44 |
Now we've got plain old notes.
Nice simple item titles.
| | 04:47 |
We could probably even make those a little
smaller if we wanted to.
| | 04:49 |
And then an edit button at the top of each item.
| | 04:51 |
So that we know that, hey, it's easy to
edit by just clicking on the edit button
| | 04:54 |
there. Alright.
| | 04:56 |
That's the solution for part one.
You can go ahead and watch this as many
| | 04:58 |
times as you want to.
But remember, the basic steps of part one
| | 05:01 |
solution are.
Star with a new app using the split app
| | 05:04 |
item template.
Go into app.xaml.
| | 05:07 |
And make the app start with the split
page, instead of starting with the items
| | 05:09 |
page.
And delete the items page.
| | 05:12 |
Then copy and update those standard 130
and standard 80 item templates from
| | 05:15 |
standard styles.
Put them into your XAML.
| | 05:18 |
Then update your list view.
And then your item details to shrink down
| | 05:22 |
the sizes of the items on the left hand
side in the list view.
| | 05:25 |
And delete the images, and add the edit
button on the right hand side.
| | 05:29 |
Now you're going to be ready for the, part
two of the challenge.
| | 05:31 |
Which is to create the editor page, and
hook the two of these together.
| | 05:34 |
| | Collapse this transcript |
| Challenge: Building the Windows Store UX, part two| 00:00 |
Okay, if you got through Challenge Part 1
and got the basic split page setup, now
| | 00:04 |
it's time to add the editor page, so we
have a text editor in order to be able to
| | 00:07 |
edit our notes.
And then we'll do just a little bit in the
| | 00:11 |
code behind to accept the parameter from
the split page to figure out which note we
| | 00:14 |
want to edit so we can pre-load the text
editor box.
| | 00:18 |
And we'll do a little bit of code in the
split page XAML so that we can implement
| | 00:21 |
the Editor button so we can determine
which item is selected in the item list
| | 00:24 |
view and pass it's ID on to the eitopr page.
| | 00:27 |
What you need to do is start with pon4ws
solution part one if you haven't already
| | 00:32 |
created yours.
You can start with the one that we
| | 00:36 |
provided in the exercise files directory.
Copy it into a new directory and rename
| | 00:39 |
the directory to part two so that you're
not overwriting the sample that we gave
| | 00:42 |
you in case you want to go back and do
challenge number one again if you didn't
| | 00:45 |
do it.
Then you're going to go through the
| | 00:48 |
process to add the editor page.
And, you're going to add the text box for
| | 00:52 |
the text editor, and set a few of its properties.
| | 00:55 |
And then you're going to go and look at
the load state method for the editor page,
| | 00:59 |
and get the property of the ID of the
object that's being passed to you.
| | 01:04 |
And, retrieve it so that you can preload
the page title and the text editor box.
| | 01:08 |
Then, we're going to go connect up the
editor button.
| | 01:10 |
So you go back to the SplitPage.xaml.
Double click on the editor button.
| | 01:14 |
And then, inside the edit button underbar
click handler.
| | 01:18 |
You're going to go retrieve the selected
item from the item list view.
| | 01:22 |
And then call frame.navigate to pass that
to the editor page, so the editor page can
| | 01:25 |
retrieve the item.
And fill in the text box and the page
| | 01:29 |
title.
Should take you about ten minutes.
| | 01:31 |
We'll see you on the other side.
| | 01:32 |
| | Collapse this transcript |
| Solution: Building the Windows Store UX, part two| 00:00 |
Okay.
Here's the solution to the challenge part
| | 00:02 |
two.
We're going to add an editor page.
| | 00:05 |
We're going to add our text box.
So we have our text editor.
| | 00:07 |
We're going to add the item we're going to
get passed from the split page, and then
| | 00:11 |
we're going to load some things into the
text editor so we can actually see the
| | 00:14 |
text in the editor.
Once we've got that put together, we're
| | 00:18 |
going to go add the Edit button's click
handler, get the selected item from the
| | 00:21 |
list view, and navigate to the editor page
so that we can see that our connections
| | 00:24 |
are working.
And then our UX will be complete.
| | 00:28 |
Alright.
To begin, what I've done is I've copied
| | 00:30 |
the PON4WS solution part one into a
separate folder called PONWS solution part
| | 00:35 |
two, so that you can have both where I
ended up at part one of the solution and
| | 00:39 |
where I ended up at part two of the solution.
| | 00:44 |
So I just opened up that solution inside
the solution part two folder.
| | 00:49 |
Now I'm going to come down to the project, right-click.
| | 00:51 |
And select Add, and select New Item.
And now I'm looking at the item templates
| | 00:55 |
for Windows Store apps.
And what I want is just a basic page.
| | 00:59 |
But I want my basic page to be called
Editor Page.
| | 01:02 |
(SOUND) So I changed the name and clicked Add.
| | 01:05 |
Now, what this gives us is automatically a
default XAML page for Windows Store app
| | 01:10 |
with a Back button, the title of the app
at the top, and an empty grid in the
| | 01:14 |
middle.
So what we want to do is, let's once
| | 01:19 |
again, let's flip these guys around, get
rid of designer.
| | 01:24 |
Do our magic reformatting, VA so that we
can see all of our attributes on separate
| | 01:27 |
lines.
And let's come down here and see what
| | 01:30 |
we've got.
We basically have the title and Back
| | 01:33 |
button and then nothing.
Then there's all the visual state manager
| | 01:36 |
stuff for the rest of the file.
So we're going to add another item.
| | 01:40 |
If we notice, if you look at the overall
grid for the page, there's 140 unit header
| | 01:45 |
at the top, and then a arbitrarily-sized
section at the bottom.
| | 01:50 |
So this is row 2 of the top-level grid,
and that's what we want to put our text
| | 01:53 |
editor into.
So we're going to come down here, and
| | 01:57 |
we're going to add another grid, so we're
going to say, Grid Grid.Row="1", because
| | 02:02 |
now we're in the second row.
And inside that grid, we're going to put a
| | 02:08 |
text box.
So we'll just say TextBox.
| | 02:11 |
And we'll give it a name and we'll call it TextEditor.
| | 02:13 |
Now let's just go take a look and see what
that looks like.
| | 02:17 |
We've done just that much.
We'll shrink this up here a little bit,
| | 02:21 |
there we go.
And we'll come down here and modify this
| | 02:24 |
to say fit all.
Now that nicely took care of everything
| | 02:28 |
and made it fit everywhere except there's
just some attributes would be really great
| | 02:31 |
if you want to have a touch editor inside
of Windows store app.
| | 02:36 |
So let's go ahead and add a few more
attributes to that text box control.
| | 02:38 |
So we'll collapse the design pane again
and come back here and add a few more
| | 02:41 |
things.
So, it looks best, in my opinion, if we
| | 02:44 |
put the little border around it.
So we'll put a border there of three
| | 02:47 |
pixels.
And we'll make the border black so we can
| | 02:50 |
see it.
Make the font nice and big.
| | 02:53 |
Font size, 24.
That works great, for example, on a
| | 02:56 |
surface font family.
Microsoft recommends using Sego.
| | 03:00 |
UI for user data entry fields.
You can see we automatically got vertical
| | 03:06 |
alignment and horizontal alignment
stretch, but let's go ahead and put those
| | 03:08 |
in anyway because I like to specify them explicitly.
| | 03:14 |
And then, the default background is a
light gray, so I guess we're already set
| | 03:18 |
with that.
Now we need to set text wrapping to wrap,
| | 03:21 |
because we want to multi-line editor.
And we also want to have accepts return
| | 03:25 |
true, because we want this to be able to
be, again, a multi-line editor.
| | 03:29 |
And because we want the text box to span
both columns because there's two columns
| | 03:32 |
there.
We're going to set grid.column span equal
| | 03:37 |
to two. Alright.
| | 03:38 |
Once again, if we bring up the designer,
you don't see much visual difference
| | 03:41 |
except that we have the, the border around
the editor now.
| | 03:45 |
Alright.
That's all we need to do in the XAML.
| | 03:46 |
Let's look at the code behind this
particular page.
| | 03:50 |
To just set up a couple small things.
First off, the title of the page right now
| | 03:54 |
is going to be my application, but we
really want to have it be the title of the
| | 03:58 |
note that we're editing.
So the way we do all that is we start out
| | 04:03 |
by knowing that we're going to be past the
ID of the note to us in the navigation
| | 04:07 |
mechanism.
And where you get to access the
| | 04:11 |
information that's passed from page to
page in a Windows store app is in the load
| | 04:14 |
state method.
So we'll come here to the load state
| | 04:19 |
method, and we'll say string item unique
ID Is equal to string of our navigation
| | 04:24 |
parameter.
We know that the data we're going to get,
| | 04:28 |
because we're still using the sample data
model, is a type sample data item.
| | 04:33 |
So we're going to come up here and create
a variable, sample data item, called our
| | 04:39 |
item.
And that, again that's not defined.
| | 04:43 |
So we control period.
And bring in the data using statement.
| | 04:47 |
Now that we've got it, we can ask the
sample data model, our item is equal to
| | 04:52 |
sample datasource.getitem, and we'll pass
in that item unique ID that we just
| | 04:56 |
retrieved.
And, if we got one.
| | 05:02 |
If it's not no, then we'll set this dot
text editor, dot text, equal to the
| | 05:07 |
content of our item and we are going to do
two things, if it came in not null.
| | 05:15 |
We'll also going to set dot page title,
dot text.
| | 05:18 |
Equal to RIMs.title.
Alright, that's how you pass simple data
| | 05:22 |
between pages in a Windows store app, and
that's how we're going to get the title
| | 05:26 |
and our text in our editor as we come from
the split items page.
| | 05:31 |
So, we'll come back to the zammo for the
split page and we'll come to our edit
| | 05:34 |
button here, and we'll click on it, and
we'll get something called.
| | 05:37 |
>> Edit button underscore click
automatically created for us.
| | 05:40 |
Now that we know that in this page we have
something called item list view.
| | 05:44 |
So we can say SampleDataItem dataItem =
this.itemListView.SelectedItem as a
| | 05:52 |
SampleDataItem.
And we can check if we actually got one.
| | 05:59 |
It's not null.
Then we use frame dot navigate to go to
| | 06:03 |
our new page.
And you do frame navigation in a Windows
| | 06:07 |
Store app based on types, not based on paths.
| | 06:10 |
So you say type of.
Editor page.
| | 06:13 |
And pass it our dataItem.UniqueID.
That's it.
| | 06:16 |
Let's go give it a try.
Here we got our items.
| | 06:22 |
Everything looks good there.
Let's click on item three.
| | 06:24 |
Click the Edit button.
And here we are onto the editor page with
| | 06:27 |
our title set up properly, and our text in
the text editor.
| | 06:31 |
Alright, that's the end of challenge
number two.
| | 06:34 |
And we're all setup now to get on to
adding the rest of the code behind to
| | 06:37 |
complete the functionality of plain old
notes, for Windows Store.
| | 06:41 |
| | Collapse this transcript |
|
|
8. Creating the Code BehindCreating the code behind the class| 00:00 |
Alright, we're in the home stretch.
This chapter we're going to complete,
| | 00:03 |
Plain Ol' Notes for Windows Phone, and
then Plain Ol' Notes for Windows Store.
| | 00:07 |
So before we dig into what it is we're
going to do to complete the apps.
| | 00:11 |
Let's review where we are with the
existing state of our solutions.
| | 00:15 |
Which you'll find in the Chapter Two
exercise files.
| | 00:18 |
Both of which are going to be labeled start.
| | 00:20 |
First, we're going to take a look at Plan
Ol Notes for Windows Phone and review
| | 00:23 |
where we are.
We have our view model with our note and
| | 00:26 |
our notes.
We have our main page and we have our
| | 00:30 |
editor page.
Let's take a look at our main page.
| | 00:34 |
You can see we have changed the title.
We've got our page name of notes, we've
| | 00:38 |
got our list selector.
Let's swap these around.
| | 00:41 |
Put the designer away for a second.
And take a look at what we have in the
| | 00:44 |
list selector.
We have a binding to items, because we
| | 00:47 |
have a selection changed event handler
call out for.
| | 00:50 |
Even though we don't have any code in it early.
| | 00:52 |
And we have our text block, with our text
wrapping of no wrap, our text trimming of
| | 00:57 |
word ellipses.
And our little pencil button and the end
| | 01:01 |
of the line indicating that we can edit
these notes simply by tapping on the line.
| | 01:06 |
We take a look at our editor page.
In the editor page you can see we have the
| | 01:11 |
app title again, Plain Ol' Notes .
Our page title of editor, and our text box
| | 01:15 |
of that allows us to edit with the
settings, as we talked about previously.
| | 01:21 |
Of AcceptsReturn equal true in order to
make it a multiline text box and text
| | 01:25 |
wrapping equal wrap.
Similarly, to make sure that it's a
| | 01:29 |
complete multi line text box editor.
We don't yet have any code in the code
| | 01:33 |
behind in the editor page.zaml that loads
the node into the text editor or takes it
| | 01:37 |
back out of the text editor when we leave
the page in order to save our dta and so
| | 01:40 |
forth.
That's what we're going to be adding when
| | 01:44 |
we actually connect the data model to the
code behind for this particular page.
| | 01:48 |
Let's take a quick look at the data model,
see our current state of the data model
| | 01:52 |
for our note.
We currently have three properties: our
| | 01:56 |
ID, our note, and our first line.
And we have a NotifyPropertyChanged
| | 02:01 |
handler here.
And as we make any changes to each one of
| | 02:04 |
these items, we call NotifyPropertyChanged
in order to make this an observable item
| | 02:08 |
and connecting it up to the Zaml.
We also have our logic here for dealing
| | 02:13 |
with multiple lines and we have our first
line property that allows us to provide
| | 02:17 |
something that's sufficent for our list
view which is different then when we get
| | 02:20 |
into the editor and we actually want to
get all of the content of the notes.
| | 02:27 |
And if we take a look at our notes model
you can see that we have two properties
| | 02:31 |
items.
And is data loaded?
| | 02:34 |
We talked about those before when we were
building the model.
| | 02:37 |
We also have a next to note number.
Because, in this version of the data
| | 02:40 |
model, we're just using an ID number.
For each note, we have a load data method
| | 02:45 |
to be able to load the data in.
And we have a, create new note.
| | 02:49 |
Which creates the new note for us.
And we have a placeholder for UpdateNotes,
| | 02:53 |
which is where the data's going to get
saved when we implement our persistence.
| | 02:58 |
Now, I intentionally built the data model
very simply here with numbers as IDs and
| | 03:02 |
some of these placeholders just here not
completely filled in.
| | 03:08 |
In order to be able to get you to have a
feel for how to build an item and a
| | 03:11 |
collections part of the data stores and
the view model.
| | 03:15 |
That you could then hook up to the user
experience of both Windows Phone and
| | 03:18 |
Window Store apps.
In the next video, we're going to talk
| | 03:21 |
about how we're going to enhance that data
model to be a bit more production
| | 03:24 |
oriented.
We're actually going to use date time
| | 03:27 |
ticks as the keys.
And we're going to implement the update
| | 03:31 |
and create.
We're also going to implement a remove, so
| | 03:34 |
that you can delete notes.
And we'll get into all that in the next
| | 03:37 |
movie.
But I just wanted to give you a sense of
| | 03:39 |
why we made the data model simple in the beginning.
| | 03:41 |
'Cuz I wanted to show you the connections
between the data model and the XAML.
| | 03:45 |
Without having to encumber the data model
with every particular thing you'd need for
| | 03:49 |
a production data model. Alright.
| | 03:51 |
That's a quick look at the Windows Phone
version of the app.
| | 03:54 |
Let's take a look at the Windows Store
version of the app.
| | 03:57 |
Where we're starting this chapter.
Here's the Windows store solution as we
| | 04:01 |
have it right now coming into create in
the code behind.
| | 04:04 |
You've completed the challenges of the
previous chapter you've edited the split
| | 04:07 |
page XAML so that it looks like what we want.
| | 04:10 |
You've added the editor page and to both
of these starting states.
| | 04:15 |
For both Windows store and Windows Phone I
brought forward the notes model and notes
| | 04:19 |
model classes.
I made one change to both these solutions
| | 04:22 |
which is that I've changed the namespace
to this pon.viewmodels as opposed to
| | 04:26 |
pon4wp or pon4ws because part of the
reason we're doing this course with both
| | 04:30 |
Windows Phone and Windows store.
Is that we can use this data model
| | 04:37 |
identically in both environments.
Our data model here is very, very simple
| | 04:41 |
but a data model for a more sophisticated
application might be quite a bit more
| | 04:44 |
complex.
And one of the things you can share
| | 04:46 |
between Windows Phone, and Windows Store
is the data model.
| | 04:49 |
So, I wanted to demonstrate that, and
that's why we did this.
| | 04:52 |
In fact, in a more sophisticated
environment you might actually make the
| | 04:55 |
date model live in a separate project.
and actually physically share the same
| | 04:59 |
project between the two apps.
Here's our solution for plain old notes
| | 05:03 |
for Windows Story and the state where we
are right now.
| | 05:07 |
We've edited the split page designer to
show our smaller items, to add our edit
| | 05:11 |
button, and to make the item title the
only piece that shows up here.
| | 05:17 |
We've added our editor page to add our
text editor.
| | 05:21 |
And I've brought forward into both the
Windows Phone, starting solution for this
| | 05:25 |
chapter, As well as the Windows Store
starting solution for this chapter.
| | 05:29 |
Our note model, and notes model class.
I've made one change.
| | 05:33 |
Which is that I've changed the name space.
So that it's the same name space between
| | 05:37 |
both versions of the apps.
Because really, the reason that we're
| | 05:41 |
doing this course for both Windows Store
and Windows Phone at the same time.
| | 05:45 |
Is that this is really the crux of the way
you can share things between Windows Phone
| | 05:49 |
and Windows Store, the models, as well as
persistence, which we'll see in the third
| | 05:52 |
video in this chapter.
We're all set with Windows Store, next up
| | 05:57 |
we'll talk about enhancing the data model,
and since the data model's exactly the
| | 06:00 |
same for both Windows Phone and Windows Store.
| | 06:03 |
We'll just enhance one version of the data
model, and then we'll copy it and paste it
| | 06:06 |
into the other model and make sure that
everything still runs.
| | 06:10 |
You ready?
Let's go turn this data model into a very
| | 06:13 |
interesting little thing into a production
data model that does all we need it to do.
| | 06:18 |
| | Collapse this transcript |
| Enhancing the data model| 00:00 |
As I mentioned in the introductory video
for this chapter we're going to enhance
| | 00:03 |
the data model to make it more production worthy.
| | 00:06 |
And we're going to do that in two phases.
First, we're going to enhance the semantic
| | 00:09 |
set up of the data model.
And then we're going to implement
| | 00:11 |
persistence in a way that works on both
Windows Store and Windows Phone.
| | 00:15 |
So, first let's change the semantic set up
of the data model.
| | 00:18 |
Let's go into NoteModel.
And what we're going to do is we're
| | 00:21 |
going to add an additional property.
Because what we want to be able to do in
| | 00:25 |
the Windows store version of the app is
show the date that the note was modified
| | 00:28 |
by.
And eventually, we're going to want to
| | 00:31 |
actually be able to sort the notes in
modified order so that the most recently
| | 00:34 |
modified one shows up at the top.
And lets do that by simply coming down
| | 00:40 |
here and copying the id field.
Copy and Paste, and we'll change this to
| | 00:46 |
modDate, and we'll replace it in all the
right places, here, here, here.
| | 00:54 |
We'll change the property to ModifiedDate
and we'll change the modified property
| | 00:59 |
change to id to ModifiedDate.
So one more thing we need to do.
| | 01:05 |
When we first put this together, the
standard Windows format is carriage
| | 01:08 |
returns and line feeds for everything.
But it turns out that when you serialize
| | 01:12 |
things and deserialize them back and forth
to disk.
| | 01:16 |
The underlying WinRT that's present in
both Windows Phone and Windows Store does
| | 01:19 |
funny things and changes everything to
just line feeds.
| | 01:23 |
So what we need to do is we need to change
this line 62 here and split our notes
| | 01:27 |
based on the line feed character only.
Because what we're going to end up with on
| | 01:32 |
disc is just line feeds.
And then we don't need to do the replace
| | 01:36 |
here.
We just grab the first line.
| | 01:38 |
Finally, what if there are no lines at all
in our note?
| | 01:42 |
Well, why don't we change the first line
here to say empty.
| | 01:49 |
So that in our list selector we don't have
empty list view boxes.
| | 01:52 |
It will have the word empty in there, so
that you'll know that, oh.
| | 01:56 |
That's my note and it's empty.
If I click on that one then I can change
| | 01:58 |
the content.
That's all the changes we need to make to
| | 02:01 |
note model for an individual item.
Now, let's go to make the changes we need
| | 02:05 |
to make to notes model.
Remember, NotesModel right now has a
| | 02:09 |
collection of items.
A Load Method, a update method which is
| | 02:13 |
empty A CreateNewNote, and the
CreateNewNote currently is based on having
| | 02:17 |
id be a numeric string.
But what we want to do is we want to make
| | 02:22 |
that a little bit more sophisticated.
So what we're going to do is, start with,
| | 02:28 |
is we're going to get rid of nextNoteNumber.
| | 02:31 |
because we're going to make the id field
contain the date time ticks, which is like
| | 02:35 |
the number of milliseconds since the
beginning of time as our string.
| | 02:40 |
Because effectively the number of times
the user can hit the add button, will
| | 02:43 |
guarantee that at least one tick has happened.
| | 02:46 |
So that, each new note is time stamped
that way and that's effectively a unique
| | 02:50 |
id.
So, what we do to that is we get rid of
| | 02:53 |
the new note number.
We'll come down here to our create new
| | 02:57 |
note and instead of setting ID equal to nextNoteNumber.ToString.
| | 03:02 |
We'll now set id equal to DateTime.Now.Ticks.ToString.
| | 03:09 |
And we get rid of this next note number,
incrementation because we don't need to do
| | 03:12 |
that anymore.
And then there's one more thing we need to
| | 03:16 |
do which is down here in our load data
notice that these ID numbers no longer
| | 03:19 |
need to be just 1, 2, 3, 4.
Let's think about what would happen if we
| | 03:25 |
just changed all these to say, DateTime.Now.Ticks.ToString.
| | 03:30 |
Do you think that would work to do that
with all of them?
| | 03:35 |
Well, it turns out that the code here can
run faster than a millisecond, and so when
| | 03:38 |
you run this, either on Windows phone or
Windows Store.
| | 03:42 |
They all end up with the same number.
So what we do for the extra ones that
| | 03:47 |
we're adding is we'll say DateTime.Now+1,
and DateTime.Now.Ticks+2.
| | 03:56 |
Those are so we get unique numbers as we
put these things together.
| | 03:59 |
All right, that's adding a more production
style ID to each one of our notes.
| | 04:04 |
Now we've done that, let's go and add a
couple of things that make it useful for
| | 04:08 |
being able to transition between our list
and our editor pages.
| | 04:13 |
Back up here, before CreateNote, we're
going to add a couple of real simple
| | 04:17 |
methods called GetItem and RemoveNote.
Public, NoteModel, GetItem, and we'll pass
| | 04:23 |
in the ID.
Now that's a very simple little link
| | 04:27 |
query.
NoteModel result equals this.Items.Where
| | 04:33 |
and f.ID is equal to the ID we got passed
in and first or default.
| | 04:44 |
And then we'll return that, that's it, now
we can go get an individual item by ID.
| | 04:48 |
So that when somebody makes a selection in
one of our list views, we can go retrieve
| | 04:52 |
our item, get the ID number out of it.
And actually get the real item in order to
| | 04:56 |
be able to pass it on to the editor page.
And then, let's implement the
| | 05:00 |
corresponding method to create new note,
public void remove note.
| | 05:05 |
And we'll pass in the actual note.
And the reason we do that as opposed to
| | 05:11 |
passing in the ID is it turns out its very
easy to say this.Items.Remove,
| | 05:16 |
noteToRemove.
And then of course because we want this to
| | 05:21 |
be permanent we're going to say update
notes even though it doesn't do anything
| | 05:24 |
yet.
When we finally implement persistence we
| | 05:27 |
of course want that written back to the disc.
| | 05:29 |
And because we made changes notify
property changed that we changed items.
| | 05:38 |
That's the changes we needed to make to
the noteModel and notesModel to bring it
| | 05:41 |
up to more production status.
I'm actually going to open up the other
| | 05:46 |
solution that is in the Windows Store App,
and Copy and Paste these.
| | 05:50 |
As I mentioned before, in a more
production environment, you'd actually
| | 05:53 |
probably have a project that had your view
models in it.
| | 05:56 |
And you would share them as the actual
project, as opposed to sharing just
| | 05:59 |
exactly the same copy of the source code.
Now that we've made the changes to
| | 06:03 |
noteModel and notesModel.
Let's make sure that these saved changes
| | 06:06 |
end up in the Windows Store version of the app.
| | 06:08 |
As I mentioned before, in a more
production environment, you probably have
| | 06:11 |
a single project with the view models in it.
| | 06:14 |
And share it between the two apps, as
opposed to having two separate copies.
| | 06:18 |
But in our case, we have two separate
copies, so let's Save this.
| | 06:21 |
Let's come back to our Exercise Files
folder, inside Chapter 08, video number
| | 06:25 |
02.
And I'm going to take the final notes for
| | 06:29 |
Windows Store, the starting spot, and I'm
going to Copy it and Paste it and Rename
| | 06:35 |
it UpdatedDataModel.
And now I'm going to open up that
| | 06:41 |
solution.
I'll open up the DataModel, and there's
| | 06:44 |
our noteModel and notesModel, so I'll just
come back here, and I'll go to the Windows
| | 06:47 |
Phone version.
I'll open up note model, Select All, and
| | 06:52 |
Copy.
And I'll come back here to visual studio,
| | 06:55 |
and I'll go to the Windows Store version,
open up note model, select all and paste.
| | 07:01 |
Then we'll verify that we have the right
one because we have our change where we
| | 07:04 |
added first line equal empty and we added
the ModifiedDate property.
| | 07:08 |
Save that, close it, we'll come back to
the Windows Phone version, close
| | 07:12 |
NotesModel.
Open up NotesModel, again, Select All and
| | 07:16 |
Copy, come back to the Windows Store
version, open up NotesModel, Select All,
| | 07:20 |
and Paste.
Let's make sure this builds in both cases.
| | 07:25 |
Alright, builds in Windows Store, builds
in Windows Phone.
| | 07:31 |
Alright, we're done with updating the DataModel.
| | 07:34 |
The next thing we're going to do is
implement persistence, so that the items
| | 07:37 |
that we have in our data model can be
saved out to the disk storage.
| | 07:41 |
Or the virtual disk storage in the case of
a Windows Phone.
| | 07:44 |
And the loaded back layer, which will be
just what we need to be implementing add
| | 07:47 |
and also delete so that our notes are
actually persistent.
| | 07:51 |
So let's move on to adding persistence to
both of these projects.
| | 07:57 |
| | Collapse this transcript |
| Implementing persistence| 00:00 |
Step two in the home stretch of completing
these two apps is making our data
| | 00:03 |
persistent.
Beginning with Windows Phone 8 and Windows
| | 00:07 |
8, there's a common OS core called WinRT
or Windows Run Time.
| | 00:11 |
And it provides a storage API known as the
Windows.Storage namespace.
| | 00:16 |
If you were building this app only for
Windows phone.
| | 00:19 |
There's a Windows Phone 7 legacy name
space named isolated storage, which you
| | 00:22 |
could use, which is synchronous and very
simple to use.
| | 00:26 |
However, if you want to be forward
looking, or as we're doing here, you
| | 00:29 |
want to share persistence across both
platforms simultaneously.
| | 00:33 |
You'll want to use the Windows.Storage
namespace because as we can see The
| | 00:36 |
minimum supported client for the
Windows.Storage namespace is both Windows
| | 00:40 |
8 and Windows Phone 8.
The Windows.Storage namespace has a number
| | 00:45 |
of unique concepts.
It has the concepts of folders, it has the
| | 00:48 |
concept of an app local folder, meaning
data that's stored with your app, that's
| | 00:52 |
uninstalled when your app is uninstalled.
And also, for Windows store apps, there's
| | 00:58 |
something called Known Folders, so that
you can get access to things like the
| | 01:01 |
Documents folder, or the Music folder, or
the Pictures folder, or Videos folder
| | 01:05 |
without having to get into the details of
file paths in the underlying Windows
| | 01:08 |
operating system.
On Windows Phone, we're only going to use
| | 01:13 |
the local storage folder.
And in that same way, we're going to use
| | 01:16 |
the local storage folder in the Windows
Store app as well.
| | 01:20 |
One of the other more sophisticated things
that makes it a little tricky to use the
| | 01:23 |
Windows.Storage namespace is that all of
the API's are asynchronous, meaning that
| | 01:27 |
you create async methods, and you have to
use the async and await keywords in order
| | 01:31 |
to be able to access those APIs.
And so something as simple as get me the
| | 01:37 |
file, delete it if it exists, and write a
new one involves a whole bunch of steps.
| | 01:43 |
Handling exceptions, dealing with
situations especially if you want to put
| | 01:46 |
things in subfolders, the difference
between creating a folder, and finding out
| | 01:50 |
if it exists, and retrieving it if it
already exists.
| | 01:54 |
Got a little bit messy, codewise.
So I wrote a library called IO recipes.
| | 01:58 |
And I provided it free on GitHub.
The way to find IO recipes is just go to
| | 02:02 |
GitHub.com, come to Search or type a
command, and type in IO recipes.
| | 02:08 |
And there you'll find Dream Timer's IO recipes.
| | 02:13 |
This makes it simple, so that you can do
things, like.
| | 02:16 |
Get the folder, get access to the file and
read a string from the data file, all with
| | 02:20 |
three simple lines of code.
Without having to worry about any of the
| | 02:24 |
tries and catches and asynchs and awaits,
other than using await on the methods
| | 02:27 |
inside IORecipes, which have to be
awaited, as you'll find out when we take a
| | 02:30 |
look at using this stuff in just a moment.
There's detail specifications here in the
| | 02:38 |
GitHub project for all of the APIs inside IORecipes.
| | 02:41 |
Things like CreateFileInFolder,
CreateOrGetFolder, DeleteFileInFolder, and
| | 02:44 |
so forth.
In order to use this in our project we'll
| | 02:48 |
simply download a zip of the file here.
This will have already been done for you
| | 02:56 |
and you'll find this in the Chapter 8
subfolder 03 folder because I'm about to
| | 03:00 |
do it right now.
I'm going to say Save As.
| | 03:03 |
Here we are, Chapter 8 subfolder 03 and
I'm going to Save the zip file from GitHub
| | 03:07 |
there.
Then I'm going to Open that folder and I'm
| | 03:11 |
going to Extract all the files from GitHub.
| | 03:14 |
And inside IORecipes-master is the one
file IORecipes.cs.
| | 03:19 |
Well I'm going to copy this, close this
window, and go into the Persistence_End
| | 03:23 |
because that's where I'm going to actually
be implementing.
| | 03:26 |
For you, you're going to either start with
Persistence_Start and copy it to make your
| | 03:30 |
own end folder, or just edit directly in Persistence_Start.
| | 03:34 |
But you'll do the same thing I'm going to
do right now.
| | 03:35 |
I'm going to open up this folder.
Open up the source code folder right click
| | 03:40 |
here and say paste.
That puts iOS beast in that folder.
| | 03:43 |
That was for Windows phone and I'm
going to do the same thing for Windows
| | 03:46 |
store right click here and say paste.
Alright now let's go take a look at using
| | 03:52 |
iOS beast to implement the update notes
which persists our data back to the disc.
| | 03:58 |
And modified load data so that we have the
ability to load data from the disk if it
| | 04:01 |
exists or we could pre-populate it with
our three nodes as we've been doing all
| | 04:05 |
along.
So let's open up the windows phone
| | 04:08 |
persistence solution and now you can see
we don't have (UNKNOWN) in the project so
| | 04:12 |
I'm going to select the project Come up
here and select Show all files and there's
| | 04:16 |
IO recipes I'll just right click on it and
say Include in project.
| | 04:23 |
Now let's go to the view models.
Let's go back here and turn off Show all
| | 04:28 |
files because we just want to look at note
model and notes model for persistence,
| | 04:31 |
there's nothing we need to do to note model.
| | 04:34 |
Note model is completely persistent
independent, it just has our properties.
| | 04:38 |
First line I.D.
modify date and note so we don't need to
| | 04:42 |
make any changes to that.
But let's make changes to notes model.
| | 04:46 |
And you can see that in notes model
remember we put in update notes but it
| | 04:49 |
doesn't have anything in it.
First thing we will do is let's write the
| | 04:54 |
data to the disc and then we'll modify
load data to read back.
| | 04:58 |
Implement UpdateNotes.
First thing we need to do is get access to
| | 05:01 |
the folder where our notes are going to be stored.
| | 05:03 |
So we go StorageFolder appFolder = IORecipes.getAppStorageFolder.
| | 05:14 |
Now as always we're going to get some red
squiggly lines here.
| | 05:17 |
If I go up to StorageFolder, Cmd+., and
select using Windows.Storage.
| | 05:22 |
Conversely to using the command Period,
you could also do a right-click on this
| | 05:25 |
and select Resolve and it will show you
the same list of things if you want to use
| | 05:29 |
the mouse.
So it will bring in
| | 05:32 |
DreamTimeStudioZ.IORecipes. Alright.
| | 05:34 |
Now, we have our folder.
In order to write our file, we need to
| | 05:38 |
delete any existing file.
So to do that, we say IORecipes
| | 05:43 |
.deletefileinfolder pass in our folder and
the name of our file.
| | 05:50 |
Now let's see what happens oops we've got
a green squiggly line.
| | 05:55 |
We hover over that and it says warning
because this call was not awaited.
| | 06:00 |
Execution of the current method continues
before the call is completed.
| | 06:03 |
That means it will just bleep right over
this and run it in a background thread.
| | 06:06 |
That's not what we want.
We want our file operations to be
| | 06:09 |
apparently synchronous and the way you get
apparent synchornicity is by using the a
| | 06:13 |
sync and await keywords.
So we'll add what it suggests.
| | 06:17 |
We'll add an await keyword and now we'll
see what happens.
| | 06:19 |
(UNKNOWN) so now we got a red squiggly line.
| | 06:21 |
So what does that tell us?
It tells us You can't use the await
| | 06:24 |
operator inside a non async method.
Consider working this method with async
| | 06:28 |
and changing its return type to task.
And in fact that's exactly what we're
| | 06:32 |
going to do.
We're going to mark it as asynch, and
| | 06:34 |
change its return type to task.
All right, now we finally get rid of all
| | 06:39 |
our squiggly lines and we have.
Access to the folder and we've deleted any
| | 06:43 |
previously existing versions of our data file.
| | 06:46 |
Before we can write our data to the data
file, we need to convert our (UNKNOWN)
| | 06:50 |
collection of note model items into XML to
store in the file, so we'll say string
| | 06:55 |
itemsAsXML, and we've included in IORecipes.
| | 07:00 |
A SerializeToString method, we can simply
pass in the collection.
| | 07:07 |
And this works for any .net collection
where all of the members are public so
| | 07:10 |
that it can be serialized and
deserialized, the standard.net
| | 07:13 |
serialization logic.
Now that we have our items in XML string,
| | 07:17 |
there's two more methods we need to use
inside IR recipes.
| | 07:20 |
The first, is we need to create the file.
And we'll call that data file.
| | 07:27 |
And we'll use IO recipes dot create file
in folder.
| | 07:30 |
And we'll pass in our app folder.
And again the name.
| | 07:33 |
Good programming practice says hey, we're
using the same name twice.
| | 07:38 |
We should put it as a constant at the top.
We'll do that in just a minute.
| | 07:41 |
But once again we've got our favorite red
under-bar squiggly here.
| | 07:44 |
What does that mean?
We look at it and it says, Can't
| | 07:46 |
implicitly convert this type.
That's kind of a bogus error message
| | 07:50 |
because in fact it works just great.
It's just that the fact that this message
| | 07:55 |
says convert the type
system.threading.tasks.task a Windows
| | 07:58 |
Storage File, storage file.
What's really going on here is we're
| | 08:02 |
missing the Await keyword here.
That converts it from the task back into a
| | 08:07 |
file and we said we were going to put this
in a constant so let's do that.
| | 08:11 |
We'll say data file name and we'll come
back up to the top of our method here and
| | 08:17 |
we'll say private const string datafilename.
| | 08:25 |
All right, now it's only going to be in
one place.
| | 08:28 |
We're going to copy this, and we're
going to replace this with that.
| | 08:32 |
Because, of course, we're going to also
use that same name down inside load data
| | 08:34 |
when we load the data from the file.
And now we have our file, but we haven't
| | 08:38 |
actually written the data to it yet.
So one more call, await.
| | 08:42 |
IORecipes.WriteStringtoFile.
And we pass in our file and our string.
| | 08:49 |
Alright.
That's everything we need to do to update,
| | 08:52 |
update notes.
Because we made update notes async.
| | 08:57 |
There might be someplace that we call that
we might need to wait for it, right?
| | 09:00 |
Well, it seems to me we did that in
RemoveNote, didn't we?
| | 09:02 |
So once again, we need to make RemoveNote async.
| | 09:05 |
Task.
And put the await keyword in there.
| | 09:12 |
Now, later, when we actually call remove
note, we'll have to await it.
| | 09:15 |
But that allows us to remove the note from
our list, and persist it back to the data
| | 09:18 |
store.
Now we've written our data to the disc.
| | 09:22 |
Let's update load data to read it back.
Here we are at load data.
| | 09:26 |
Right now, it simply creates these three items.
| | 09:28 |
There's song lyrics, plan camping trip for
April and Shakespeare quote.
| | 09:32 |
What we really want to do is we really
want to see if there's a data file out
| | 09:35 |
there, we want to load it in and use the
file instead of using the predefined
| | 09:38 |
items.
So here we go again.
| | 09:41 |
StorageFolder.
We'll get the IORecipes dot.
| | 09:48 |
Get app storage folder, and we'll get a
reference to the data file.
| | 09:52 |
Storage file, get file in folder, and that
needs to be awaited.
| | 10:05 |
And once again.
That means now load data has to be async
| | 10:10 |
Task.
Alright there we go now we're good now we
| | 10:14 |
say if data file is not equal null meaning
that we actually got a reference to a data
| | 10:19 |
file object then we'll load it.
Else we'll come down here.
| | 10:26 |
And pre-initialize it.
So now we know we have a file.
| | 10:29 |
Let's see if we've already loaded it from this.
| | 10:31 |
'Cuz we don't need to load it over and
over again.
| | 10:33 |
So we'll see, if not, isDataLoaded, will
load it from disk.
| | 10:38 |
So we get the string from the file. (SOUND).
| | 10:40 |
And we'll say, await.
IO recipes.readstringfromfile.
| | 10:49 |
And we'll pass in data file as our argument.
| | 10:54 |
Now that we've got the data from the file.
We need to create the items collection.
| | 10:57 |
This.items.
And we've provided a method for that, IO
| | 11:01 |
recipes.
.serializefromstring now you notice that
| | 11:04 |
this doesn't have to be awaited because
its an inherently synchronous method
| | 11:09 |
because it doesn't do any IO but we'll
make it observable collection of note
| | 11:14 |
model and we'll pass in.
Items as XML.
| | 11:21 |
There we go.
We've got our data loaded.
| | 11:23 |
Let's do the same thing inside the pre-initialization.
| | 11:26 |
We'll say, if not, is data loaded.
And we'll come down and put the closing
| | 11:33 |
brace, after that.
And if the data hasn't been loaded, let's
| | 11:37 |
initialize the items collection since we
need to be adding it to it.
| | 11:40 |
this.Items equals new
ObservableCollectionofNoteModel and then
| | 11:41 |
we add our items.
And finally, because we may do this more
| | 11:46 |
than once, we also need to do a
NotifyPropertyChanged On items.
| | 11:56 |
And that's it.
We've even blended persistence with build.
| | 12:00 |
Make sure it builds. Okay.
| | 12:01 |
So now, in our code whenever we create
something new, our data will be written
| | 12:05 |
back to disk.
And when we come in to the app and load
| | 12:08 |
the data.
If it exists on disk, we'll be reading it
| | 12:11 |
back.
And just as we did before, what we did was
| | 12:13 |
implement this into the Windows Phone solution.
| | 12:16 |
So let's copy the whole notes model.
Here, let's go to our folders here, 03.
| | 12:22 |
And I'm going to open up Windows Store
persistence n.
| | 12:25 |
Because that's where I'm going to be working.
| | 12:27 |
And put this in similarly you could either
be working in Persistent Start in the
| | 12:30 |
example files or you can like I did have
copied it and put it into a separate
| | 12:33 |
solution so that you can maintain the
original pristine version of Persistent
| | 12:36 |
Start even if you have to start over again.
| | 12:42 |
Do the same two steps we did.
We're going to Show All Files, include
| | 12:46 |
IORecipes in our solution, turn off Show
All Files.
| | 12:50 |
going to close that, and now we're
going to open up NotesModel.
| | 12:54 |
And we're going to Select All and Paste.
And we can verify that we got the right
| | 12:58 |
thing.
Because we now have the using for
| | 13:01 |
Dreamtime studio recipes so that we can
get IO recipes.
| | 13:04 |
Alright, that's what's necessary to
implement persistence.
| | 13:07 |
Now let's move on to hooking up this nice,
preresistible data model to our code, and
| | 13:11 |
then we'll also implement add and delete
notes and we'll be done with building
| | 13:15 |
plano notes for Windows phone and Windows storm.
| | 13:20 |
Alright, I just remembered there's one
more step.
| | 13:22 |
Since we're going to be creating the model
and using low data, we can come down here
| | 13:26 |
to the constructor, and we can get rid of
this initialization of the note model.
| | 13:31 |
So, I want to make sure that if we come
back in and create an instance of this, we
| | 13:34 |
don't want to create an empty list and end
up having it overwrite data that we've
| | 13:37 |
read from disk.
So, we'll delete that there, we'll come
| | 13:41 |
back over to the Windows phone version,
and do the same thing.
| | 13:47 |
And now we're done.
We've implemented persistence, and now we
| | 13:50 |
can save our data and load it back.
Let's move on now to completing the
| | 13:54 |
windows phone version and then the windows
store version of the app.
| | 13:58 |
And hooking up the add button and the
delete button.
| | 14:01 |
At completing plain old notes for Windows
phone and Windows store.
| | 14:04 |
| | Collapse this transcript |
| Exploring the code behind for Windows Phone| 00:00 |
The last walk-through before the last two
challenges of the course.
| | 00:03 |
So first, I want to show what it is you
need to do to update the current state of
| | 00:07 |
the Windows phone app to reach the
completed state of the Windows phone app.
| | 00:13 |
In which we're basically going to be
hooking up the full data model to the UX
| | 00:16 |
and we're also going to be implementing
the add button, and the delete
| | 00:19 |
functionality.
First of all, let's go to the
| | 00:24 |
MainPage.xaml.cs and see I've made the
OnMavigatedTo method async.
| | 00:31 |
That's so that we can use the await method
here on the LoadData.
| | 00:34 |
Also we've updated the selection change in
a couple of different ways.
| | 00:39 |
One we've kept track of what the
lastSelectedNote was and that's because we
| | 00:44 |
need to do that For our Delete
functionality, and we've passed the ID of
| | 00:48 |
the selected item as our query parameter,
so the to our editor page.
| | 00:54 |
Similarly, our Add button now goes and use
the ViewModel.CreateNewNote, and calls
| | 00:59 |
Navigate to the editor page.
Now, you'll notice that CreateNewNote
| | 01:04 |
doesn't have an await.
That's because we don't actually save it
| | 01:07 |
until we leave the editor page.
'Cuz there's no point in saving an empty
| | 01:11 |
note, and updating the persistence model.
Because, if, from some reason or other,
| | 01:15 |
the app crashed in the middle of that.
You wouldn't have the data anyway.
| | 01:19 |
But you would have the data to say, you
got a phone call.
| | 01:22 |
Because the on navigated from method would
be called editor page when the phone call
| | 01:26 |
came in.
You may remember that when we put together
| | 01:29 |
the.
Long list selector.
| | 01:32 |
We had a tapped method.
Now we've changed the body of that to call
| | 01:34 |
the selection changed method.
And the reason for that is because, by
| | 01:39 |
calling this here, we get the side effect
of this.
| | 01:43 |
Of being able to get the last selected item.
| | 01:46 |
So that when the user calls delete, we're
going to put some delete zammle into out
| | 01:50 |
long list selector, so that it calls this
method when the user taps and holds.
| | 01:55 |
In order to implement this, we're going to
be using something from the XNA framework,
| | 01:59 |
the gamer services, to give us a message
box, that also has an AsyncCallback on the
| | 02:03 |
message box action.
So that we can, down here, in the on
| | 02:08 |
message box action, look to see if we got
an action, if we did, and it's the yes
| | 02:12 |
button, then we can use the dispatcher
that begin invoke to call our delete part
| | 02:16 |
two.
To get us back on the ui thread, and then
| | 02:21 |
we use our api to remove the note, our
last selected note, and that's the reason
| | 02:24 |
why we had to keep that last selected
note, and then we call.
| | 02:30 |
Update Notes.
Notice we made this method async as well
| | 02:32 |
so that we could await the results of
Update Notes.
| | 02:35 |
One of the things that's true about
Windows Phone is that all the controls you
| | 02:39 |
need for a real production app aren't in
the tool kit you get from Microsoft
| | 02:43 |
directly, so what you need to do in order
to be able to use the long tab and delete
| | 02:47 |
functionality is you have to add a thing
called the Windows Phone Toolkit.
| | 02:55 |
And the way you get that is you come up to
the Tools menu, go to the Library Package
| | 02:59 |
Manager, go to Manage NewGet Packages for Solution.
| | 03:03 |
Now this is installed packages, let's just
go online, and we're going to newget.org,
| | 03:08 |
and we'll search for Windows Phone Toolkit.
| | 03:12 |
And you can see here's Windows Phone Toolkit.
| | 03:15 |
Because this is our final solution I’ve
already included it.
| | 03:17 |
What you’ll need to do is to click on
Windows Phone Tool Kit, and there’ll be an
| | 03:21 |
install button, and you can install it
into your solution.
| | 03:25 |
That gives you the ability to handle that
long tab delete functionality.
| | 03:30 |
The updates to the examples you’ll be
needing to do in the challenge.
| | 03:35 |
R, swap these again and get rid of that.
You're going to be needing to add this
| | 03:39 |
line here, that reference the tool kit.
XMLNS colon toolkit.
| | 03:44 |
Let me scroll this back over here and it
needs to say, the name space is Microsoft
| | 03:48 |
dot phone dot control and the assembly, is
Microsoft dot phone dot controls dot
| | 03:52 |
toolkit.
We referenced this in one place only.
| | 03:58 |
Down here, inside of our long list
selector, we've added these lines.
| | 04:05 |
This says we're adding a context menu.
And the context menu is the delete note
| | 04:09 |
menu.
And by implementing the long tap, and
| | 04:12 |
selecting the context menu, it allows us
to call our delete selected click handler
| | 04:16 |
that we saw back there in the code behind.
Similarly, if we go down to our app bar at
| | 04:22 |
the bottom, we're going to change the name
of the click handler from application bar
| | 04:26 |
button icon under bar click to add button click.
| | 04:31 |
And fill in code.
So we can take a look here.
| | 04:37 |
That calls create new note.
And then navigates to the editor.
| | 04:41 |
Alright, that's all the changes we're
going to need to make it to the
| | 04:43 |
MainPage.xaml to finish the app.
Now we need to make a couple of minor
| | 04:48 |
changes to the editor page.
The EditorPage.xaml doesn't need to change
| | 04:52 |
but the editor page code behind does
because our current code behind doesn't
| | 04:55 |
have anything other than the constructor.
What we're going to be adding to this is
| | 05:01 |
two methods on navigated two and on
navigated from.
| | 05:05 |
These are both implemented by the base
class and we're going to override them in
| | 05:08 |
the on navigate two override.
We're going to go get the ID of the note
| | 05:12 |
that we want to edit from the query string
and assuming that we're able to get it
| | 05:15 |
form the query string.
We're going to use that get item method we
| | 05:19 |
added to our data model, to go get the
note we want to edit.
| | 05:23 |
And then we're going to set the text of
the editor text box to the content of our
| | 05:26 |
note.
On the on navigated from, which is what
| | 05:28 |
happens when the user hits the back
button, we're coming back to our list.
| | 05:33 |
We're going to go get the data from the
text box.
| | 05:36 |
We're going to replace all the carriage
returns with line feeds.
| | 05:39 |
And as I mentioned briefly before it's
kind of funky when you save it to a file
| | 05:43 |
all the carriage returns get turned into
line feeds.
| | 05:47 |
But, when you type into the box sometimes
you end up with carriage returns and line
| | 05:50 |
feeds both in the box.
Which if handled appropriately by the
| | 05:54 |
editor but you don't want to save them in
the file because then you can't split the
| | 05:57 |
file into lines very easily.
So we replace all of the, carry the terms
| | 06:01 |
by line feeds.
Especially because the editor, when he
| | 06:05 |
puts them in, only puts in the returns and
not the line feeds.
| | 06:08 |
So this dot replaced at the end of the statement.
| | 06:10 |
Sort of unifies all of that data so that
all we ever end up with in our data store
| | 06:14 |
is lines separated by a single line feed character.
| | 06:19 |
So we update the content of our note here
on line forty.
| | 06:22 |
And then, we call, update notes on our
data model in order to write it to disc.
| | 06:27 |
Remember, we had to make this method async
because we're going to call await here.
| | 06:31 |
That's all the changes we need to make to
complete the Windows Phone version of
| | 06:35 |
plain old Notes.
Your challenge is going to be to go
| | 06:38 |
through these steps, and the challenge
will remind you what the steps are that
| | 06:41 |
you need to do, and you can look at my
solution and see how I finished
| | 06:43 |
implementing the Windows Phone app.
In the next video, I'm going to go through
| | 06:49 |
the changes necessary to complete the
Windows Store version of the app, which is
| | 06:52 |
a very similar set of changes.
But there's some subtle nuances based on
| | 06:57 |
the fact that the user experience
mechanism, while it's still XAML, is
| | 07:00 |
different than that on Windows' Phone.
| | 07:03 |
| | Collapse this transcript |
| Exploring the code behind for Windows Store| 00:00 |
Let's talk about the last steps we have to
go through to make the Windows store
| | 00:03 |
version of Plain Ol' Notes functional.
One of the things we have to do is add the
| | 00:07 |
ability to add a note and delete a note.
In Windows store apps that's done with an
| | 00:12 |
app bar.
So we'll open splitpage.XAML I'll go to
| | 00:15 |
the button and you'll see that we've added
a page.bottom app bar.
| | 00:19 |
Now the XAML we have here says we've got a
single app bar.
| | 00:23 |
With a stacked panel, and two buttons
inside of it.
| | 00:26 |
And our two buttons use styles that we're
going to define at the top of our XAML.
| | 00:30 |
That are derived, once again, from the
standard styles that are inside
| | 00:33 |
standardstyles,xmal.
If we open up standard styles.xaml, and do
| | 00:37 |
a search for button style.
You'll see that we find a whole bunch of
| | 00:41 |
different button styles.
Primary, secondary button style, radio
| | 00:46 |
button styles, and then here we have a
whole bunch of standard at bar button
| | 00:49 |
styles.
And you can either uncomment at these or
| | 00:53 |
copy them and put them directly into your
XML file.
| | 00:56 |
The key thing that they do is that they
use SegoUI symbol To pull out individual
| | 01:01 |
characters.
The Windows utility CharMap is something
| | 01:05 |
that could really be your friend when
you're looking for custom icons to use in
| | 01:09 |
an appbar.
These are all specific character codes
| | 01:12 |
that are inside that character map for
Segoe UI Symbol.
| | 01:17 |
In our case, we created two,
AddAppBarButtonStyle and
| | 01:20 |
DeleteAppBarButtonStyle.
And up here at the top, we've added those
| | 01:24 |
two styles here, AddAppBarButtonStyle, and
it's just a copy of one of those from
| | 01:28 |
standard styles with the proper name, AddAppBarButtonStyle.
| | 01:33 |
And the proper content in our case, the
character code E109.
| | 01:37 |
And similarly the delete app bar button
style, is just like the add app bar button
| | 01:42 |
style, and used the character code E106.
Remember the style does not specify the
| | 01:47 |
text, it shows up underneath the icon.
That gets done down here.
| | 01:52 |
And it's done not with this tag, that's
tag's important, but it's actually done,
| | 01:56 |
remember the text for setting the button
is not done in the button bar in the
| | 02:00 |
bottom.
It's done here by using this automation
| | 02:04 |
property.
To set the name property of the buttons so
| | 02:08 |
this is where add and delete get sent.
If you want to change the names on those
| | 02:12 |
buttons then change this particular
automation property not the text at the
| | 02:15 |
button at the bottom.
What's down at the app bar here at the
| | 02:18 |
bottom is connecting it up to the event handlers.
| | 02:21 |
So let's go ahead and go take a look at
those event handlers.
| | 02:25 |
Navigate to event handler.
And you can see that for New Note we use
| | 02:28 |
our app view model, create New Note, put
some text into it, and then navigate off
| | 02:31 |
to the editor.
For delete, notice we can take click
| | 02:36 |
handlers and make them async.
We did that for this one, because of
| | 02:39 |
course we're going to end up calling
Update notes once we've deleted it.
| | 02:43 |
Though what we first do is, go and get the
data item that's been selected.
| | 02:47 |
Assuming we have one, we're going to use a
WinRT built in functionality called
| | 02:51 |
message dialogue.
Something you've seen in many apps, for
| | 02:54 |
example when you unpin an item from start
or you uninstall an app is a little box
| | 02:58 |
called a fly-out.
It turns out that fly outs are not part of
| | 03:03 |
the C-Sharp EPI directly from Microsoft.
There is a tool kit from Callisto, which
| | 03:08 |
does implement fly outs and gives you
great control by giving you user controls
| | 03:13 |
to do.
Everything you might want to do in a fly
| | 03:16 |
out but in our case all we really need is
to ask yes or no do you want to delete the
| | 03:19 |
note.
So we're going to use message dialogue and
| | 03:22 |
its kind of a little bit upside down the
way you have to create it but you do it
| | 03:24 |
this way.
You create a message dialogue instance
| | 03:28 |
then you create a command handler to
handle the user tapping on one of the
| | 03:31 |
buttons and in our case we said if button I.D.
| | 03:35 |
is tapped we're going to go through and
call remove note from our API for the data
| | 03:38 |
model.
Then we're going to await the update notes
| | 03:42 |
call and then we're going to go grab the
items and reset them into our view model
| | 03:45 |
to cause the display to update.
Then once you have a command handler put
| | 03:50 |
together then you put together your
commands and add those commands to the
| | 03:53 |
dialog setup a default command index and
display the dialog.
| | 03:58 |
And when the user taps one of those
commands this command handler's called
| | 04:01 |
asynchronously.
In order to be able to execute the command
| | 04:04 |
that the user has selected. Alright.
| | 04:06 |
One of the other things we did here, in
addition to implementing add and delete.
| | 04:10 |
Is, inside the page state management, we
updated load state and save state.
| | 04:15 |
First of all, we made load state async.
Then we called IsDataLoaded.
| | 04:19 |
And if the data hasn't been loaded, we
call await LoadData to go get the data
| | 04:22 |
from our file.
And then we initialize the default view
| | 04:26 |
model items key inside that dictionary
with the items from our view model.
| | 04:31 |
We talked already about this code here,
the page state code, we didn't change any
| | 04:33 |
of that.
It's just exactly what it was before.
| | 04:38 |
We talked before about this page state
code, that hasn't changed.
| | 04:42 |
In save state, however, we've gone through
this code and remove every reference to
| | 04:45 |
sample data model.
So, for example, this selected item needs
| | 04:49 |
to be a note model now,not a sample data item.
| | 04:52 |
Our sample data item.
That's all the changes we needed to make
| | 04:54 |
to the split page.
Now let's take a look at the editor page.
| | 04:59 |
In the editor page, I'll flip this up again.
| | 05:02 |
Get rid of this.
We didn't have to make any changes to the
| | 05:05 |
Zamo.
Zamo's just the standard zamo with our
| | 05:07 |
editor control in the middle of it.
Over the code, we made a few changes to.
| | 05:12 |
It used to just be initialize component in
the editor and a load state.
| | 05:16 |
Well we've changed load state to go get
the item and get the text out of the item
| | 05:19 |
and set the TextEditor in our page title
that's now reading the modify date field
| | 05:23 |
of our note model in order to set the page
title for this age.
| | 05:28 |
Similarly we updated the save state method
we made it async so that we could go get
| | 05:31 |
the text from the TextEditor and we could
call update notes.
| | 05:36 |
Now it's interesting to note that one of
the attributes of Windows store versus
| | 05:39 |
Windows Phone is that we didn't have any
trouble with inconsistent carriage returns
| | 05:43 |
in line feeds.
So we didn't have to do the replace of the
| | 05:46 |
returns with the line feeds at this point
in our code.
| | 05:49 |
The TextEditor in the XAML has specific
call outs for two events, TextChanged and
| | 05:54 |
SelectionChanged.
We have dummy methods for those here
| | 05:59 |
inside the code.
The reason I put those in there was to
| | 06:01 |
remind you that in some situations, if
your user's going to spend a long time
| | 06:04 |
doing editing, you may want to catch some
of those events.
| | 06:08 |
And every tenth time or every so often,
save the data if the user's editing.
| | 06:14 |
So that if his machine crashes, all the
data that he's been creating hasn't been
| | 06:17 |
lost.
And so you can do that inside TextChanged
| | 06:20 |
to see if it's been awhile since you had TextChanged.
| | 06:24 |
And if that's the case, then update the data.
| | 06:26 |
And you might also then want to even have
a separate background timer that says,
| | 06:29 |
hey.
Has it been more than x period of time?
| | 06:33 |
Say, more than 30 seconds or a minute?
And the user text is different than the
| | 06:36 |
text I have stored.
So I still want to update my data model.
| | 06:40 |
That's beyond the scope of this course
but, the reason I left those particular
| | 06:42 |
items in there was so that you could think
about that particular problem when you get
| | 06:45 |
into the business of actually making real
production apps.
| | 06:49 |
That's all the changes we need to make to
finish off Plain Ol' Notes for Windows
| | 06:52 |
Store.
So now, pick one or both of the
| | 06:54 |
challenges.
I'll review the changes you need to make
| | 06:57 |
in each challenge and then I'll go through
and create the solution to solve the
| | 07:00 |
challenge so you can follow along.
| | 07:03 |
| | Collapse this transcript |
| Challenge: Building the code behind for the Windows Phone app| 00:00 |
Alright.
Now, it's your turn.
| | 00:01 |
To complete the code behind for the
windows phone version of Plain Ol' Notes,
| | 00:05 |
you can start with the solution we put in
the Chapter 8, subfolder labeled 06 for
| | 00:08 |
Video 6.
There's also a copy of it in the subfolder
| | 00:12 |
07, which I started with when I was doing
the solution.
| | 00:16 |
They're exactly the same.
But I'd start with the one in 06, make a
| | 00:18 |
copy of it, rename it and, and then, begin
following through the process of doing
| | 00:21 |
your challenge.
But what is your challenge?
| | 00:24 |
Well, your challenge is to hook up the
data model.
| | 00:28 |
Your challenge is to implement the add and
delete functionality and there's a lot of
| | 00:31 |
steps in here, so take it slow.
And finally to implement load and save on
| | 00:35 |
editor page, which is actually pretty quick.
| | 00:38 |
If you get stuck, follow the solution
along, step by step.
| | 00:42 |
The whole challenge should take you
probaby 20 minutes, and this is the most
| | 00:44 |
complex challenge in this course.
And I know you can do it, but as I said,
| | 00:48 |
if you get stuck, follow the solution.
It goes through things step by step and
| | 00:52 |
then pause when you've fixed what you need
to figure out, and carry on yourself.
| | 00:56 |
I'll see you on the other side and you can
watch what my solution here in Chapter 8,
| | 00:59 |
movie number 7.
| | 01:01 |
| | Collapse this transcript |
| Solution: Building the code behind for the Windows Phone app| 00:00 |
Before I show you the solution to the
challenge you just had to complete plain
| | 00:03 |
note for Windows phone let's take a look
at the finished app.
| | 00:06 |
Fire it up there's our three simple data pieces.
| | 00:11 |
We can edit our data change it to plan
camping trip for July.
| | 00:15 |
Go back go back in again see that, that
got persisted.
| | 00:19 |
We can add a new note.
(SOUND) And we can also delete notes.
| | 00:23 |
We can edit anything we want.
And so this is hooked up to the data
| | 00:28 |
model, it's got the Add Button
functionality, its got Delete Button if
| | 00:31 |
you click and hold here.
Although, it won't do that if you have the
| | 00:34 |
ad, popped up.
But, you can click and delete notes this
| | 00:37 |
way.
(SOUND) And everything is running.
| | 00:40 |
So now, let's go take a look at how to
make that real.
| | 00:42 |
To begin with, we'll open up the code
behind for the main page.
| | 00:49 |
We're going to take out this supported
orientations thing from when we were
| | 00:52 |
discussing it before so that it will work
in both portrait and landscape.
| | 00:56 |
And we're going to come down to the on
Navigated Tool method.
| | 00:58 |
And you'll see, we've got some green
squiggles here, and it tells us, once
| | 01:01 |
again, because this call is not awaited,
execution continues before the call was
| | 01:05 |
complete.
Since load data is now async, we need to
| | 01:09 |
put async right here to make the
OnNavigated to async.
| | 01:13 |
And we need to put a an await right here
to make sure that we don't carry on til
| | 01:16 |
the data is actually added to storage.
All right, that's item number 1.
| | 01:21 |
Here we are in selection changed.
Now we need to create a data item here.
| | 01:25 |
Private NoteModel, lastSelectedNote for
our deleting functionality.
| | 01:33 |
And then we need to make some changes to
the selection change method.
| | 01:36 |
So first of all we need to say, NoteModel,
selectedItem equals a MainLongListSelector
| | 01:42 |
as note model.
That's fine, we'll use that code right
| | 01:47 |
there.
There now we've got that and we'll set
| | 01:52 |
lastSelectedNote equal to selectedItem so
we can remember what it was.
| | 01:56 |
Now, we need to navigate to the new page.
Well, the new page is no longer details
| | 02:00 |
the new page is now EditorPage.
And the selected item, unlike before, is
| | 02:06 |
now going to be selectedItem.ID.
All right.
| | 02:09 |
And that's all we've gotta do.
And we reset it to make sure we don't have
| | 02:13 |
any selection, and we're good to go.
We wanted to be able to add, right?
| | 02:17 |
So we're going to come back to the XAML.
Flip it, and get rid of the designer.
| | 02:22 |
Go to the bottom.
And we're going to change this to
| | 02:26 |
addButton_Click.
And then we're going to navigate to Event
| | 02:30 |
Handler.
We're going to delete
| | 02:33 |
ApplicationBarButtonIcon_Click.
We had to create that in order to be able
| | 02:37 |
to compile the code before.
But now, we're actually going to put code
| | 02:40 |
inside the add button.
Well we gotta create a new note, right?
| | 02:43 |
So first up noteModel newNote App.ViewModel.CreateNewNote.
| | 02:51 |
And now, we're going to to off to the
service, just like we did before.
| | 02:55 |
So we'll go up here and copy this line,
and all we have to do is change this from
| | 03:01 |
selectedItem.ID to newNote.ID, and we're
all set.
| | 03:08 |
Okay, so that gives us that functionality.
Now, what we need to do is to add the
| | 03:12 |
logic in here to be able to handle our delete.
| | 03:17 |
Now, we mentioned that we have to add the
tool in here.
| | 03:19 |
So we're going to go up to Tools.
Go to Library Package Manager.
| | 03:23 |
Go to Manage NuGet Packages.
And we're going to search for Windows
| | 03:27 |
Phone Tool Kit. (SOUND).
| | 03:32 |
And there it is, Windows Phone Tool Kit,
and we'll click Install.
| | 03:38 |
We'll install it in our Solution NuGet,
we'll download it and install it and we're
| | 03:40 |
all good.
Now, we can click Close.
| | 03:43 |
Now we can come back to the XAML for our
main page.
| | 03:45 |
Go back to the top and we need to add the
namespace for the tool kit.
| | 03:50 |
It will come here after shell and we'll
say xmlns:toolkit equals
| | 03:58 |
clr-namespace:Microsoft.Phone.Controls;assembly
equal Microsoft.Phone.Controls.Toolkit.
| | 04:10 |
And it tells us it couldn't find it.
That's because we haven't done a build
| | 04:14 |
yet.
So let's do a build.
| | 04:16 |
And we've got an extra character someplace
in our CS file.
| | 04:20 |
try it again.
Our build succeeded.
| | 04:22 |
And our blue line's gone and our XAML
because we now have a reference to the
| | 04:25 |
tool kit.
At least we should have one.
| | 04:27 |
Let's go ahead and try to reference it,
and see what happens.
| | 04:30 |
What we need to do here is, we need to
come down here into our long list
| | 04:32 |
selector.
This now said, this is invalid XAML.
| | 04:34 |
Which means we must have done something in
terms of adding this name space.
| | 04:41 |
Clr-namespace:Microsoft.Phone.Controls.
Resources, toolkit.content, here's our
| | 04:48 |
toolkit content.
Here's our packages.config that says we
| | 04:52 |
have the thing and here we've got Microsoft.Phone.Controls.Toolkit.
| | 04:57 |
So let's see what did we do wrong?
Microsoft.Phone.Controls.Toolkit, what
| | 05:02 |
else could we have done here?
Let's look at our error list.
| | 05:11 |
Those are all errors in our sample data
which we don't care about.
| | 05:16 |
Let's go ahead and delete the sample data
altogether, because we don't need it
| | 05:21 |
anymore, delete that.
And then we'll make sure, try to build
| | 05:27 |
this again.
Let's do a solution clean, and a solution
| | 05:31 |
rebuild.
I just don't understand why this is
| | 05:33 |
invalid XAML, unless we accidentally typed
something strange into it.
| | 05:39 |
And then, of course you're going to delete
this design data.
| | 05:42 |
I think the right thing to do is to delete
the toolkit line and let's just copy one
| | 05:45 |
of the lines we've already go there.
Shell and then change it change this to
| | 05:50 |
say toolkit and we know that the assembly
is Microsoft.Phone.Controls if we
| | 05:56 |
misspelled something there and its Phone.Controls.Toolkit.
| | 06:04 |
And we'll build that, and that's fine, no
blue lines there, no blue lines there.
| | 06:09 |
Must have typed it wrong, but now that's
the way you can do it.
| | 06:12 |
Just clone the shell line and change the
name space in the assemblies there.
| | 06:17 |
All right, now, in order to use that tool
kit we're going to come down here and
| | 06:20 |
we're going to add our Context Menu item
inside the StackPanel for the long list
| | 06:23 |
selector.
So here's our StackPanel.
| | 06:26 |
And we're going to add the following.
Toolkit, ContextMenuService.ContextMenu.
| | 06:34 |
And inside that, we're going to say Tookit:ContextMenu.
| | 06:38 |
And inside that, we're going to say
Toolkit:MenuItem and Header equals Delete
| | 06:43 |
Note, which is what the user sees.
And our Click is DeleteSelected_Click and
| | 06:51 |
then slash close angle bracket.
All right, that adds this, we should get
| | 06:57 |
one error when we build because we haven't
implemented DeleteSelected.
| | 07:01 |
So now, we'll right-click here, and say
navigate to event handler, and we'll go
| | 07:05 |
take a look at what we need to do put this
code in.
| | 07:08 |
All right, here in DeleteSelected, so what
we're going to do now is we're going to
| | 07:12 |
use the XNA game services guide in order
to get our dialogue.
| | 07:17 |
So we'll say Guide.BeginShowMessageBox.
And our arguments are going to be, quote,
| | 07:24 |
Please confirm.
And, are you sure you want to delete this
| | 07:31 |
note?
And we pass in a string array oops, gotta
| | 07:34 |
have a comma over there.
New string array of Yes and No and then
| | 07:40 |
the next argument is a zero.
And then we want to pass in
| | 07:47 |
MessageBoxIcon.Warning, then finally new
AsyncCallback on MessageBoxAction, and a
| | 07:57 |
null, and close.
Now, in order to make this all happy,
| | 08:04 |
we're going to click here and set Resolve
and add
| | 08:06 |
microsoft.xna.framework.gamerservices.
Everybody's happy except we don't have it
| | 08:11 |
on message box action.
So what we're going to do is we're
| | 08:14 |
going to right-click here.
And we're going to generate this method
| | 08:18 |
stub.
So there's on message box action.
| | 08:21 |
Inside our on message box action, we
want to do the following.
| | 08:25 |
We'll go see if any selected button was clicked.
| | 08:28 |
Guide.endshowmessagebox we'll pass in our
async result see what we get and now we
| | 08:35 |
say switch selected button.
And all we care about here is case 0 and
| | 08:42 |
that we're going to call Deployment.Current.Dispatcher.BeginInvoke.
| | 08:48 |
DeletePart2, which we haven't written yet.
And now we'll have close and a semi-colon.
| | 08:56 |
Cannot convert lambda expression to
system.delegate because it's not a
| | 08:59 |
delegate type because we don't have
DeletePart2 written yet.
| | 09:02 |
That's it.
And then we'll say break.
| | 09:04 |
And then we'll add a default case, a break
there too.
| | 09:08 |
And end the switch statement.
Now, we need to generate method style for
| | 09:12 |
DeletePart2.
Alright, here's DeletePart2, and inside
| | 09:16 |
DeletePart2, we want to actually go delete this.
| | 09:19 |
So we'll say App.ViewModel.
Dot remove note, our last selected note.
| | 09:24 |
And then we'll say await dot map view
model and update notes.
| | 09:31 |
And realize we need to make this guy async.
| | 09:33 |
Let's take a look at the notes model.
I think between the time I did the
| | 09:38 |
original test of this, and the time we
finish this, We actually put the code to
| | 09:42 |
actually do the call to update notes into
RemoveNote, find out, yes we did.
| | 09:48 |
Okay.
So all we have to do here is simply call
| | 09:50 |
Await, Removenotes so we don't have to
call update notes.
| | 09:53 |
All right, there we go.
And of course, we need to make this task.
| | 09:58 |
All right.
So now we've finished implementing Part 2.
| | 10:00 |
And we don't care that this isn't awaited.
Because this is what we're trying to do,
| | 10:04 |
which is to verify this again. Deployment.current.dispathcer.begininvoke.
| | 10:10 |
In paren, goes to Delete Part 2.
We can actually just turn this to void.
| | 10:14 |
Because it has to be void to match the
proper signature for this.
| | 10:17 |
There we go.
Now, we got everything resolved.
| | 10:19 |
All right, let's go back to our challenge
check list and see what else we have to do
| | 10:21 |
for Windows phone.
So I think we've completed the delete
| | 10:24 |
logic.
Now, let's see what else we have to do in
| | 10:26 |
the Windows Phone challenge.
See how we've implemented our add?
| | 10:30 |
We've successfully implemented add, we've
added the Toolkit, and we've implemented
| | 10:33 |
the delete method.
Alright, so that's all the changes we have
| | 10:36 |
to make to the main page.
Let's go on and make the final changes we
| | 10:38 |
have to make to the Editor page to
complete the Windows phone app.
| | 10:42 |
Let's go to the editor page.
We don't have to make any changes to the
| | 10:44 |
XAML.
Let's open up the code for the editor
| | 10:46 |
page.
And notice, all we have is the
| | 10:48 |
InitializeComponent.
We need to have a non-navigated to, and a
| | 10:51 |
non navigated from.
So the easiest way to begin is to start up
| | 10:55 |
by saying protected, override, on
navigated to, and let it fill out the
| | 11:00 |
basic method.
And again, protected.
| | 11:04 |
Override on navigated from and let it fill
out the base.
| | 11:09 |
Now, what we want to do is we know that
we're being passed a note ID, so string
| | 11:13 |
noteID and let's go see if we can get it
from the query string.
| | 11:18 |
If NavigationContext, here we go, NavigationContext.QueryString.TryGetValue.
| | 11:26 |
Looking for the ID value here, and we're
going to call out noteID.
| | 11:33 |
Now, if we got one, our note equals, what
we need to do is to create a public
| | 11:37 |
variable here so we can keep track of
which note object we have.
| | 11:43 |
So note model, our note.
Now, on navigated to, we set our note
| | 11:48 |
equal to app.ViewModel.get Item, and pass
in the ID.
| | 11:53 |
noteID that we got passed in on the URI.
And finally, editorTextBox.Text =
| | 11:58 |
ourNote.Note.
There, now we got the data into the text
| | 12:01 |
box.
Now, on the way out we're going to need to
| | 12:03 |
be async because we're going to save it.
So we go through the OnNavigatedFrom base
| | 12:12 |
code.
And we're going to say ournote.note equals
| | 12:15 |
editor text box.text.replace, we're
going to replace the return characters
| | 12:20 |
with linefeed characters so that
everything's consistent.
| | 12:26 |
And then we say, await app.viewmodel.
Update notes.
| | 12:32 |
All right.
That's everything we should have to
| | 12:33 |
change.
Let's do a build.
| | 12:35 |
All right, here in editor page, we started
referencing note model and we haven't
| | 12:39 |
added our reference in yet.
So Ctrl+Period.
| | 12:43 |
And bring in our view model, there we go.
Let's make sure everything builds.
| | 12:47 |
There, now we have a successful build.
So just a quick review.
| | 12:51 |
We have added logic to the main page.
XAML to load data in the on navigated to
| | 12:56 |
and made that async and we waited for it.
We added change to the selection change in
| | 13:02 |
order to be able to get to selected item
and navigate to the Editor page.
| | 13:07 |
We added the Add button in order to create
a new note and go to the Selector page.
| | 13:12 |
And we added the whole infrastructure here
for delete, beginning with the show
| | 13:15 |
message box, the on message box action,
the Delete Part 2, which actually removes
| | 13:19 |
the note, which now also saves it back to
the persistent data store.
| | 13:24 |
And finally we went to the editor page and
implemented on navigated two in order to
| | 13:28 |
grab the ID from the query string get the
note and put it into the textbox.
| | 13:33 |
I then implemented on navigated from in
order to get the data from the textbox.
| | 13:38 |
Fix up the return to line feeds.
And update our note.
| | 13:41 |
And then write it back to the persistent
data store.
| | 13:43 |
All right let's go ahead and give it a shot.
| | 13:45 |
Whoops, it looks like maybe our data
initialization isn't quite right here.
| | 13:49 |
Let's go back and take a look.
At our notes model.
| | 13:54 |
we forget the take out the returns in our
raw data.
| | 13:57 |
Just nice little line feeds in there.
Alright, let's give that another whirl.
| | 14:05 |
And that looks better.
All right, let's see what happens when we
| | 14:08 |
click on one of these guys.
Did we get a selected item?
| | 14:11 |
We haven't executed that line of code yet.
All right, let's see if we've got a
| | 14:15 |
selected item here.
We'll step over.
| | 14:16 |
We've got a selected item.
There's our note.
| | 14:18 |
And we're going to use our selected item here.
| | 14:22 |
Let's go ahead and Continue.
We got to the Editor and we didn't get
| | 14:26 |
anything.
All right, let's see what we missed.
| | 14:28 |
What we'll do is we'll simply go back and
we've got an empty string here or we
| | 14:32 |
didn't get a note cause there must be
something wrong with this logic here.
| | 14:39 |
So let's stop and set a break point here
and see what happened.
| | 14:42 |
We select a note, we continue, we end up here.
| | 14:48 |
We do a step over, Oh, and we didn't even
get an ID.
| | 14:51 |
And so the interesting question is why.
Let's go to our immediate window and we'll
| | 14:56 |
say ?NavigationContext.QueryString.
Let's see what it says.
| | 15:02 |
And it says selected item, that's why.
One of the changes we needed to make back
| | 15:06 |
in our code.
In the main page.
| | 15:09 |
Our parameter we want is ID, not selected item.
| | 15:12 |
Selected item was in the standard template.
| | 15:15 |
Let's give that another whirl.
Select one, and we can undo this break
| | 15:20 |
point here.
Select continue, do a step over, now we've
| | 15:25 |
got one.
There's our note, take that break point
| | 15:27 |
away.
And there's out note.
| | 15:31 |
Now we can come in here, click here, use
the page down here to use the hardware
| | 15:34 |
keyboard instead of the editor keyboard.
Type in July since it's long past April,
| | 15:40 |
and hit the Back button.
And when we click on it again, we can see
| | 15:44 |
that it's been persisted.
There we go, planned camping trip for
| | 15:47 |
July.
Well, let's add one.
| | 15:48 |
Click the add button, and put in a note,
this is our new note, hit the back button,
| | 15:54 |
and there it is.
Our Plain Ol' Notes has added a new note.
| | 15:59 |
We can click on Edit it, we can click on
any of the other ones, and edit those, and
| | 16:03 |
we're good to go.
All right.
| | 16:05 |
And last but not least, let's try our
delete functionality.
| | 16:09 |
We can look at our notes, and then let's
see, we decide to try to delete this one.
| | 16:13 |
Hold down the button 'til it says Delete
Note, we select Delete Note, select Yes.
| | 16:19 |
Whoa, what happened?
We deleted the wrong one.
| | 16:20 |
Well, it turns out the way we're keeping
track of the last selected note is wrong.
| | 16:24 |
It turns out that the menu item on the
long list selector actually tells us which
| | 16:28 |
one we need.
So let's go ahead and stop this.
| | 16:33 |
Come back up here to our List Selection Changed.
| | 16:36 |
We can get rid of this line,
lastSelectedNote = selectedItem.
| | 16:38 |
This is sort of a weird inconsistency with
Windows Phone and it's partly because this
| | 16:43 |
Windows Phone toolkit is not part of the
built-in SDK.
| | 16:48 |
So what we need to do is to say
lastSelectedNote, which we're going to use
| | 16:51 |
in the further sections of DeleteSelected.
Is equal to sender as MenuItem, because
| | 16:57 |
that's what we get here in the sender
item, .DataContext.
| | 17:01 |
And that DataContext is a NoteModel, so
now that's the note that we actually
| | 17:06 |
want to delete.
So, let's give it another whirl.
| | 17:10 |
Let's add a couple more notes.
And then let's go ahead and look at this
| | 17:24 |
one that's good now let's delete b.
Hold down, select Delete note, we say Yes,
| | 17:30 |
and poof, b goes away.
So we've got the right one being selected
| | 17:34 |
when we have the long list selectors, long
hold, being used to tell us when it's time
| | 17:37 |
to delete, which brings up that context
menu item.
| | 17:41 |
And that completes Plain Ol' Notes for
Windows Phone.
| | 17:44 |
| | Collapse this transcript |
| Challenge: Building the code behind for the Windows Store app| 00:00 |
Alright.
You've reached the last challenge of this
| | 00:02 |
course.
Finishing up the code behind for the
| | 00:04 |
Windows Store app.
You'll find in the Exercise Files, in
| | 00:08 |
Chapter 8, Video 8, a folder containing
the starting point for your solution.
| | 00:14 |
You're going to connect up the data model,
you're going to implement the Add and
| | 00:17 |
Delete buttons and you're going to
implement Load and Save on the EditorPage.
| | 00:21 |
So you can follow along with the previous
movie, where we did the full walk-through
| | 00:24 |
of the things that have to be changed, and
then, go ahead and build your own.
| | 00:28 |
Or you can watch the solution, step by step.
| | 00:31 |
As we add the styles for the Add and
Delete button and then we add the Add and
| | 00:34 |
Delete button.
We finish hooking up the Editor button and
| | 00:38 |
we finish hooking up the Add and Delete
buttons on the main page and then we
| | 00:41 |
implement data loading on the editor page.
We come back and hook up data loading on
| | 00:46 |
the main page and then finally we end up
changing the XAML.
| | 00:51 |
So that it no longer matches the sample
data model but it matches our new note
| | 00:54 |
model and notes model.
Alright, this challenge should take you
| | 00:58 |
roughly about 20 minutes, and we'll see
you on the other side with the solution.
| | 01:01 |
| | Collapse this transcript |
| Solution: Building the code behind for the Windows Store app| 00:00 |
Before I show you my solution to the
challenge let's take a quick look at the
| | 00:02 |
finished running app.
Here we go here's our default data each
| | 00:07 |
one of our items our modify date here our
text here.
| | 00:11 |
When I click on the edit button we can add
new text.
| | 00:14 |
I know that that's not the right next line
there for Shakespeare but it.
| | 00:20 |
Will show us that we can edit the text.
And that the item that we selected remains
| | 00:24 |
selected when we come back.
We'll right click here, 'cuz we don't have
| | 00:27 |
a touch screen in our recording booth.
And we'll click add.
| | 00:31 |
We can add a new note.
And we'll go back, and there you go.
| | 00:36 |
We have a new note.
It has multiple lines.
| | 00:38 |
We can change our camping trip to July,
since it's no longer April, and we're all
| | 00:43 |
set.
Now, maybe it's not good to add our own
| | 00:46 |
notes to the Bard.
Let's delete that one.
| | 00:49 |
We select it, and you can select by either
left-clicking, or tapping if you've got
| | 00:53 |
touch screen, or right-clicking just as well.
| | 00:56 |
We're going to delete the Bard, there.
We're going to right-click and select
| | 00:59 |
Delete.
Notice that our default button is the No
| | 01:01 |
button.
So if I hit the Enter key, it doesn't
| | 01:03 |
actually delete.
But if I come back again and select
| | 01:06 |
Delete, and select Yes, our note goes away
and everything nicely animates.
| | 01:10 |
And now we have the mother note and we can edit.
| | 01:13 |
Alright, that's plain old notes.
Now let's go open up the solution that we
| | 01:16 |
can start with And finish implementing
Plain Ol' Notes for Windows Store.
| | 01:20 |
So, the first thing that we need to do is
we need to add the styles for the app bar
| | 01:24 |
buttons at the bottom so we can have an
add and delete button.
| | 01:28 |
We're going to open up splitpage.xaml once
again we'll swap and put away the
| | 01:32 |
designer, and we'll do a build.
Make sure all of our little blue squiggles
| | 01:38 |
go away.
There we go.
| | 01:39 |
And inside page resources we need to put
some styles for the add app bar button
| | 01:43 |
style and the delete app bar button style.
Where we're going to get the beginnings of
| | 01:48 |
that, is we're going to come over here to
common, open up standard styles And we're
| | 01:53 |
going to say, Find bar button style.
And that's the beginning of the app bar
| | 01:58 |
button style.
But we're going to look for another one.
| | 02:01 |
All right.
Here we go.
| | 02:02 |
Here we go.
Skip back app bar button style.
| | 02:04 |
That would be good enough to give us a
starting point.
| | 02:07 |
We'll just select that style, copy it,
come back to split page.xaml, and add one
| | 02:10 |
in here.
And we're going to name this first one
| | 02:14 |
Add, and we've got our target type and our style.
| | 02:18 |
And we're going to change this value to AddAppBarButton.
| | 02:22 |
We're going to change the name to Add.
And our character's going to be E109,
| | 02:26 |
which is the plus sign.
Then we're going to do another one, and
| | 02:30 |
this is going to be called Delete. AppBarButtonStyle.
| | 02:35 |
You can change the value to DeleteAppBarButton.
| | 02:40 |
Change the name property to delete.
And our button is E106.
| | 02:47 |
Now we have the styles.
Let's go ahead and add the app bar at the
| | 02:50 |
bottom of the page.
And we do that by coming all the way to
| | 02:53 |
the bottom.
I just hit control n to go all the way to
| | 02:56 |
the bottom.
And we're going to put this after the last
| | 02:59 |
grid.
So now we're going to say page dot bottom
| | 03:02 |
app bar.
And inside our bottom app bar we're
| | 03:05 |
going to put an app bar control, and we're
going to say it's name is bottomappbar1.
| | 03:12 |
And it's padding is 10, 0 10 0 just to
make it in proper style.
| | 03:18 |
Now, inside that we're going to put a
stack panel.
| | 03:22 |
Stack panel, orientation equals horizontal
and inside that stack panel we're going to
| | 03:26 |
put buttons.
1 button is going to be called.
| | 03:30 |
The New button.
And inside that we're going to say Style
| | 03:36 |
equal StaticResource and it's going to be
called AddAppBarButtonStyle and we got to
| | 03:41 |
spell it with two t's.
And click Is equal to new note, underbar,
| | 03:47 |
click, we need a click handler for it.
And tag equals new document.
| | 03:54 |
That tag's not actually used for anything,
but we put it in there anyway.
| | 03:57 |
And that's it.
There's one.
| | 04:00 |
And we just clone this to add the other one.
| | 04:01 |
Our buttons can be called.
Delete button.
| | 04:06 |
And our static resource is delete, app bar
button style.
| | 04:11 |
R click is going to be called DeleteNote.
And we'll say Remove Document.
| | 04:18 |
Now, before we even try to run this code,
we can bring back the designer.
| | 04:21 |
And you can find out one thing about the designer.
| | 04:23 |
First of all.
We'll tell the designer to make sure that
| | 04:26 |
it fits everything and then we'll zoom in
a little bit.
| | 04:29 |
One of the things you can see, is that if
your cursor in the XML is inside the
| | 04:33 |
bottom button bar, it shows up.
If your cursor is elsewhere, the button
| | 04:37 |
bar doesn't show up.
But, now let's just zoom in a little bit,
| | 04:41 |
fit selection, now you can see we have a
bottom button bar And it's got an Add
| | 04:44 |
button, and a Delete button.
We're good to go in terms of adding the
| | 04:49 |
code, let's make that go away and let's
Navigate to Event Handler for this one,
| | 04:51 |
and we'll come back to the XAML, and we'll
Navigate to Event Handler for that one.
| | 04:57 |
So, that gives us the code that we need in
order to be able to Fill in the code that
| | 05:00 |
actually implements those.
So let's go ahead and put that new code
| | 05:04 |
in.
New note is going to say note model
| | 05:07 |
because we need one.
Create a new note.
| | 05:10 |
New note equals app dot view model dot
create new note.
| | 05:17 |
you're going to find a few interesting
things here.
| | 05:19 |
One of them is that note model, of course,
isn't defined.
| | 05:21 |
So we'll right click here and say resolve
to Our data model.
| | 05:25 |
But app.ViewModel isn't there.
That's because we need to go the
| | 05:29 |
app.xaml.cs and create the same kind of
thing that we had from the Windows Phone
| | 05:32 |
version.
So I'm going to go to app.xaml.cs.
| | 05:35 |
And I'm going to come down here.
And I'm going to put in the same thing
| | 05:38 |
that I put into the Windows Phone version,
which is.
| | 05:44 |
Private, static, NotesModel, viewModel
equals null, then a public, static,
| | 05:51 |
NotesModel property, called ViewModel with
a capital V.
| | 05:59 |
And it has a getter, which says if the
lower case viewmodel is null, then set the
| | 06:06 |
lowercase viewModel equal to new NotesModel.
| | 06:13 |
And then I'll return lowercase viewModel.
And once again we'll come up here,
| | 06:19 |
Cmd+Period, bring in the namespace we need
for our data model.
| | 06:23 |
And there we go.
Now we'll come over to our split page
| | 06:26 |
XAML.cs and give this another shot here.
We'll do a build.
| | 06:31 |
There now, this says to contain the
definition for view model.
| | 06:34 |
And the reason for that is I typed it wrong.
| | 06:38 |
New model.
Yay, Visual Studio is much happier.
| | 06:41 |
What do we do once we've got a new note?
Well, of course.
| | 06:45 |
We're going to set some text into it.
New note that note and we're going to say
| | 06:55 |
this.frame.navigate to the editor page.
And we're going to pass in our new notes
| | 07:07 |
I.D.
and we're good so when we create a new
| | 07:10 |
note.
Its going to add our new note to the items
| | 07:12 |
array we're going to fill in some text to
it and navigate off to the editor.
| | 07:16 |
Now its time to impleent delete now delete
is quite a bit different in Windows store
| | 07:21 |
than it was in Windows phone.
We can do it all in an entire single
| | 07:25 |
method but first we have to figure out
which one we want to delete.
| | 07:29 |
So, we'll say note model data item equals
this dot items list view dot selected
| | 07:36 |
item, as note model.
And then we'll say if data item not equal
| | 07:43 |
null then we'll go ahead and prepare to do that.
| | 07:47 |
In order to put the confirmation dialogue
up as I mentioned in the Walk through
| | 07:50 |
before we did the challenge.
We're going to use something called
| | 07:54 |
message dialog.
Which is different than the way you might
| | 07:56 |
really want to do it in a production app
which would be just using flyout.
| | 07:59 |
But as I mentioned before, flyout is not
something that is provided in the box by
| | 08:03 |
Microsoft for C sharp developers.
It is provided in the box for Java script
| | 08:07 |
developers for some reason, but not for C
sharp developers.
| | 08:10 |
But there's this great open source tool
kit called Calisto.
| | 08:14 |
Which will allow you to implement flyouts
using custom controls beyond the scope of
| | 08:17 |
this course.
But, I highly recommend you check it out,
| | 08:20 |
because it also has a whole bunch of other
additional things, such as menus you can
| | 08:24 |
attach to app bar buttons that are
completely customizable, and a lot of
| | 08:27 |
other different, great functionality that
is built in to the Callisto tool kit, that
| | 08:30 |
didn't end up in Windows 8.
We got a data item, now we'll create a
| | 08:37 |
message dialogue equals new message dialogue.
| | 08:42 |
And we're passing parameters.
The first one is delete selected note.
| | 08:48 |
And the second is our title confirmation.
Once again it looks like we need a new
| | 08:52 |
name space.
Come back up here.
| | 08:54 |
Control Period.
Windows UI popups, there we go.
| | 08:59 |
Now I've got that.
Now, similarly to what we did in Windows
| | 09:01 |
Phone, we have to create some command
handlers and things and we can do it all
| | 09:04 |
inside this method.
So we're going to create a UI command vote
| | 09:08 |
handler.
We'll call it cmdHandler.
| | 09:12 |
And it is initialized by saying new
UICommandInvokedcmdHandler And we'll say
| | 09:17 |
async, because we need to call our
methods, command.
| | 09:22 |
And what are we going to put into it?
Inside here, we're going to say int
| | 09:28 |
command ID equals, we'll retrieve.
The ID from the command when it gets
| | 09:35 |
invoked.
And we'll say, if the ID that we got is
| | 09:39 |
equal to one.
'Cuz we're going to set it up that way.
| | 09:42 |
Then it's time to do the delete.
And we do the delete by saying
| | 09:46 |
app.viewmodel.RemoveNote, and pass in our
data item.
| | 09:51 |
Then we say await app.ViewModel.
.updatenotes and finally we need to go
| | 09:57 |
retrieve the notes.
This needs to be awaited because we put
| | 10:00 |
the code into remove note to actually do
the update notes so we actuallt don't need
| | 10:04 |
to call update notes here.
So that does everything it removes the
| | 10:10 |
note and updates the note.
But now we need to update our.
| | 10:14 |
Data context dictionary so we say
this.defaultviewmodel items is equal to
| | 10:22 |
app.viewmodel.items and that's it.
Give an extra brace there alright there we
| | 10:30 |
go.
Now we've got a command handler.
| | 10:33 |
Now we need to use it, so we create some commands.
| | 10:35 |
UI command, command one equals new UI
command, yes, you want to delete.
| | 10:43 |
Command handler, that's what we use for a
handler, and an ID of one.
| | 10:48 |
And this should be called command one.
And we're going to create another one like
| | 10:52 |
this.
For Command2, which is No.
| | 10:58 |
And we're going to make a default of two.
And finally, we're going to add those to
| | 11:02 |
the dialog.
So we've got dialog.commands.add,
| | 11:06 |
Command1.dialog.commands.
.add command two.
| | 11:12 |
Now we're going to set the default command
index which is what'll happen if the user
| | 11:15 |
does this and then hits the return key.
Now in the case of a delete command you
| | 11:19 |
don't want it to be the yes button you
want it to be the no button.
| | 11:23 |
So we're going to d.defaultcommandindex=1
yes being the zero index and no being the
| | 11:28 |
second index.
And then finally we'll show our dialog
| | 11:31 |
await. D.showAsync.
| | 11:34 |
Alright, and everything's fine, except
that the DeleteNote click that we got from
| | 11:40 |
saying navigate to event handler is
missing our favorite keyword, async.
| | 11:48 |
So we got async there.
That makes this await work properly.
| | 11:51 |
And that's the implementation of delete.
Let's do a build.
| | 11:54 |
Make sure this builds.
Now we've implemented add, and we've
| | 11:57 |
implemented delete.
Now, let's go make sure that we're loading
| | 12:00 |
the right data into our code.
Come back to the top of the code behind
| | 12:04 |
for this page, and we'll see what's going on.
| | 12:06 |
It's going to be inside the page state management.
| | 12:09 |
it looks like we still got a whole bunch
of sample data source stuff still left
| | 12:12 |
there.
Let's get rid of that stuff and hook up to
| | 12:15 |
our data model.
The way we're going to do that is we're
| | 12:17 |
going to get rid of this.
All this group stuff we'll just delete all
| | 12:22 |
that together.
Now remember we're using file io, so it
| | 12:24 |
has to be async, right?
So we'll make this method async and then
| | 12:29 |
we'll say var notes equals app dot view model.
| | 12:35 |
Which we don't even need that.
We need to say is, if not
| | 12:38 |
app.viewmodel.isdataloaded.
We need to await app.viewmodel.loaddata,
| | 12:42 |
that loads it from disk.
Either way, we want to set this
| | 12:46 |
.defaultviewmodel Subscript items the key
of items to app.viewmodel.items there now
| | 12:54 |
we've got everything hooked up and we know
this page state stuff here is just fine.
| | 13:06 |
Except look there's once again a sample
data source instead of a note model.
| | 13:10 |
And w'ell change that to say note model
and make sure that we've got everything
| | 13:13 |
else right.
Looks like that's correct.
| | 13:17 |
Look we've got a sample data source again.
What do you think we need to put in there,
| | 13:20 |
we need to put in app.viewmodel.
And we have get item just like we had
| | 13:24 |
before.
So, that allows to get the item we want
| | 13:27 |
out of the page state.
I believe we've got everything done inside
| | 13:32 |
splitpage.
(INAUDIBLE) .zs.
| | 13:34 |
nope.
We got another SampleDataItem here.
| | 13:35 |
This needs to be NoteModel.
There we go.
| | 13:37 |
And our EditButton_Click is still the
wrong thing.
| | 13:39 |
This is the final stage of hooking up our
data items here.
| | 13:41 |
Our dataItem is going to be a NoteModel
that we get from the selected item and A
| | 13:49 |
note model doesn't have a unique ID, it
just has an ID.
| | 13:57 |
Alright, there we go.
Now we need to go to the editor, and
| | 13:59 |
finish implementing the code to receive
this data item ID.
| | 14:03 |
And load the data into the text editor.
Let's do a build.
| | 14:07 |
And we must have another place where we're
looking at unique ID.
| | 14:10 |
Yes, over here is save state.
Again, we'll just put this on a new line
| | 14:13 |
so we can see it better.
Because that was associated with the old
| | 14:18 |
date model, we need it to be ID.
Alright, now we're all set.
| | 14:22 |
Now let's go open up the code behind for
the editor page.
| | 14:25 |
And you see what we have right now, is
some load state here, and it uses the
| | 14:29 |
content and title from the previous data model.
| | 14:33 |
So let's go ahead and look and see what we
actually do there.
| | 14:36 |
What we need to do is we get our
navigation parameter.
| | 14:39 |
That's correct.
Except that our sample data source is now
| | 14:43 |
app dot view model.
So our item, at the top of the page here,
| | 14:47 |
instead of being a sample data item,
should be a note model.
| | 14:51 |
You got to bring in our view model
definition there we go and once we've got
| | 14:54 |
our item if its not null we're going to
set text editor.text to ouritem.note and
| | 14:57 |
we're going to set the page title to ouritem.modifydate.
| | 15:01 |
Alright there we go on the exit the
default gives us nothing to do in save
| | 15:09 |
state.
We want to update our file on disk, so
| | 15:14 |
that our data is persisted.
So, we're going to do file IO, we're
| | 15:17 |
going to do async, one more time, and now
we're going to go our item, now we're
| | 15:20 |
going to do our item.Note = this.texteditor.txt.
| | 15:24 |
Now, notice here, because it's Windows
store instead of Windows phone.
| | 15:37 |
We don't have to do the replacement of the
(INAUDIBLE) returns by the line feeds
| | 15:40 |
because the editor always does the right thing.
| | 15:43 |
And finally, the reason we had to be async
is await app dor view model dot update
| | 15:49 |
notes.
All right, here we go.
| | 15:52 |
That's the absolute minimum we need to do.
As we talked about in the walkthrough.
| | 15:56 |
We're going to add a couple more
properties to our text editor to remind us
| | 15:59 |
that we need to do some things later about
saving data while the user's editing.
| | 16:05 |
So here's our editor and let's add a
couple more events, just to remind us to
| | 16:08 |
handle that situation later.
So we're going to add a TextChanged event,
| | 16:14 |
and we'll say.
That and we'll add a selection changed
| | 16:19 |
event and now we'll right click here and
say navigate to event handler.
| | 16:25 |
Go back here, right click here and say
navigate to event handler.
| | 16:29 |
Now we've got the empty event handlers
that we can fill in later to do timed
| | 16:33 |
based saving.
We'll do another build.
| | 16:35 |
That all looks good.
Alright, let's double check the list.
| | 16:40 |
We've connected up to the data source.
We've added Add.
| | 16:42 |
We've added Delete.
We've changed the load state to be in sync
| | 16:46 |
and load the data from our data source.
And we've gone to the editor page and
| | 16:50 |
implemented load state and save state in
order to be able to load our notes from
| | 16:54 |
the note object and save them back to the
disk when we're done.
| | 16:58 |
So drumroll please, let's give it a whirl.
Alright, well we missed hooking up
| | 17:06 |
something.
Let's take a look why, cause we didn't get
| | 17:09 |
our notes.
So what did we do wrong?
| | 17:13 |
Well, we what we did was we didn't finish
connecting up our data model in the
| | 17:16 |
(INAUDIBLE).
We did all the stuff we needed to do in
| | 17:19 |
the code behind.
But our data model in the XAML still talks
| | 17:23 |
about things like title and content.
So we're going to stop here and change the
| | 17:29 |
text block binding for our main data item
template from Title to First Line.
| | 17:38 |
And then we're going to come down here,
change this one to First Line.
| | 17:43 |
And then we're going to come down here to
our implementation of our list view.
| | 17:49 |
It uses our templates, but our item detail
can no longer use content, it needs to use
| | 17:56 |
note.
And our title here, we want to use first
| | 18:00 |
line.
Now, we want to use modified date.
| | 18:05 |
All right, let's give it another whirl.
Hey, look at that.
| | 18:14 |
There's our notes.
Let's click the Editor button.
| | 18:18 |
And we missed something.
Value cannot be null.
| | 18:22 |
We must've missed something when we were
updating the data model.
| | 18:25 |
Let's take one stop here.
Well, when do we set modified date.
| | 18:30 |
Let's just go take a look at all the
references for modified date.
| | 18:34 |
And we see, we're using it here.
We have a property but nobody sets it.
| | 18:38 |
Uh-huh.
Must be back here in note model.cs we've
| | 18:41 |
got a modify date property but we never
set it.
| | 18:45 |
We need to set it every time we set the
value of a note.
| | 18:48 |
So we're simply going to say modify date
equals date time.now.tostring and let's
| | 18:54 |
give it one more try.
There we go.
| | 19:02 |
Now, we've got modified dates.
They're showing up.
| | 19:05 |
We come in here and click the editor button.
| | 19:07 |
There, now our title's the modified date.
We'll change this to say July and hit the
| | 19:11 |
back button.
And there we go, look.
| | 19:14 |
It's July.
If you don't have a touch screen, you
| | 19:17 |
right click, and the app bar pops up.
You just can't right click on top of one
| | 19:20 |
of these things, because that actually
does a selection.
| | 19:23 |
So you right-click someplace else on the
screen, and the app bar pops up.
| | 19:27 |
Similarly, if you have a touch screen, you
can swipe up from the bottom.
| | 19:31 |
And the app bar shows up.
You can also swipe down from the top.
| | 19:35 |
And even though it's a bottom app bar, the
app bar will still show up.
| | 19:38 |
In this case, let's add a new note.
Here we go.
| | 19:41 |
There's our new note.
Well say, this is a very nice note and it
| | 19:45 |
has multiple lines.
Yes, it does.
| | 19:51 |
And we'll go back, and there you can see
there's our first line, this is a very
| | 19:55 |
nice note.
Over here, this is our data.
| | 19:58 |
In fact, let's stop here.
And stop using the simulator and switch
| | 20:02 |
back to using the full screen so you can
see this in more detail.
| | 20:05 |
Instead of simulator we'll use local machine.
| | 20:10 |
Remember, the simulator is just a view
under the local machine.
| | 20:14 |
So, there we go.
This is still our very nice note with our
| | 20:17 |
data and your Shakespeare And you can add
something to Shakespeare, say it's mine.
| | 20:24 |
And you notice when we came back, because
of the page state management, this
| | 20:28 |
particular note was still selected.
And for the final test, let's see how
| | 20:33 |
delete works.
We select an item, planned camping trip
| | 20:36 |
for July.
We click Delete and we get a confirmation
| | 20:39 |
dialogue here, delete selected note.
Notice that item number one, a zero based
| | 20:44 |
array of items here, is selected so if we
hit Enter, our note is not deleted.
| | 20:50 |
Try it again, select Delete, this time
we'll select Yes, and the note goes away
| | 20:54 |
and everything animates properly.
And our note is deleted.
| | 20:59 |
Alright, victory is ours.
We can declare that Plain Ol' Notes for
| | 21:02 |
Windows Store is running.
This isn't quite as complicated as the
| | 21:05 |
completion of, Plain Ol' Notes for Windows Phone.
| | 21:09 |
But again, if you have any troubles, walk
through the solution step by step and
| | 21:12 |
pause once you've figured out whats wrong,
and carry on and implement the rest of
| | 21:15 |
your challenge until you get it right.
Congratulations on doing all the
| | 21:20 |
challenges in this course.
You've learned a lot in terms of building
| | 21:23 |
apps for Windows Phone, and for Windows Store.
| | 21:26 |
You've learned where there are
commonality, and where there are
| | 21:28 |
differences.
And you've learned about Windows storage
| | 21:31 |
name spaces, asynchronous methods.
And how to share data between Windows
| | 21:35 |
Phone and Windows Store in common data
models.
| | 21:38 |
| | Collapse this transcript |
|
|
9. Creating AssetsSharing assets between iOS, Android, and Windows| 00:00 |
We've done a lot of talking about how to
build plain old notes for Windows Phone
| | 00:03 |
and Windows Store and what's common
between Windows Phone and Windows Store.
| | 00:07 |
Let's just talk briefly about what's
involved in manipulating graphics and
| | 00:10 |
sharing them between iOS, Android, and Windows.
| | 00:14 |
Since all three platforms use PNG, or
portable network graphics files, pretty
| | 00:18 |
much you can share everything that you've
got in one platform with another.
| | 00:23 |
The specific things you need to know about
the Windows platform have to do with how
| | 00:26 |
to construct icons and splash screens.
Now the good news is, there's a really
| | 00:31 |
great tool, called the Windows market
place, or Windows marketplace/store icon
| | 00:34 |
maker.
And it's available in source code form on
| | 00:37 |
get hub.
So you just need to download this, it's a
| | 00:40 |
visual studio solution, and then press F5
and run it.
| | 00:43 |
And when you run it, it looks like this.
You go ahead and open your icon image, for
| | 00:47 |
example our logo here.
And you'll see that it automatically
| | 00:50 |
creates all the right size tiles for
Windows Phone and Windows 8 and Windows
| | 00:54 |
Store.
I'm just going to create one more folder
| | 00:57 |
name here.
I'm going to call it Course Demo.
| | 01:00 |
Then I'm going to click Save Icons.
And you'll see that little thing slides
| | 01:03 |
down the bottom there.
And if we come back to our Assets folder.
| | 01:07 |
You know see that there's 3 folders
entitled Course Demo WP7 Icons for Windows
| | 01:12 |
Phone 7 and Course Demo WP8 Icons.
And the way you use those, let's go to our
| | 01:17 |
solution for PlainO Notes for Windows 7.
And I will switch back to the assets
| | 01:23 |
folder and open up the WP8 icons from the
logo WP8 icons.
| | 01:28 |
And you simply select these like this and
drag them right in here, into the Tiles
| | 01:31 |
directory.
And in case of the application icon, you
| | 01:33 |
simply drag it right on top of the
application icon.
| | 01:37 |
For Windows Store, we'll switch over to
the Plain Ol' Notes for Windows.
| | 01:41 |
Got it running in the simulator right now,
we'll stop that and switch back to our
| | 01:44 |
assets.
And go into the logos for Win8.
| | 01:48 |
Now, you can simply select all of these
and drag them right here into the Assets
| | 01:51 |
directory.
Now, those of you with a clever eye will
| | 01:54 |
notice that when you first created your
directory with the Blid app template,
| | 01:58 |
there were files in here for Logo.png,
smalllogo.png, splashgreendot.png, and
| | 02:03 |
storelogo.png.
Because this tool creates the logos at the
| | 02:08 |
various scale sizes, you need to go
through in the assests directory and
| | 02:12 |
delete those items that do not have the
dot scale, dash number.
| | 02:18 |
because it will confuse the Package at manifest.
| | 02:21 |
If you have those here, you'll see your
100% sizes will have an empty spot here
| | 02:25 |
with a red x because it doesn't know which
one of those to use.
| | 02:31 |
Whether it should use logo.png for example
versus logo.scale-100.png.
| | 02:37 |
So simply delete the ones that were
provided by the Visual Studio template,
| | 02:40 |
and you'll be good to go.
And when you do that, this is what it
| | 02:43 |
looks like.
One more time, back to the assets
| | 02:45 |
directory.
We've also created a splash screen for the
| | 02:47 |
Windows store app by simply putting the
logo on a dark blue background.
| | 02:52 |
And so what happens now.
When you run this on the simulator, you'll
| | 02:55 |
see a nice splash screen there.
And we close the app.
| | 03:00 |
And go back to the desktop, you'll see we
have a nice icon for plain old notes,
| | 03:04 |
that's for Windows store or Windows Phone.
We'll go ahead and run this in the
| | 03:10 |
emulator.
And there's plain old notes, and when we
| | 03:13 |
come back to here and go down here to look
in the list of applications You'll see we
| | 03:17 |
have our nice app icon.
And if we click and hold and pin to start.
| | 03:23 |
We've got our large icon we can hold again
and shrink.
| | 03:26 |
And we've got our small icon.
We've got all the things that a
| | 03:29 |
professional Windows Phone app has. Alright.
| | 03:33 |
That's a short discussion of sharing
assets between iOS Android in Windows.
| | 03:36 |
And understanding the preparation of
Windows specific assets.
| | 03:40 |
| | Collapse this transcript |
|
|
ConclusionNext steps| 00:00 |
Congratulations, you made it to the end of
the course.
| | 00:03 |
Here's some suggestions for next steps you
can take now that you've completed
| | 00:06 |
Building a Note-Taking App for Windows
Phone and Windows Store.
| | 00:11 |
There's additional courses here in the
online training library which can help you
| | 00:14 |
advance your skills in building Windows
Phone apps and building Windows Store
| | 00:17 |
apps.
There's the Windows Phone SDK Essential
| | 00:21 |
Training, a course that I did called
Fundamentals of Software Version Control
| | 00:25 |
if you're not familiar with how to use Git
or Mercurial or Perforce or TFS, the
| | 00:28 |
Building Windows Store Apps Essential
Training and the Distributing Windows
| | 00:32 |
Phone Apps through the Windows Phone Store.
| | 00:37 |
For both of these apps, I'd highly suggest
that you build them out, make sure that
| | 00:41 |
you're signed up as a developer for the
Windows Store.
| | 00:45 |
Ship a Beta version, even if only to
yourself, so you can go through the entire
| | 00:48 |
process of putting an app through the
store mechanism.
| | 00:52 |
The only thing that won't do is run you
through the final Windows Store
| | 00:56 |
certification mechanism that Microsoft does.
| | 00:59 |
It will allow you to discover all of the
screenshots, and the text, and the keyword
| | 01:03 |
requirements, and various business
decisions that you need to make along the
| | 01:06 |
way before you're ready to ship your app.
And it's much better to discover those up
| | 01:12 |
front rather than on the day your code is
already to go and you're ready to ship,
| | 01:15 |
only to find out you've got two days worth
of additional prep to do.
| | 01:20 |
For both these apps, you might want to
modify the data model.
| | 01:22 |
Of course, you'd only have to do this once
since they're shared.
| | 01:25 |
To sort the notes by the modified date,
you might also want to add, share by
| | 01:28 |
email, so that you can share an individual note.
| | 01:32 |
For the Windows Store app, you might
modify it.
| | 01:34 |
Instead of using the app Local Storage to
use the Roaming Profile so that the data
| | 01:38 |
gets updated automatically if you have 2
different Windows Store devices, your
| | 01:41 |
notes will be shared automatically by
Microsoft across your different devices.
| | 01:47 |
For the Windows Phone app, you might
want to add the ability to add an image
| | 01:50 |
either from the camera library or from the
camera for each note.
| | 01:55 |
So, for example, if you were keeping track
of your expenses for a trip, you could
| | 01:58 |
take a picture of each receipt as you went
along the way, and that it's for building
| | 02:01 |
a note taking app from windows phone and
windows store.
| | 02:06 |
Alright, and that's it for Building a
Note-Taking App for Windows Phone and
| | 02:09 |
Windows Store.
Thanks for taking this course and we'll
| | 02:12 |
see you again in another course here at
lynda.com
| | 02:15 |
| | Collapse this transcript |
|
|