>> Sam Landstrom: All right. So I created Wizard's Choice. I'm a -- I work for Microsoft, and I did this is as a moonlighting project on the side. It was originally Windows phone app, and I ported it over to Windows Store. And anyway, the -- all right. So basically what's interesting about Wizard's Choice is what it isn't, which is to say it's not a very sophisticated app. This is a sub '80s level text adventure. We're talking not even Zork level, where you type in commands like open door or something. This is just literally making choices, choose your own adventure on steroids, perhaps. But I've gotten quite a few downloads. And so what I thought might be interesting to talk about is kind of what I thought went into to getting these downloads. Over close to a million now. And it's getting great ratings. So I don't think it's so much a matter of having an app that's really flashy, but just one that's very easy to use and is fun to play. Well, in this case it's a game, so play. So, yeah, power of free. I give it away mostly and make money off of ads. Kept it simple. The great store art and icons, invested a lot into art, what little art I have. And I encouraged my users to help me to spread the word. So I'll go on to some of that. Yes. So used monetization schemes that allowed me to give it away for free. As I mentioned you've got to do it free. I mean, if you -- at least if you want to get a lot of distribution. I have tried doing lost leader log, where I'll give away the first game and then have the SQLs charge for those. It actually works pretty well on some platforms, but for this I find it much more rewarding just to give away the whole thing and just make some money off of apps. So and actually I have a blog post about making money, if you want to read that. Yes, kept it simple. So here's the level of -- this is the height of complexity of this game. So literally you just making choices. You just read, make choices, read make choice. You might see some notifications based on, you know, whether or not your choice was advantageous or not. But, yeah, there's not much to -- not value a feed of engineering by any means. I did invest some money into hiring some artists to give me some decent logos. So as you can see up there, you can probably pick my stuff out a little bit. And that really helped me I think to attract eyeballs. And it's remained in the top 100 for free games, both on store and on phone for months. And I think a lot of it has to do with art. And so not just the -- that little 50 by 50 pixel square logo, which I think is crucial, but also your logo once you're on the store or once you're on the start menu so people can pick you out. The woman with the dagger there, I -- personally, I would click on that. But, anyway. So how I did that is I hired my artists through elance and guru.com. It costs you a couple hundred bucks. But let's face it. I don't think most of you are necessarily artists. Or if you think you're an artist, you're probably not really an artist. And so I know I'm not an artist at all. So I really am glad I went through this route, so -- not only for that, but for editing. And of course you can also hire them for coding if you want, but maybe if you want a widget or something. I've heard that that's actually usually what people use those websites for. All right. So I had asked for help from my users shamelessly. Of please rate the app, preferably a good one, which I guess is what I'm doing now. I didn't all know that you were going to rate it five but I guess now that you are that's good to know. And I also would point them to my Facebook page, which came in really -- became really important later strategically. As you can see on Facebook, you start getting a whole -- of course, it doesn't matter what outlet you have, but you have to have a outlet through your customers to give you feedback because I found a lot of bugs this way. And I also get a lot of five star ratings to begin with, because I have fans that are following me. And I'm close to a thousand now on here. And when you just distribute and say I've got a new app out, a bunch of people have downloaded initially, pump up your ratings really quick and then also give you quick feedback, mainly just because my testing is -- I try to test it. But in the end, I test it in production. So, anyway. You're raising your hand? >>: Yes. Is your Facebook page your personal Facebook page or one you developed for Wizard's Choice? >> Sam Landstrom: I have both. And at first people were friending me on Facebook and that wasn't working very well, that didn't scale. So, yeah, I created one for -- it says Sam Landstrom and that has to do with my authoring because I like to write. I have a novel too. But anyway, what I normally would do is I would have changed that to do you like games. And that's what I'll probably do later as I spit out more games. >>: Got it. Cool. >> Sam Landstrom: Yeah. Normally you wouldn't probably put your name on there as your Facebook page or whatever website you're using. And that's the main step. It's like basically keep it dead simple so I don't have many bugs. I have the advantage of the fact that my content was kind of what drove value to it while the shell itself was very simple. And so what it did, it did really well. Again, I got people to try to help me by being shameless about my plugs in there. Great art. And then just having a good feedback loop with my customers. That's basically it, I think. So questions? >>: [inaudible] from the phone to Windows? You have [inaudible]. >> Sam Landstrom: It -- because it was such a dead simple framework, so I had a simple framework around it, and then I just swap XML files. So in XML file I'll use to define the game. So basically how the store goes, what decisions you can make, what are the consequences, all that I determine in an XML file. But it dead simple framework around it. And, yeah, I just -- I ported it over in probably about a day. The hardest thing was adding a few new features for Windows 8 like an app purchase. But otherwise it was a pretty quick and easy port because of how simple it was to begin with. Your results may vary. Yes? >>: How many downloads have you had for your upgrade scenarios on top of the ones that you've had for the -- your free case? >> Sam Landstrom: Oh, right, so for the InApp purchase? That, not as many as I had hoped. About -- let's see. I made about 650 bucks off of the Windows store version. So that's like maybe 320 -- it's like 2 bucks a pop. So, yeah. I give the first three chapters away for free and then they get hit with the InApp purchase. And honestly, I thing a loss leader model is probably better, where you give away the first chapter and then you charge for each one after. I'm trying to work out why that is, but I've seen it on other platforms and it's more effective, strangely, in some cases. I think it's because you trust the app more going up on the store and seeing it and seeing its ratings versus having this chrome that shows up where it's asking for your credit card right in the app. Especially with an app that looks as crude as mine. You're like is this guy phishing me? What's going on? And so I haven't seen as many InApp purchases as I'd like to see. And I'm thinking of rereleasing it as free and just have ads for it. >>: If you don't mind asking me, how much are you getting from the ads revenue? >> Sam Landstrom: Recently like maybe 30 bucks a day. And ->>: That's great. >> Sam Landstrom: Yeah. That's mostly off phone though. Well, actually I don't have ads on the Windows Store version. But off of phone, yeah, but that's just because I did a new release. It's usually more like 15, $20 a day. But, yeah, my ECPMs are not very high. I wish my app was more sticky so people were -- the problem with the text adventure is once they burn through it, they're done. Unlike a card game, for instance, where you can make a lot of money. >>: [inaudible]. >> Sam Landstrom: Yeah. And I'm hiring writers again through that websites because writers are cheap. So, anyway. >>: By the way, do you keep statistics about what choices the readers did? >> Sam Landstrom: I'd like to do that. I was thinking of hooking this up to the cloud and just having a few things like, okay, I have stats at the end like where you rank and then it gives you a title like you're anything from like wetter of the trousers all the way to grand champion of whatever. And what I like to do is hook that up to the cloud so I can start seeing how people are scoring and see where the bell curve is, and then see how you compare to others more directly, versus kind of my evaluation of how you did. And also, yes, it would be cool after each choice to see stats, see what everybody else was doing. So those are kind of features I've been thinking of adding. >> Francis Cheung: Well, all right. How is everyone doing today? Okay. My name is Francis Cheung. I work for Patterns and Practices. Anybody heard of Patterns and Practices before? Four, five. Okay. So what we do is we provide guidance. Guidance is oftentimes terms in the form of books. We also write a lot of code. Anybody use Unity, Enterprise Library? Okay. So ->>: [inaudible]. >> Francis Cheung: It says yes. Hello. Can you not hear me? >>: [inaudible]. >> Francis Cheung: Oh, there we go. >>: Perfect. >> Francis Cheung: We're green. We're very green now. All right. So Patterns and Practices we produce books, we produce reusable libraries like Enterprise Library, Unity, and Prism. So let me give you a little bit of background about what we're going to be talking about today. I'll be giving you some tips and tricks on Windows 8 development but mainly concentrated on building business style apps, line of business style apps. That's what we really are focusing on. That's generally our customers, the enterprise customers. So that's really what -- where we focus our tips and tricks. So to give you some background, Kona really started because of Prism. Prism was the framework that we came out with that was really to help business customers, enterprise customers build line of business style composable applications on WPF. Okay. Anybody heard of CAB, composite application for app block? Okay. You go way back. You get a reward for CAB. Now, we created CAB for Windows forums. And initially we said some -- a lot of customers said hey, let's go ahead and port CAB to WPF. Well, luckily we didn't listen to them. We thought, well, what do people really want to do in WPF that they need help with? What are the problems, what are the pain points in WPF? So we rethought what they wanted. Said, well, what do you want? Do you want composability, do you want modularity? What do these things look like in this new platform? And we readdressed those scenarios. Fast forward five years those same customers are asking us now, hey, can you please port Prism to Windows Store? And we said absolutely not. We rethought these scenarios and said, hey, what do people need help with in Windows Store? We don't know. So we set out to build an application to find out. So let's take a look at this application here. It's a web based application, I know. But imagine it's, let's say, a desktop or WPF application. See if you can spot any differences or similarities between it and the Windows Store version. Let's see. Again, web, Windows Store. Any similarities? I'll do it again really slow. Web, Windows Store. Anyway, the point is that there's such a big difference in platform, in functionality, in user experience that in a lot of the same challenges you had in WPF don't apply. For example, one thing that we spent a lot of time with in Prism was composability, right? You had code coming from different modules, from different teams. You need to assemble a user interface with all the -- these different components. How does that work in Windows Store? Well, Windows Store apps aren't like that, right? They're typically really simple screens. You want to do a simple task on that screen. You don't have 10 little subwindows on this screen. They're all inner working. You don't really have that. So we don't have the same composability challenges or needs on this platform. So what we decided to do is build a shopping cart style app in Windows 8 using C# and XAML because that's what most of our enterprise developers were using. That was the tool set they were using. And so we wanted to make sure it was bulletproof, it was world ready, it was built on the technologies that we wanted to really showcase. So we built out this app, and as typical for Patterns and Practices we like to build the app first and then see what kind of things were really reusable, and we pulled them out. And so that's what we did. So we'll be shipping the app here, which is the AdventureWorks shopper, based on the adventure works database and SQL server, as well as some reusable libraries. And we'll be shipping in May 2013. So let me give you a quick demo of the AdventureWorks Shopper. >>: [inaudible]. >> Francis Cheung: Sorry. 2013. >>: Okay. There you go. Okay. So here's our app. We went ahead and shot some nice images as opposed to the images that were in the AdventureWorks database. So you can see here you can dive into different categories. This is the hub page and so you can see us scrolling here. And you get some semantic zoom here. And go to a certain scroll -- scroll to the right you can zoom into this category. You can go to the product details, add to the shopping cart. You know, pretty typical shopping cart type app, right? And we showcased a lot of different things here. For example, here's an example of composition. So what you have here is a page with three constituent parts. Here you've got address, billing and payment. These three different forms are used in the other parts -- parts of the application where you want to, let's say, add a specific shipping address, or you want to edit a payment method and so forth. So we have some composition here, and we also have to deal with situations like for example here. If you hit submit without anything in the form, you get a whole bunch of validation problems, right? And, sure enough, let's say if we were to put some data in here, go back up to the Visual Studio, suspend your application, launch it. What do you expect to happen? What do you expect to see? You expect to see exactly what we left from, right? That, itself, is pretty hard to do. The validation's hard to do. Keeping the stored state is hard to do. A lot of it's pretty hard to do. In addition, this is actually not at the page level. These are user controls within the page. So he has that level of composability that is also kind of hard to do. So after we built the app, just let me go back to the Power Point here again, we look at what is so commonly used in the app and figured is this useful enough to ship as a reusable library? And we found a number of components that were. And so we'd like to introduce Prism for Windows Runtime. If you use Prism before, we've released Prism 4.1 for WPF and Windows Phone and Silverlight. This is a completely new thing. It's Prism for Windows Runtime. It provides MVVM support, navigation, decoupled communication. Anybody use event aggregator? Nobody? Boy. Tough crowd. Decoupled communication is all about the event aggregator. We decided to actually pull it out of Prism and put it in a portable cuffs library so you could even use it in Xbox if you wanted to. Commands, support, validation support as well as flyout support. Anybody create flyouts in Windows? Windows 8? It's pretty fun, isn't it? It's -- is it a lot of work? >>: Yeah. >> Francis Cheung: To create a flyout? Yeah. I'll show you it will be like three lines of code for us. It will be super easy. So flyout support is something that I think is going to be a big win for you guys. So let's move on to tips and lessons learned. Again, what we do is we provide guidance by really experiencing it and having a test team hammer on our code. They look at every line of code. So this is where we provide value. Most of our corporate customers don't have the time to experiment with five different ways of doing every little thing and seeing which way is the best. That's what we do. We look at every option, or at least most of the options that is we like to entertain, and we have our test team -- we build it out. If we don't like it, we build it again. If our test team doesn't like it, we build it again, so forth, so on. Right. Let's start with the first tip. These tips are pretty general. First tip is that, hey, you know what, if you're a Windows 8 -- sorry, Windows Phone developer, Windows Phone, Mango or even Pre-Mango, Windows Phone 7 developer, the transition to Windows Store apps is going to be pretty straightforward. There's just a few things different. For example, suspend, terminate, resume experience is very similar to deactivate, tombstone and reactivate. So if you had to worry about that before, this is going to be pretty similar. The push notification service is very similar to the new WNS. Pretty similar. A little bit different, but pretty similar. Also, you've got to go through the same or similar certification process with Windows Phone you have a certification, with Windows Store apps you have a slightly different certification process. They're going to look for different things, but you also have that layer before you get your app submitted. By the way, if you have any questions about anything I say up here, or if you have a comment, please let me know. All right? Tip number two -- again, these are pretty general. If you haven't done any Windows Store app development, this might be useful to you. My point here is that you don't have a lot of the things that you'd expect if you're doing, for example, WPF or Silverlight development. For example, blend behaviors. Behavior of T. People build a lot of code around that. That's not available here. Binding expressions. You can build a binding expression but you can't get access to it programatically. So there's a lot of things that you can't do. So if you've been doing development in Silverlight back -- way back like in Silverlight version 3, your skills are going to be really needed. So attached behaviors, you're going to be doing a lot of those. All right. All right. Next one, push notification. In Windows Store apps, push notification requires you to register your app with the store because the Windows Store is actually where it's going to be -- at least it's -- every message is authenticated through the store. So what happens if you had a sideloaded app? Sideloaded app's probably not going to be registered with the store. Your enterprises are going to build up these apps, expecting them to be deployed to your -- your employees or certain customers or so. They're not going to -- those apps are never going to see the light of the Windows Store day. Right? So how do you deal with that? Well, unfortunately right now there is no third party push notification service. There's only one. So you have to go through the store. So the only option that we found is to use a periodic notifications. So no push, but you can do a pull. Right? Async and await. Now, with the new platform it's really important not to lock the user interface. Not to lock that UI thread. So typically anything that takes any amount of time, file, IO, talking to services, that's all going to be async. You know, typically the APIs that are provided to you are async and so forth. You know, your chain of calls all the way up are probably going to be async too. As well as any APIs that you write. If they take any amount of time, they need to be async. Okay? So for example, anybody done async and await stuff? Half the crowd. Okay. You guys are probably experts at this already. So you can see here that you got an HTTP client. The next line creates a task or returns a task, actually uses that client to go hit a URL and return a task of string. And then we do some work here on line five. And you can see here, this is all synchronous, right? This goes boom, boom, boom, boom, boom. Just goes against this until line 7. On line 7, it -- we've got the get string tasks that we created up here. And we're awaiting it. So now we're going to allow it to finish and then the UI is now responsive again. You can do other things. And once that's done, do we do the rest of this method? So the line 8 is not executed until line 7 finishes. So how does that happen? It looks like, you know, that would be some sort of callback. Well, all of that's taken care of for you by the compiler. So all you have to do is put a weight there and the rest of the method will not get executed until that await finishes. So really, really useful. We had several different projects use -- well, we had the Halo projects written in C++ as well as a Win JS. And they're code for asynchronous programming was much more difficult to write. If you're doing C# development, async and await are your friends. They're very, very useful. Okay? Let's talk about navigation. Page-to-page type navigation. What can we do to help with that experience? You think, well, it's not a big deal to do that kind of stuff? Just let me make sure I'm on the same page. Okay. So how do we help with navigation? Number one is to use the visual state aware page. Now, this is actually something we provide in our framework so I should preface that with the Prism visual state aware page. This is very, very similar to the layout aware page. If you've created a new project and use anything other than I think the blank template you get the layout aware page, right? So we basically use the layout aware page but ripped out some things that we didn't really like. Like we have this concept of a view model in the later page that didn't really match what we thought was view model, so we went ahead and removed that. And we renamed it something that was more specific to what it does. It really just helps you with your visual states. Okay? So your visual state aware page, also it helps with some navigation support. So you've got some three methods here, go home, go back, and go forward as well as several of the methods here for a lifetime management. You'll notice the method signatures. What do those look like? Those are event handlers, right? So that's kind of funny. How would they provide all these methods here as event handlers? Do I call it? If I call it what do I provide it? It's kind of funny. I wondered that the first time I looked at these overloads, these virtual methods. So here's how you're supposed to use it. Imagine you got a button and you want to go back when I hit the button. You basically point it to the go-back method, which is basically just event handler. So you're saying, hey, use the a code in the goback handler when I hit this button. So that's how you're supposed to use that. As well as here you can see the loaded event of the user control and the unloaded event are tied to the start layout updates and stop layout updates. So this is really important if you -- well all of your apps are going to be able to need to handle all the various visual states, right? So your apps aren't always just going to be viewed in landscape, they're going to be viewed in portrait. They'll be viewed in snap. They're going to be viewed in many different ways. Come Blue there will be even more. So you're going to need to deal with these. So in your page, that's one thing. But in your user controls you need to pass this information down too. So that's how you -- that's how you do that. That's why they look the way they do. They're actually event handlers. So that's how you're supposed to wire them up. Okay? So this is pretty general stuff. If you've been using layout aware page, you've probably been doing this already. Okay? And here's how you save and load your state. Again, this is at the page level. This is page state. So what would -- what kind of data would you want to load and save in your page state? Well, scroll position, number one. I'll be talking a lot more about view models and the MVVM pattern. But what kind of stuff would you typically want to save in your page, your scroll position? So in this case, you can see my horizontal offset is being saved. So I'm pulling it out of my visualized stock pile and putting it in my page state. Here I'm loading it. Okay? Pretty typical usage of those two methods. And next tip is definitely support your visual states. If you're anything like me, you'll be spending a lot of time here. If you want your apps to look correct in all your various page states, which you -- which you really need to do. I'm not sure if the review process is really going to hammer you on this, but you know what, if the user -- if your users just tilt your app or snap it and you give them nothing, then they're not going to be that happy, you know. If you look at the first party apps, I think more and more of them are going to be supporting this. And it's just a better user experience. If you have data -- if you have functionality in the full page, you want to have that functionality or have a good reason for not having that functionality in snap view. Or portrait and so forth. So you'll be spending a lot of time here. In this case, blend is your friend. Blend can provide you a lot of this data. In blend you can change to your different states and then see how it looks. So definitely use blend for that, okay? World readiness. Well I'll just scratch the surface here in terms of world readiness and talk about translations or getting data out of resources. So, for example, let's say you got a tool tip. And you got some content in your tool tip, so that's what it shows up in, let's say, in your designer. But how do you get it in runtime to show the translated data? Well, you provide a UID here. And then in your source file, you point to -- you basically tell it what you want to translate. So for example you can see preview cartoonized app R, but in tool tip you can see the very top it references that dot content. And there's the content. In this language. So you create your various resource files in your various locales and you provide that same -- same keys over here. And the -- at runtime that content up here will get put into the content of your control. Pretty straightforward? Does anybody use this already? Okay. A couple of people. It's really useful. Yeah. It's out of the box. But it's really useful. All right. The rest of this talk will be on the MVVM pattern. Anybody use MVVM? A couple people. All right. All right. So I'm not going to sell you on MVVM here. MVVM I'll just give you 10 seconds on it. If you're interested in testability, maintainability you want to look at this pattern. This is the -- by far the dominant separator presentation pattern in XAML stacks, Windows Phone, WPF. I think it -- John Gossman originally created this pattern on WPF. And it's a really useful pattern through all the XAML stacks. So take a look at it if testability, maintainability are important to you. And they should be. Okay. So that's enough about MVVM. So given that you want to know about MVVM, the rest of the talk is important to you. So navigation. Imagine that you're in a view model, okay, a view model being the place where you're going to put your business logic that your view cares about, right? Typically the place where it calls the databases or calls various services, aggregates a whole bunch of information in order to paint your screen. That's your typical view model. Imagine you're there. The users hit a button. You've done some processing and then you want to navigate, right? So you've got a navigation service. And you want to go to another page, let's say. What does that navigation call look like? Do you like view first where you say, hey, I want to navigate to a page type, very much like with the frame navigation service -sorry. The current frames navigation service provides you. Anybody a fan of that? Anybody like that? A couple people. Anybody like the second approach, where you actually do kind of a view model first approach? In this case you can see I'm creating the instance of the view model, initializing it with some information and navigating to the view model instance. Anybody like that? Okay. So a 10-10 split. That's what we found too when we asked our advisors, when we asked our team, we were kind of divided, you know, which one looks best to us. And there's some downsides with both approaches, right? With the view first we realize that, you know, what, I'm not sure if we want our view models knowing about views. We saw that as kind of coupling that we didn't like. The second approach, well, in this case the view model knows about another view model. Should that really happen? What if we have separated teams and, let's say you're working on a view model and I've got another view model? Should my view model know about yours? I'm not sure if we should. So we wanted a little bit of a decoupling there. So we went with a string based navigation. So here I'm just going to navigate to an item detail experience. Something else with resolve that experience to a page type. And whatever the navigation underlying needs, and I'll pass it whatever it param's, right? So that's what we went with our framework. All right. The next thing is to use the bindable base. Now, this isn't specific to view models. But bindable base can be found very, very important. If you're doing any type of a binding, you're going to need to use INPC, I notify property changed, right? You're going to need to tell your views that, hey, something's changed. Go ahead and update yourself. Have the control. Go and get new data. So that's going to be really important to you. So bindable basis is provided to you out of the box. File a new project, you're going to get bindable base, right? We liked it. We didn't see a lot of changes in it, so we just went ahead and incorporated it into our library. So you'll get one if you do file new project and you'll also see that we have a bindable base in our framework. All right. So what does that give you? Well, number one, it gives you this method called set property. Set property is really nice. Because typically in your view model you have, let's say, a property, you have a setter and a getter or getter and setter. Your setter would typically check the value of the value coming in. If it's different than the value you already have, then you want to set it and raise it again, right? Only when it's changed. So that's what this does for you right here. So you don't have to check anymore. This will only fire the event if it's changed. So you can see here if it's the same we just go and return. And then it will raise the on property changed method for you. And you don't have to pass it a string representation of the name of the property. It all takes -- it all makes the code much simpler. Okay? So this is provided for you. Now, let's imagine that you have an app and you want to use view models. But you're in a view first type world, which is in the store. You have views that you navigated to. But now you have to have view models to support the views. So how do you do that? How do you have these two things work together? Well, we're using the view model locator pattern. Now, people have used this pattern before. Anybody use this pattern before? Okay. It's pretty standard if you've got views and view models. You need to connect them somehow. Oftentimes you would have something really simple like you've got a view and you set the data context of the view to static property of some view model locator class and then that property would go in to construct whatever you needed to set it to the data context, right? So that's the general functionality of the view model locator. What we decided to do here is bring that up a level and make it more general and more reusable for you. So what we do here is we do a convention based lookup. Imagine your page is called my page, and you use our view model locator. It's going to go and look for a my page view model, construct it, and set it into the data context, right? Isn't that what you need? That's what you'd expect, right? So we do that for you. So all you have to do is set this attached property here, view model locator.auto wire view model equal to true at your page, and we'll go and find the view model for you, assuming that it fits that convention. Now, what happens if you don't follow that convention? Well, then you're screwed. No, I'm kidding. Then you can change it. We completely give you -- we have like three different hooks, three different ways to change that convention. You can simply say, no, it's actually a different folder, oh, we want to use a completely different way to wire it up. I'll show you a couple different ways in our talk today of how you can change that convention. But out of the box you get a convention. So it will find a view model for you, assuming it's in the right place. And it will do it up. Okay? Next thing, validation. What did validation look like back in WPF and Silverlight? Well, you typically implemented I notify data error info. That was your friend. That was what you did 9 times out of 10. Your model classes would implement that and then on your controls you'd use notify validation error true. And then all of a sudden your control would light up just as easy as that. For example, here, notify on validation error equal true as well as validates on exception equals true. So if the code had an exception or had any validation problems, this text box would light up. Isn't that great? Unfortunately that's now how it works in the Windows Store apps. You don't have that support. You don't have those controls that listen for those interfaces or the events that those interfaces imply. So what do you do? Our recommendation is to use our validatable bindable base. Validatable, I'm not sure if that's really a word, but hopefully our ethics team doesn't kill me on this. But, yeah, it's a bindable base that we saw before. But it's a validatable version. So how do you use it? Well, you take your model class, for example address here, you just simply extend validatable bindable base. You can see here in the center we call set property, as you would normally, right, I mentioned before bindable base provides with you a set property method. Use it. It's going to be very valuable. It's only going to raise the property change event if it's changed and so forth. It's very useful. In this case, set property is not only going to set it and raise the event, it's actually going to do the validation if the values changed. So your view model code or your model code doesn't have to change its looks hardly at all. All they have to do is extend our validatable bindable base. And then what do you get? Well, you get a property. You can see here in the view you got a text box. The text is bound to add just that first name. For example here that first name property. We have an attached behavior. This is just -- this doesn't ship with the library. It ships in our reference implementation, our sample project, our sample app. But the highlight form on errors is basically an attached property that binds to the model's error's property. So model's errors is a collection and I index into it using a first name, and basically this says, hey, is there anything here? Is there anything in that collection? If there is anything in that collection, I want to make this control that I'm attached to highlighted. I want to make it red, right? So that's how that works. So all that does -- and you can create your own. You can style it however you want. But this is the point is that what we provide for you in validatable bindable base is a slightly different set property method as well as the errors property here. Okay? Question? >>: [inaudible] extra block or [inaudible] to show [inaudible]. >> Francis Cheung: In this case -- the question was did we need another control to show the error message? In this case, yes, if you want to show the error message here. In this case, what we're doing here is we're highlighting if we want -- if this field here is an error. If you want to show the actual method itself, I'll put that in another text box. And then in that case, the text box text property would be bound to the address dot errors first name. All right? In that case it would show -- it would probably show the first one or so. Okay? Any questions about this? Again, this is something that's really missing -- you got a question back there. But ->>: [inaudible]. >> Francis Cheung: Yes. The error message? Yes. >>: [inaudible]. >> Francis Cheung: Okay. So to localize that, probably the best thing to do is look at the code. What you can do here is you specify in the data the attribute, the error message type that you want to use and so you create like a kind of an error message helper class that has static properties on it. And the getters of the property would call your resource library. So that's how we've done it. So that's how you would localize that. All right. Decoupled eventing. So, again, doesn't sound like we had a lot of fans here of event aggregator, but let me describe to you what the scenario is here. Imagine that you have a page and you've got a user control on the page. Well, the page doesn't have a lot of connection with the user control. All you see is little XAML reference to the user control and that's it, right? Imagine you have view models behind the page and a view model behind the user control. They don't talk to each other. This is referred to as the Hollywood parent pattern. Anybody heard of that before? It's kind of crazy. I actually had a customer come up to me and -- I was on Prism for a very long time. He said oh, you should use the Hollywood parent pattern. What are you talking about? Yeah, we do that all the time in Prism. Like, wow, I had no idea people actually gave names to this thing. But it's where the parent really doesn't know anything about its children. Okay? So in this case, the parent page doesn't really know much about its children. It doesn't participate in the children's wire up much, except for the fact that it's there in XAML. But when the parent page goes away, does it tell its children? No. When it gets instantiated, does it tell its children? Not really. So the only hookup is in XAML. So imagine you have user control. It's got a view model behind it -- or let's say it's just got code behind. And it needs to listen to an event. Let's say you've got long running service. And it hooks up to an event on the service. All right? Now, let's say you navigate away from the page and you come back a bunch of times. What happens? Anybody? Come on. It's a memory leak. It's a memory leak. Because the user control did the plus equals on the event. But it didn't do the minus equals. It's connect to go a long running service that will run for the lifetime of your app and it has you keep running your app, keep hitting that page and leaving it, you get more and more handlers to that event. But does the user know that? No. So you get a memory leak. So this is where it's useful to have something that's decoupled. Because in that user control you don't have an opportunity. You don't have an on navigated from. You don't have an on closing type of thing to tell you that, hey, this is the opportunity to close and unregister. You don't have that. So what we suggest to you in this case is to use our event aggregator, which has -we've referenced eventing. So we ported the event aggregator from Prism into a portable class library. And we suggest you use that. So here's how it looks if you're using the events aggregator. So, for example you've got a view model that wants to subscribe to an event. You basically take as a constructor dependency the event aggregator here. We call get event of a strongly typed event there, and we subscribe to it passing it a delegate of what should happen if the event were to be called. Here, down here is the case where you publish the event. So, again, you take the event aggregator reference and at the appropriate time you call publish on the event passing it a payload. Right? So that's how you fire the event. That's how you listen to the event. When you do this, the listener of the event can go away. If that isn't a user control, it can just go away. It can get garbage collected. It will happen without having to create any memory leaks. All right? Any questions on that? So next let's talk about commanding. Does anybody use commands? Coupled? If you don't use commands, what do you do? You just handle on click on everything? What do you guys use? Anybody? >>: [inaudible]. >> Francis Cheung: Okay. So commands are pretty useful, right? Commands are for really buttons, right? Right now the only control that supports commands is button base. So if you have something where you want to execute functionality but maybe only in certain scenarios, for example if you have something selected, oh, then you want to highlight the button. The button should be enabled when something is selected. If nothing's selected, well, you want the button grayed out. How do you do that? You do that through commands. So if you just handle on click of everything will get clicked and then, you know, you're going to need to tell the user somehow that, hey, you shouldn't have done that. But here ICommand provides execute, can execute, and an event called can execute changed. Those, again, are for those situations where your app state really want -really should affect the functionality or the can executedness of the button. Right? So, again, those are supported by a button base. There's a whole bunch of things, however, that you don't get a command -- that commands aren't really adaptable for. For example, a grid view, right? Let's say you've got a grid view and let's say you -somebody clicks on a certain item and you put grid view. And you want to navigate, all right? Well, in that case you get an event. You don't get -- grid views aren't compatible with commands. So what do you do there? In that case, there isn't this concept of can executedness, right? It's always executable. If you see it, you can click on it. In that case, we really just want to get rid of all the stuff and just go from an event to an action. So that's what we recommend. If you have a button, then you probably want to use Icommands, otherwise you want to use event. Let me show you what that looks like. So here's our delegate command. It's our own implementation of Icommand. It's really, really simple. All you do is you pass it -- you could see here. We created a new instance of -- all you do is you pass it to the delegate. The delegate to be executed. The button is enabled you hit it, that method will get executed. And then a method for -- or delegate for can execute. So first thing is page is going to do is it's going to call that method. It can execute and say, hey, can I run you? If so, I'm going to enable the button. If I can't, it's going to be in a grid form. And then in the view model you're going to want to raise you can execute change. In the case where let's say your view models in a state where you really can't -- you don't want the user to perform that function. So you want to -- you want this method to return false and then you call that method. Okay? And simply in your view model you just bind to that command. Pretty straightforward? All right. So pretty standard stuff. What we're providing here is the delegate command. Because, otherwise, you'd have to create your own implementation of Icommand. Here, this is just a really simple way to do it. And it's all the -- all the interface requires is the execute and can execute, and so we did that all for you. All you have to do is provide it to the delegates. So people found that very useful. So reported that to the Windows Store. Next thing attached behaviors for the rest. For example, I mentioned before you've got a grid view, right in and you've got a clicked event. So all we do here is we've created our own little attach behavior. Again, that's the theme. We don't really have behavior key, so you're going to have to create your own attached behavior. We set the action equal to that so that this attached behavior listens to the clicked event. And when it happens, we're going to call that action. Right? And your view model here is the action is just pointing to a method. So it's just a delegate. All right? Any questions? All right. Suspend, resume, terminate. Anybody here support suspend, resume, terminate your app? Okay. You guys all should. Okay? If you guys get through a certification without this functionality, well that's unfortunate. Because this is -- should be something that should be tested thoroughly. And that's an experience where you start up your app, and let's say you swipe away. You launch another app, right? So you go into suspended state. If you have enough memory pressure or system resource pressure your app will get terminated. Your app is not going to know that. It's just going to get removed from memory. And then if the user decides, hey, I want to go back to my app, so if I find it's not there anymore, your icon doesn't launch it, it should return to the same state as you left it, as I showed you in the demo. You need to return to the same state, otherwise the user says, oh, shoot, what happened to my data? Wasn't I like halfway through filling out this form? Where did it all go? You need to be able to support that, okay? So how do you do this? This is really important. And it needs to be handled. What we do is we provide some support for you if you're doing view models. If you're doing code behind type stuff, as I mentioned before in your layout aware page, your visual state aware page, you have the load state and save state methods, you can use those too. But if you're using view models to store your state, which is, in this case, for example your form fields were probably bound to properties on your view model, you'll want to use the restorable state attribute, okay? All you need to do is extend view model, our base view model class, and put this restorable state attribute. That's it. The framework does the rest. If your application is -- is terminated or actually is suspended, because we don't know if you're terminated. If you're suspended that's the only opportunity that we have to stash away any state. Termination you're not going to get an event. So we need to stash it away when we can. We need to do it quick. So what we do is we look at anything with a restorable state attribute, and we put it away. It's the same -- we use the same backing store as the -- as the visual state aware page, it use this thing called the suspension manager, right? So we like suspension manager. We like the functionality. But we didn't like the fact that it was -- it was static. So we just created a different service that was basically a copy of the guts of it. So instead of suspension manager we have session state service. Okay. So the session state service basically takes all that data, sessions its away for you so that when you come back from suspension, it goes and rehydrates everything. Okay? So that's all you got to do. Unit testing. Anybody do be unit testing here? Got a question. >>: [inaudible]. >> >> Francis Cheung: You can. You can -- so the question here is can you include complex types? So in the previous case I actually had restorable state on a string. What if my restorable state was on an address, right, or something more complex? Yes, you can. But ->>: [inaudible]. >> Francis Cheung: Noun types? I'm. I'm not following. >>: You need to access known types? >> Francis Cheung: Known types. Yes. Yes. So the question was what if you use complex types here for the restorable state attribute? Yes, that works. But underlying, we are using the suspension manager, which was underneath it, it was using the data contract serializer. So it needs to know what types it is expected to serialize and to use serialize. So because of that, you have to tell it. So I'll show you how to do that -- actually, go ahead and take a look at the RI, our reference implementation, as to how, as to how did we do that? But it's pretty straightforward to -- we actually have a -- if you look at our MVVM app base, there's an -- there's a virtual method to provide those known types. But, yes, you have to tell it the types that you want to serialize. Okay? Thanks for the question. All right. Unit testing. Anybody doing unit testing here? Come on. You got a -- should have more hands than that. So unit testing support in Windows Store apps is really good. Especially if you've been doing Windows Phone type apps. Really the best option out there was Silverlight test framework by Jeff Wilcox. It was really nice. But the problem is that it ran the tests on the device. Well, it was great. You know that the tests are actually running on the hardware that our expecting. But how do you get the test off? If you get a test failure, how do you know? How do you report to your build server? How is anybody going to know, right? You want some sort of automated process that will tell you success or failure. You don't want to have your developers be in charge of, oh, they get checked in code. I'm going to go home now. You know. I hope everything went well. You don't want that case. You want some sort of automated build process to run your test, harvest the results aggregate them all. So the unit test framework within Visual Studio 2012, for Windows Store apps is really nice. So that -- so that's -- that's that point. Here I provided you a MS build script to extract the contents of the unit test into your build server. So you can see here I have an item group for the appxs. Here what we're going to do is we're going to use VStest.console EXE against all of your appx packages. It's going to run it. And it's going to use slash logger:trx. So it's going to be to log in TRX format. So if you use this MS build, you'll go and run those tests and export them as TRX. So you can harvest them into your build server. Okay? All right. The last hint here I think is the most valuable. So I already talked about flyouts. So in order to create a flyout, it's probably -- well, I think the sample, if you look at the sample, it's like 50 lines of code in order to create a flyout. That's not talking about the actual flyout itself, the XAML to -- with all the controls. Just to create a flyout, show it, listen to the closed event and do all the wiring, it's about 50 lines of code. Anybody use Callisto? A person. Okay. So a couple people. All right. So that's Tim Heuer's project. He created something that will help with that. So he got from it 30 lines of code -- 50 lines of code down to about 30. But still quite a bit of work. So what we recommend is to use our flyout view. So all you have to do to do that is simply take your view class, in this case I created a login flyout. You can see the picture of it over there. And we're extending flyout view instead of page, right? So all you got to do is right click new item, blank page, or whatever page you want, typically blank because you really don't have that -- you don't want that many controls in your flyouts. Right. Instead of extend page, you extend flyout view. At a constructor you specify the width. So there's two standard widths for flyouts, a wide and narrow. In this case it's narrow. Call the initialized component. And then, for example, if you want to show it, you just use the flyoutservice.showflyout and you pass it the name. Similar conventions as I've talked about before. So log in here. What it's going to do is it's going to look in the view's folder for file for a type that's flyout name flyout. So in this case, it's going to look for a login flyout. Okay? That's all you got to do. And in your page, you put your XAML controls as you expect. The flyout view does all the ugly work for you. The ugly work of creating the popup, taking the stuff, putting it as the child of the popup, listening to the closed event, all that stuff, all the wire-up, the boilerplate code, it's all taken care of for you. All you have to do is this. Right? Does that help anybody at all? Got another question. >>: [inaudible]. >> Francis Cheung: So that the next step. I can show that to you if you want. But this is just to show the flyout, right. So this is the code to show the flyout. If you want to include it in the settings, that's just a little bit more code. I'll show you how to do that. But this is at least how to show the flyout. The settings charm can do a whole bunch of things, right? You could show flyouts. You could launch to different URLs, you could do a bunch of things. But this is the code to actually just launch the flyout. All right. Any questions on this? All right. Let me create an MVVM app from scratch for you. What we'll do, go over to Visual Studio, file new project. I'll set with a blank app. I'll call this AppXfest. All right. And what I'll do is I'll go ahead and bring in the other project, our library project. Which is Microsoft.practices.prism.storeapps. We'll probably be shipping this initially as source. So you probably need to do something similar. Okay? And we'll go ahead and create a reference to it. All right. So let's go back to our appfest project here. Let's take a look at the app XAML CS. What you'll realize here is that you've got a lot of boileplate code. We're listening to the suspended event in order to hook everything up, right? So what we'll do is we'll get rid of all the boileplate code. Does that make anybody happen? Anybody? It makes me happen. Because it's the same code over and over. And you got to muck witness a little bit in order to get your app to run correctly. If you don't put things in the right order, it's going to be very unhappy. So get rid of all the that boilerplate code. Instead of a set application, you would go and expend MVVM app base. Okay? And then it complains to me. It's like, oh, well, extending me is fine. But we need to do a little bit more than that. Let's go ahead and we need to provide it an implementation of on-launch application. You need to start your application somehow. Typically you want to navigate to a page, right? So we'll go ahead and navigate to a page. Let's go ahead and navigate so that there is a navigation service provided. I'm going to navigate to the start page. Okay? And pass it in null. And that's almost all you have to do. In this case, you have to go ahead and update the application here to also extend from MVVM map base. Okay? We can build it. Should be happy with that. But now what's it going to do? It's going to try to navigate to a start. Well, we don't have a start page. So let's go ahead and create that. I'm going to create a folder within my project. I'm going to call it views. So my convention -- the navigation service is going to follow the convention that it's going to look for the view in the view's folder. I can change that convention if I want, but let's just go ahead and follow it for right now. In the view's folder I'm going to add new item, a blank page. And I'm going to call it -anybody? >>: Start. >> Francis Cheung: Thank you very much. Start page. Right. So that's convention. So in my start page, I'll go ahead and put in a little text box -- text block over here, just to make sure that we're in the start page. Text block, all right? And if I run my app what's it going to do? Oh, there we are. Start. Well, I hit art. But we're pretty close. So what we've done is we've created an application and navigated. Not that impressive. But let's take a look at what we have. Let's go back to your apps MLCS. And in our app let's see what other services we have. We have the navigation services we've seen before. We have a session state service. And I believe up here we also have a flyout service. So we have those three service that we provide to you by the MVVM map base. All you have to do is extend it, and those three already configured for you. If I want to show a flyout, I can do so here too. All right. So let's do that. Let's go ahead and create a flyout. See how painful that is. I'm going to add a new item here. Blank page. Let's go ahead and call it a login, for example. Right? Is and let's say -- actually before we go ahead and show the flyout, let's talk about view models here. So we have our start page. Now, let's see what it will take to connect the start page to a start page view model. Let's follow the convention again. Let's go ahead and add a project -- sorry, a folder. View model, and within that -- again, we have a start page. So what am I going to name my view model? >>: [inaudible]. >> Francis Cheung: Thank you. Okay. Move all that stuff. Okay. Right now I don't even have to extend our view model. Let's just see what happens here. What I'm going to do is I'm going to create a property. Okay. And instead of making auto property, let's create a backing field, just so that I could put a break point right here. Right? So what we're going to do is we're going to go to your start page and bind to the center and see if it works. Right? So our start page here I have got a text block here. Let's put in a stack panel so it doesn't blow up on me. Okay. Got the text block there, and I'll put a text box here. Text equal binding name -- is that what I name my property there? I think so. Name property. Okay. So I'm binding this to name, binding it to make sure that the binding is 2 way so that the view model can update the view and the view can update the view model. Okay? Run that and see what happens. See what I did here. All right. Get rid of this. See what happens. See if I hit that. So we're at a start page here. I put some data here. I hit tab. Nothing. Hmm. It's because our view and view model aren't connected yet. So what we have to do is in our start page in the XAML for the page what I do here is add viewmodellocator.autowiremodel equals true. Let's try that now. So now, when the page loads, that property is going to hunt for the according view model in the typical place. If it fine it, it's going to call -- activate or create instance on it and put into it the context? Right? So now I've got my view model -- I've got my view here, some data here. Hit the tab. And here we have -- we've hit the center. So here we've connected the view model to the view with minimal, minimal pain. Right? So that worked fine. But now say I want to do something more interesting to my view model. Notice the view model is pretty simple. And the state I just made about 10 seconds ago, the fact that our view model locator calls activate or create instance, does anybody think that's kind of strange? Normally you wouldn't do that, right? Because your view models typically have dependencies. And these dependencies typically shown as constructor parameters. Right? So let's say this view model now wants to do something with the flyout. If you hit the button, imagine you've got a button here and you want to show a flyout. Let's do that. Okay. So let's first create a command here. I forget I have a mouse. Let's call it show flyout command all right. So I'm a constructor. I'll go show flyout command equals new delegate command. So here let's say I just want to do a show flyout method. Right in here I'll just go ahead and create the method here. All right. And so we've got this command. I'll go ahead and hook up a button to that. So my start page I'll go ahead and put that right blow the text box here. Button. Let's go text. Is it content? I forget. Content. Yeah. Show flyout, right. Command equal a bind to the show flyout command there. All right. Let's see if I hit my break point. Hit the button. And I hit my break point, right? So that's all you need is to do to set up a connect buttons with commands. So here all they did is create the delegate command there, pass in a delegate of what I want to execute, so that's the show flyout here. And I hit my break point. Groovy. No big deal there. But now I actually want to show the flyout, right? I want to show that flyout that I spent all the that time creating, right? So actually let me do something on the flyout just so we can see it in action. The login flyout here I'll go ahead and put in a little text here, text box texts. All right. Just so if it shows up, it shows up. And actually, let's make the background of this instead of that static resources, let's make it white. Anybody know why? Turns out there's a UX guideline for this. Flyouts have to have a white background. Have to have a light background. So even if your app has a bark theme, which most do, because that's the template, your flyouts have to be a light background. Which great. You are know why? Because that means all of your controls need to be restyled for your flyouts. So if you put any controls over there, you need to provide a light theme style for all your controls. So it's a little bit of pain point. But just to let you know. I'm not sure if they'll catch it in terms of the review process, but if you read the UI guidelines, they have to be a light background. All right? So now you'll see that. All right. So now our view model here, what we want to do here is we want to do something like a flyoutservice. -- actually it would be something like flyoutservice.showflyout and we want to show the login flyout, right? But this is a service that we don't have access to right now. What we want to do is we want to get that service passed into my view model. How do I do that? Well, we typically make that a constructed parameter. Okay? All right. So now I've got my variable. There it is. Great. If I hit a five, what happens? Kaboom. Right? Activate or create instance on something that does not have a default constructor is not going to be happy. So what we need to do is we need to help the view model locator resolve that dependency. So there's a couple ways of doing it. We can either take the more explicit way, where we actually tell it -- tell the view model locator, hey, if you run into this view and you need to create its view model, here are specific instructions, here is the delegate that will return you the theme that's set in the data context. Okay? That's option number one. Option number two is use a dependency injection container. In the dependency injection -- anybody use Unity or any other dependency injection containers? One? Come on. More than that. No? Right. So this is pretty standard in business in enterprise applications. Dependency injection containers are very common because it gives you that decoupled experience. So you don't have to know about the actual implementation of any service. You're just programming to interfaces. You don't know about the specifics of any service. You only deal with interfaces. Something else is going to resolve it for you. So here you just specify your dependencies and say, hey, I need an I Foo service. Please, somebody provide that to me when I'm running. So that's something else's responsibility. So we have option number one, which is to do it explicitly, provided factory method to construct it. Option number two is the container approach. Anybody want to see the container approach? The explicit approach? All right. I got a couple hands for the container approach. All right. So let's say we want to use the Unity container. I like it not only -- not just because Patterns and Practices wrote it but the Unity container, like a lot of the other containers out there, they don't require you to change much of your code in order to use it. Right? Anybody use MEF? Okay. MEF is also a very popular container because it comes out of blocks. Although for Windows Store apps it's not really out of the box. You still have a package you have to download. So it's not quite out of the box. So anyway, here, let's go ahead and take a reference to Unity. So I'm going to right click on references here. Manage new get packages. And the current version of Unity that is compatible with Windows Store is not in release yet. So let's go online. Here I include pre-release. I must not be online. I'm not online. That's not good. In that case I'll just go ahead and refer to a previous version of Unity that I've used before. But typically you just include the NuGet package. Anybody here use NuGet? Come on, you guys all should be using NuGet. All of your dependencies should be resolved through NuGet if at all possible. I've actually had some cases where somebody wrote a library and they didn't created a NuGet package. I said, you know what, I'll create you a NuGet package. Your library is so popular that I don't want to depend on somebody having to download the DLL and put it in the right folder, I'll just go ahead and create a NuGet package for you. And whenever you want to take it over, feel free to take it over. But it's so useful. In your project, you just create these NuGet package dependencies, and your customers, when they get your source code and they compile all those dependencies will come down. Even the newest versions will just automatically get downloaded. So NuGet is a good thing. But in this case, it doesn't look like I have connectivity so I will just go ahead and take a dependency on the DLL, which I have previously. All right. And first thing I want to do here in my app is create a member variable. All right. So here I've got a field -- you probably want to do this in a property. All right. And then what we want to do is we want to configuring the container with all my services. So in this case, I really only care about the file service because that's what I'm depending upon. So what I'll do here is I'll look at the overloads that I've got for MVVM app base. And you'll notice that there is an on initialize. This is where you want to initialize your application. On initialize. Okay? Actually let's make sure to include the base, because there might be something in the base. Okay? So here we'll go container.register. In this case we're going to register an instance because the MVVM app base is already configured the file service for you. It's already ready to go. I just want to register it so that I can resolve it. So I'm going to go register instance of the flyout service. Right? And the container already can configure out, hey, what interfaces does this thing implement? And it will go and register it based upon that type. All right? And one other thing we have to do, there's a resolve method. Basically we want to have a type, and I need to return an object. So I'll use the container to do that. So I'll just go return, container, resolve of that type. That's it. That's all you had to do to configure a container with your MVVM application. So now let's try the same thing. Okay. It doesn't blow up. So that means the constructor was at least resolved correctly. I'll hit the button here. We'll see if I hit the code. Let's see here. See if I hit that. Okay. I hit that. So now my flyout service should be called. And the flyout, the login flyout should be shown. Let's see if I spelled that correctly. So I got my login flyout, login flyout XAML, yeah. Funny. So anyway, that should have been shown off to the right. The demo gods aren't with me today. Oh, maybe because of the break point. So let me get rid of the break point and try again. Anyway, what should happen at that point is the flyout will come out to the right. Let's see. Oh, sorry. I need to configure the container. I always forget about that. So when I register the instance in this case, the lifetime manager, I'm going to give it a container controlled lifetime manager. Basically making this a singleton. Okay. Let's try that now. Otherwise when it resolves it, it will try to create a new instance every time. Let's try that now. All right. I'll figure out what I did wrong and kick myself later. Any questions about that? All right. So what we did, basically everything we talked about in the slide deck we created a view. We navigated to the view, connected the view to view model, put some commands on the view model connected to buttons. Also, let's do this. In the start page, let's see here. You notice that the name doesn't have any attributes on it? So what happens when we start the application? Let's go here. Put some data here. And I go here and that -- let's try that again. Put some data here. Come back to the app. Oh, that's right. Break point. Thank you. All right. And let's say we terminate the application. Go back in. Oh, where's our data? Let's make sure that's restorable. All we do in our view model is extend the view model base and put an attribute on this guy. Restorable state. Put some other data in it. Go back to VS. Shut down. Run the app. And our data's preserved. Right? That's pretty useful, especially if you're doing forms over data. That's not necessarily the only thing you're going to be concerned with when you're doing business style applications but that's definitely one of them. All right. Any questions about that so far? No? I'm that good. No, I can't be that good. All right. So that was creating the app from scratch. Any last questions? Got a question back there. >>: [inaudible] pop up because you're not online right now? >> Francis Cheung: No. It's nothing that it should be getting. So I'm not sure why it didn't show up. But I'm sure I just fat fingered something. But go ahead and take a look at the RI. Everything is working there. So any other questions. >>: I have a question [inaudible]. >> Francis Cheung: Okay. >>: How does that -- you know [inaudible] the current view model. So assume they've [inaudible] in memory but not [inaudible] on this page. Would that catch the data -- >> Francis Cheung: Okay. So the question is how does a restorable state service work. And you mentioned another view model in memory. But typically view models that are connected to pages go out of memory. Unless you tell the page explicitly to cache itself. So let's say you don't cache the pages. When you go from page A to page B, page B's view model will be loaded, page A's view model will go away. That's typically what happens. >>: So [inaudible] cache assume that you don't have to create a view model [inaudible] know that I'm going to be using data. So is it best practice to do that on -- you mentioned that [inaudible] use the vehicle to describe your model. Is that. >> Francis Cheung: So if you're doing -- so the question was what's best practice around where to store your state, I think. So I think -- let me see if I could answer this question. If you're doing view model type work, MVVM type work, your fields, your model will be in your view model. The only state that your view will know about is things like scroll position. You typically wouldn't want to store that in injure view model. That's not really business. That's just kind of UI state. All the other state, like the values, the form fields that user entered, you want to store that. And they eventually want to go into the back-end services, right? So you typically have them defined in your view model. So the view model state you definitely don't want to lose. So you want to use a restorable state attribute on those types of fields. Did I answer your question? >>: Kind of [inaudible]. Okay. Let [inaudible] my question. So if I have a page I have to control and each control has its own view model so it goes to automatically [inaudible]. >> Francis Cheung: So the question was really around composability. Imagine you have a page. Let's say the page has a view model and it has two user controls on the page and those have different view models. That is actually the exact scenario that we had in the check out hub page where you saw the shipping, billing, and payment. That's exactly that same case. So in that case, the Hollywood parent pattern doesn't work very well, because we need for the parent view model to pass down the information. Because the parent view model knows that, hey, I'm navigating away from them. So that's the -- that's a good time for me to tell my children, hey, I'm being navigated away from. So in that case, there is a little bit of wire-up code to coordinate the relationship between the parent and the child controls. >>: [inaudible]. >> Francis Cheung: Yes. So the question is, you know, how do we make sure that happens? In the case where you have a composition type model where you're not just exposing the fields or the properties on the view model, you actually have view models or the page's children's view models that you want to coordinate the -- the closely connected pattern is better. So the parent view model knows that, hey, I'm being navigated away from. So I better call my children's unnavigated from. And his children need to call its unnavigated from. That's the only way I think it will work. Okay? Question over there. >>: I have two questions. First one is also related to the lifetime of the view model. So what if we want to tell our vacuum that persists across the multiple [inaudible] is there a way to do that? >> Francis Cheung: A long live view model? >>: For example, I have a form -- view model that gives me a lot of fields and there are multiple pages to fill out all that. >> Francis Cheung: So the question is what do you do with a view model that lives longer than one page, for example a wizard. You may have a wizard that fills out part of the form or part of the view model on one page, and it continues to fill it out. In that case, I don't see it as a view model. That's really more of a model, right? You've got this big model thing that eventually will get filled, and then you need to take that thing and submit it to back in service. So in that case, what I would do is I would have the view models go and fetch that model thing, that long live model thing from the service that is long lived. Typically what I've seen on the wild is that the view models are really the models for a view. Right? So if you got five things on the view, the view model helps support that. So you typically have those five things exposed as properties of your view model. Typically not more. Now, in your case, what I would say is I would ever the view model say, hey, I'm concerned about the shipping address part of the model. So in that case, you would go and call some back-end service and say, do I -- what is the current shipping address for this user. And I would go and pull it. Then I would paint those fields on the screen. And then the next screen it would have its view model, it would get other fields. So in that case, I wouldn't have this long lived view model, it's more the model thing that spans the whole lifetime of the wizard. That's what I would do. Do you have another question? >>: The question was [inaudible]. >> Francis Cheung: So the question is this available for C++ right now? No. This is just meant for managed code right now. Mainly because my customers who are doing more of the line of misses type applications are using C#. But I think a lot of these concepts can be ported over to C++. Especially over to the XAML stack. A lot of these things still pertain. Question? >>: So following on the note, taking the extensive knowledge that you have [inaudible] line of business, but say a lot of the guys here are not looking at long business apps, I'm going to actually talk about his app, I forget the name of it, wizard app, considering he got a lot of content of stuff like that, if he wanted to take features and compose what you're presenting, how applicable would that be for someone who is not [inaudible] his application? >> Francis Cheung: So the question is how applicable is this code, this guidance to apps that are not necessarily line of business? I think it's highly applicable. If you want your app to be refactorable, well, how do you know that your app is refactorable? To me the only way -- what that translates to me is unit test. Do we have unit tests that will ensure that, hey, if I change this one line of code, does it break the app? How are you going to know? So if you want to have any level of quality where you expect a certain level of maintainability across say a team of developers, I think you need to make it testable. So therefore MVVM is the typical pattern to provide that testability. So I think it's very important. I know some people who do unit tests, even TDD all by themselves in a room. They have no other developers, you know. And they're even using them on spike code. So I think if you cautious if I care about testability and the ongoing maintainability of your app, I think it's very applicable. >>: [inaudible] I know when [inaudible] a lot of new people that come to this event for the first time. And the little sample [inaudible] that you demoed how to show [inaudible] group containers. So if I'm just starting with a Windows 8 app and I start with a great app which has all of the [inaudible] how can you take from the Vis Studio and create template app to kind of using some of your stuff and help people visualize it? Are you guys going to have guidance for that? Because, again, you're talking about a line of business, but a [inaudible] saying, hey, I want to do a reader app or book app or [inaudible] app or video app, and I may want to take some of the same guidance. But they don't start with the grid app. So how do you see them using your stuff so it's not too complicated for them and complex? But do you guys have guidance on that ->> Francis Cheung: All right. Thanks for the question. The question is around how do you take the guidance here and the code and adapt it to projects other than the blank project, which is what I showed here. I think the answer is that it's very applicable. The only difference to me in the grid template versus the blank template are the views. They give you a couple extra files. I think the bindable base and the outlayer page only show up if you ask for some of the advanced templates. But really it's just the views. So with the exception of XAML, this is all applicable. So the thing that I showed you in the boilerplate code in your app XAML CS, that should all go away, same as in the base -- in the blank template. It should all go away as boilerplate code. And what you really want to do is you want to add your business specific initialization logic or registering of known types logic, all of your business specific application logic, that's what you should expect to see there. So it should all be the same. The only difference is the views, right? So the views need to get the data from somewhere. In the case of the new projects, it gets it from some mocked out services in the [inaudible] behind. You could easily swap that out for a view model. So I think it's easily applicable. Any other questions? >>: [inaudible] can you use for the existing app? [inaudible]. For example, we have 10 pages [inaudible] is it something I can use this framework [inaudible]. >> Francis Cheung: Okay. So the question is how hard would it be or how easy it would be to adapt this code to an existing application? And I think the question -- I think the answer to the question is it should be pretty easy. But as you can see here that I provide a lot of base classes, okay, for example, the base view model, base flyout view, a lot of base functionality. We try to encourage -- we try to adopt composition over inheritance. But in this case, we just got so much bang for the buck if we inherited that we decided to do that. That makes it a little bit harder if you have your own base classes. But we shipped the source. So if you like our functionality you can take the code that you want and put into it your base classes. Also, the functionality that I showed you was really quite separate. The validation logic doesn't depend on anything else. If you want validation, you just extend validatable bindable base, and you just bind to the errors collection. That's all you have to do. If you want the restorable state attribute, that's a little more involved, because restorable state needs to know if you're being suspended. So in that case we need to have the view model base as well as the frame navigation service. Because the frame navigation service is telling -- is what tells the view model, hey, I am leaving you, so you need to save your state. So in general, we try to make the pieces as decoupled as possible. So it really depends. I love to find out if you do try to adapt this to your project how difficult it is. Because we'd love to hear that feedback back too. Okay. Any other questions? All right. I want to thank you very much for attending and spending your time with me today. I know this is your evening. And I appreciate your time. Thank you very much. [applause]