Sharing C# across Windows, Android and iOS using MvvmCross
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Lodge, Stuart
1.4 Million new Android devices are activated every day. 500 Million iOS devices sold. You can target all of them today from your existing C# skills and code. This talk covers: - very brief introductions to Mvvm, Portable Class Libraries, MonoTouch and Mono for Android, - a walkthrough of creating an app using Mvvm and Data-Binding on MonoTouch and Mono for Android, - using native features and functionality through portable plugins, - delighting users with native UIs on all platforms
 Good morning. I think we're ready to go. So let's kick into this. This morning's session, I hope you're all in the right one, is about sharing C-Sharp and it's about using NVVM to do that. We're going to look at all of the modern platforms. So we're going to look at all the Windows platforms and we're also going to look at Android and iOS and we're going to look at C-Sharp across them. There are other modern platforms. There's obviously the Xbox coming along, the Xbox One. And there is also the new modern platforms like, you know, PlayStation 4 is coming along, PlayStation Vita, Google to us. All of these are coming along and all of these will be home for C-Sharp. So what we put in the abstract about what we talk about is all of this. But I know that, actually can I just ask, who here already knows about NVVM and does NVVM kind of a... Okay, so it's pretty much the majority of you. So particularly after all the great sessions that were yesterday from Laurent and Gil and from Rocky today before about NVVM, I'm going to not go too deep into the NVVM introductions. But also with the sessions that are coming up from Craig, I'm not going to go so deep into the introductions into Xamarin iOS and Xamarin Android because you've got plenty of opportunities to do those later. But what I'm going to try and concentrate today is really on the core of what I can bring benefit, I hope, to you guys with, which is NVVM on the modern platforms. And it's about how you can extend portable classes to bring native features. So in particular, I hope you get to leave here today with kind of a good understanding about how you can use NVVM across all the platforms. So what I'd like to do is I'd like to spend the next hour, I'd like to spend the next hour telling a story. And this story is going to start in a very good way. It's like a classic story. And it's going to start a long time ago, actually November in 2011, in a galaxy far, far away called London. And it starts with a project called Social Storm. And it was for the Connect Star Wars game. The idea was to bring an app together that would bring together streams from Facebook, from Twitter, and from Xbox. And it would bring them together on Android, and iPhone, and on Windows Phone. And it would enable kind of this, you know, rich scrolling effect. It would enable mini games. It would enable features on top of your social streams that would get you talking about the game. And the idea was you talk about the game, and then hopefully people would buy the game, they'd hear more about the game. And that was the whole point of this app, this project. So we looked at it from a technical perspective, because I'm a techie. I look at things from a geekie. And we could see all of these layers of things we'd need to write. And we could see, you know, there was service consumption, about network data, and local data, and GPS, and all sorts of things we'd need. There was app logic about, you know, if you're going to a certain place, you do this. If certain tweets came in, you do this. There was all that sort of thing. Then there was UI logic about how you logged in, about how you retweeted, about how you tweeted. And then at the bottom, there was the whizzy stuff. There was the stuff that we really wanted to make sure we had, because we wanted to provide delightful user experiences. So there were animations, there was nice layout, there was nice graphics, there was retina graphics on the right platforms. So there was real, like, concentration on making sure we had that. And so we looked at it, and we knew that we, first of all, had to support Windows Phone. Windows Phone meant that we had to support C Sharp, yeah. And then we were asked for native. So we knew for iPhone that the classic route at the time would be go objective C. And then we knew that we had Android. So we knew that we'd have Java. And we looked at this as a bunch of techies. And there were five or six of us involved in this. It was a techie project that was Pavel and Matt and John and a couple of others. And we looked at this, and this didn't fill us with joy at all, because we thought we're going to have three stacks. We're going to have a project where we want to do releases over a period of ten months. We're going to have to maintain these three stacks. We're going to have separate bugs on each platform. We're going to have separate features on each platform. Maintaining them is going to be hideous. So we looked and we saw MonoTouch and we saw MonoDroid. And we thought, can we apply that Xamarin magic? Can we apply the tools that were out there, before Xamarin iOS and Xamarin Android, the MonoTouch and Mono for Android, to turn it all into C Sharp? And then if we can turn it into C Sharp, can we unify this layer? Can we unify those top two layers so that we can share all of the things? So we actually used things like TweetSharp, we used things like RESTSharp, we used common libraries like SQLite, IphoneNet, in order to share those top two layers. And that filled us with joy. We love this sort of thing as techies. We really love to reuse our code and share our code and do things efficiently. We hate to cut and paste. We like cut and paste. We hate copy and paste. But we still looked at this and we still saw all of this UI logic. And we saw that on each platform, we would have this challenge where on Windows, we'd use NVVM because it's what we love. We use the data binding that's in XAML. On the iPhone, we looked and we saw what we had to do since called UI View Controllers. And it's a classic pattern called MVC. Everybody I hope in the room has heard of a Model View Controller. And it's really baked into the Apple approach and to Xcode and to MonoTouch as a result. That's how you do your eyes. And on Android, we saw we had activities. And activities, they are NVC, but actually they're pretty much code behind. So if you've done Windows Forms, it's a bit more like that. And we looked at them and we thought, well, we can't really share that code, which means we can't really test our UI logic as well. And you know, it's going to be hard work and we're going to have to replicate these things. And is there any way that we can unify those layers as well? So we thought if only we could actually just apply NVVM across the board, then if we could do that, then we could share our UI logic. We could test it once. We could have a single set for build and when we could push that out. And so this was where NVVM Cross version one was born back in November 2011. And version one was all about NVVM and it was all about providing data binding across all the platforms. So data binding. Don't worry, there's not too many slides, I promise. Data binding is there and it's what enables NVVM. Again, for those of you who haven't really experienced NVVM before, I hope it's not going to dive in too deep by not going through an introduction to data binding. But the idea is that in your UI definitions, whether it's a C-sharp definition of a UI or whether it's a XAML markup or an Android XML markup, you add some additional information that allows you to bind to the view model to the data. And so let's just dive in and build one of these. And we've got a plug-in that somebody in the community has made for us. And it's called the Ninja plug-in. And as you can probably see, I built one last night just to make sure it was working. But let's build a new one and we'll call it NDC. And this plug-in allows us, you know, normally in Visual Studio, we'll go to File New Project. We've got File New Solution because we want to target multiple things at the same time. And so we're just going to check everything on this list. We've got Droid, iOS, Windows Phone, Windows Store. And then let's hit Go. And let's hope I didn't make any mistakes there. And it's going to go off and it's going to generate these things for us. And at the end of this, we should within very short time have all of these projects. So as you can see, we start, it's giving us a nice little read-out. This is Adrien, by all means, send him a virtual beer or whatever to say thank you. This is excellent. And what you get here is you've got a simple project, just a starter project like you would with File New Project Wizard. And in there, we've got a first view model. And this first view model's just got, you know, my property in there, a standard kind of raise property change thing. And so let's just call this MVX NDC to prove it's live. And that's got what you expect of raise property change. Yeah, the coding style here is my coding style. This is obviously a very much style cop type coding style. But it's good because you can use that in your enterprises. If you've got teams and you've got resharper and you've got style cop, it really gives you that unification of feel. And you know, it does it automatically without you having to argue. So that's our basic view model. It's just got one property. And we're going to just get a data bind to it to start with. So let's just dive down and let's see dubpf. So, you know, I guessing that most of you in the room have seen dubpf data binding before. I won't even show you the designer. I can work out how to use this. And it's just the XML. And you can see that normally when you're using the data binding, you'll put in these curly brace syntax, you'll bind to my property and you'll do a two way bind. So we've got two controls here, both bound to my property. And if we hit debug start new, it'll go off and build it. And hopefully we'll get a very ugly dubpf app. But you can see, you know, it says MVX NDC. Really, I should have changed it to say hello NDC. And then we'll be tab away. The data binding happens and everything's updated. So that's your standard dubpf approach. Similarly, we've got a Windows Store and you'll see very similar XML in Windows Store. And if we run that one up, then you'll get, you know, an instant little bit of data binding for Windows Store. All sharing the same view model, all sharing that same code. So again, if it's hello NDC, we tab away and it updates. Similarly, if we have Windows Phone, you'll get exactly the same experience. We'll have to stop some of these debuggers at some point. So I'm just running the Windows Phone. Oops. No, I do need to do one thing here. I've turned off virtualization in my laptop, just because I use it for the Android emulator and an Android emulator uses it, then it means the Windows Phone can't. So I just need to turn down to the old style emulator, if it will let me. So if I go back to the Windows Phone 7 emulator and I run it up, then hopefully it will connect to this existing one. And what we should see is you get exactly the same data binding, exactly the same logic. Ah, without a keyboard. So data binding in action there. So those are the traditional platforms. Those are also the new platform for Windows. And you can see that we're sharing code automatically. We're sharing code by default. So if we've got these unit tests here, by default it's just an empty unit test that's generated, but you could put logic in there. Then you can test it. So if you want to test validation of your login credentials, then you're automatically set up when you use this approach to have that tested across all the platforms. So let's move on to the Xamarin platforms as well. And we're going to start with Xamarin.Android. And you can see what's generated here is a default Xamarin.Android project. And just I'm going to go through a bit more detail of these guys because you probably haven't seen an Android project in as much detail before. What we get is we, for every platform we have a setup file. And the setup file really doesn't do very much for a default except it tells where to look for the application and the view models. So it tells it to look in that core assembly where our view models are. We also have some linker please and clue, which is a techie detail which I'm going to pass over. We've got a splash screen and then we've got a views folder. And in the views folder we put our views. Now the views you'll notice are very much like a Windows view, you know, a page in Windows phone or in Silverlight or in Dubf. And there's very little code behind again. Instead of code behind what you get is you get a link to a resource. And these resources are XML files. Now obviously they're not XAML files. Instead of that they put the A and the X the other way around and they're A XML files. And you can see what an A and XR file looks like. There is a design that comes with Android. Let me just stop running because I'm not using so much. There is a designer which I can show you which allows you to, you know, drag and drop. I don't tend to use the designer. I'm kind of an XML guy so I just edit the XML directly. And the XML looks like this. So instead of stack panels what you get is you get a linear layout. It's exactly the same type of layout as a stack panel for those of you who use to XAML. Instead of edit text you get a text box, sorry, instead of text box you get an edit text. And instead of text block which you get in obviously all the way to XAML platforms, you get a text view. And you can see that what we've got in here is we've got normal Android attributes. So we've got things which say layout width, please fill my parent. I hope this is readable enough for even those of you who haven't seen Android before. And for layout height please wrap to whatever the height of my current content is. Text size again should be self-explanatory. But what's special, what we've introduced for MVVM cross are these extra ones, these MVX bind. And what this line says is it says please bind my text property to the my property on the view model. Now you might have expected if you'd come from Windows to see mode equal to way there. But actually I don't like mode equal to way because I always forget it whenever I'm doing XAML. And so we've kind of made that the default on an edit text because we've now got control of the binding layer. So we've made that the default. And now let's run this up. Let me just remove what I've just added. And when we run that up it should run in the emulator. And the emulator is already here. It takes a moment to deploy. Build started. Just thinking about it. And then when it deploys we should hopefully see that we get exactly the same experience as we had before. And if we edit text here you'll see that it actually edits in line so it's not that kind of delayed tab away. But you can see that it's live data binding going on. So there's a text view and an edit text bound together. So the final platform that we've got in the package here is also iOS. And unfortunately I can't run iOS live here because I did bring the Mac so I could run it and connect across a remote desktop. But unfortunately the network here won't let me connect on the ports that I want to connect. So instead of that I've pre-canned the demo part of this. I recorded it in the hotel last night. But what you'll see inside the iOS is you'll see exactly this, a very similar type of setup in terms of project. So you'll see we've got a setup. You see we've got that odd linker please include file. And you'll see that we've kind of just got some default files like app delegate and main which you get with a normal one-of-touch product. And then inside the views you'll see that we have a couple of views again. And if you look in first view then instead of having XML here we're actually doing our layout here by code. And this is the way quite a lot of iOS UIs are built in code. And you can see that what we do is we lay out and we have a UI label. So instead of a text block we've got a UI label. Instead of a text view we've got a UI label. And we put its location at this rectangle. We add it to ourselves. We then get a text field. And then there's this code here. And this code here does the binding. And you can see I hope as you read through we've got a fluent syntax. And actually it's a little bit borrowed this fluent syntax from a guy sitting in the front row there, Paul. It's a bit inspired by it by the work they've done in Reactive UI. And it enables us to bind to various properties on the view model in a very straightforward way. If you'd rather you can do it using text instead of using this kind of expression based syntax. But this is the way we do it by default. And so I'll just show you what this looks like when it runs up. This is what I recorded last night. And hopefully you'll see. So this is running inside the Mac. I just couldn't get them to remotely connect. Recorded in Oslo, recorded in NDC. And when you run this up, when this person who ever is stops wittering on the screen cast. When it runs up inside an emulator, then you'll see that the data binding is exactly the same experience as you had before. So if you edit the top one, the bottom one goes. And this gives you the testability of your UI because you can test that view model and you can test it across all your platforms. So that's binding a simple property. What else can you do? Well, so if you're used to using NVVM, then no doubt you'll think about things like, well, can I have a value converter? So let's build a value converter. And we've made portable value converters in NVVM Cross. And in order to build a value converter, what you do is you just declare one. So let's take the string and let's add a length value converter. Converter. And oops, I missed a class keyword. By all means, join in the big programming exercise, the pair programming we're doing here. And we will add, so it's going to inherit from something called an NVX value converter. All of our classes inside NVVM Cross start with the letters NVX, which is absolutely brilliant until you come to document them. And then you zoom through A to A to A2O and you get there and you get to M, A2O. I don't know my alphabet. You zoom up to M and then you have to start documenting M and it goes all to pop because every class starts with M. But we've got this NVX value converter and we'll import the namespace. And what we're going to do is we're going to convert a string to an int and then we'll implement it. We implement it by overriding the convert method. So if you're used to value converters, you'll just notice this is the same as a live value converter, except we've got no objects here, we've got strong types. And all I'm going to do is return value.length. And then I can build that. And that value converter will now be available in all my projects because it's portable. So it's available in all these projects down here. So for example, in first view in this Android, or I'm going to open it in the other editor, I can, for example, add another text view at the bottom here. Let's do it. And this text view I'm going to bind and all I'm going to do is I'm going to apply a converter and this converter is called length. And the reason it's called length is because over here it started with the word length. We use convention and we use a bit of reflection to find these things. And so now when we run up the Droid project, we should see that we'll have another text field that will show us the length of the current text. So there you go. We've got the things bound together. And again, if I start editing, then you'll see that everything updates all in sync. And that's really useful if you need to enable buttons as you change things. If you need to perhaps display how old you are as you're entering a date of birth, that type of thing, it's a really great way of putting things together. You can also combine multiple things together in a value converter. So if you need to take a first name and a gender and a last name and put them together to give a full title, you can do that using this type of approach. So that's value converters. What else do you get inside view models? Well, quite often you get a command. And so we'll add a command. And this command will be the NDC command. And so we're going to add in an NDC command. And I'll just do this in line. So if you're used to something like NVVM lights, then you'll have a relay command. We don't have a relay command. We have an NVX command, but it's a similar type concept. And when this command runs, what we'll do is we'll set my property to be equal to Bazinga. I should know some Norwegian really, so I can actually do this in local. Is Bazinga Norwegian? I don't think so. So as soon as we've added NDC command, then that's going to be available. And if we want to bind that to a UI element, then we can do it very straightforwardly, for example, by adding a button. And let's just copy some XML syntax so we can get there quite quickly. And on this button, I can bind the text to the button as well if you want to. I can bind it to the length as well. So we can apply multiple things. And then I'll also bind in the click event on the button. So if you're used to using XAML, you probably might have a behavior. Or if you're lucky, you've got a command on the control. Here we've got these events that are there. And we just bind directly to the event delegate. So the click event, we're going to bind to NDC command. And I'll run that up. And hopefully we'll see in the emulator that now we'll get a button. That button will have the text, which is going to be my property.length. And when we click it, we'll clear the text. Maybe the end of my demo has just, let me just see what was there. Why is it not loading for me? That's not part of the demo. Why is that happening? Anyone spot on the deliberate error as I typed through that? Let me remove this because it's not normally in there. But I don't see any errors that I made. Anyone spot anything? No, I do know, I think. I think the problem is at the moment that my project probably isn't set up correctly. So I probably haven't rebuilt my core. It's just in the configuration. So there's still a few little bugs to iron out in that new solution wizard. But I'm guessing if I rebuild it and then build, it'll run. If not, then I'll cut this out of the video afterwards. So there it goes. So there's your binding. If you change the text up here, then you'll see that everything updates. There's no icky find view by ID or get thing by name or get a tag or try and link all your code together and then do that. Everything updates. If you hit that, then the text changes. So that's data binding. If you wanted to do the same thing in Windows, then I hope most of you here will know about XAML. And if not, then as I said, there were some excellent presentations yesterday about that. If you want to do it in IOS, then what you would have to do is in FirstView, you would have to add some additional bindings and some additional UI controls. So for example, if we wanted to apply the converter here, then we'd do it using a with conversion. And we would just put the name in, like length, and it would work. If you wanted to bind to the command, then what you would do is, for example, if you wanted to have for the tap on the label, then you would actually put the name in like that because we haven't got a fluent expression syntax for that at the moment. So you put in that when it taps, I would like to bind to the NDC command on the view model. And you can see how IntelliSense helps you there. You can see how you can build it out. And also if you refactor that, it will refactor across the entire project solution. So that's data binding. I hope that was vaguely followable. Sorry about the mistake halfway through with not rebuilding. And you can see that for simple properties, we get, you know, Windows at the top, Android in the middle, and iOS at the bottom. And I hope that's followable for most people here. If you want to apply a value converter, then that's the way you do it. And I believe that our syntax is much neater and nicer than kind of the curly brace one that Windows has by default. And then if you want to bind to commands, then you can do it very straight forwardly. So that was MVVM cross V1. And that was the social storm project. And we were very lucky and very grateful to Microsoft and to McCann London to allow us to open source what we produced. And V1 was brilliant. It was absolutely amazing to develop these things. And we did have changing customer requirements all the time, which meant we wanted to refactor. And we did have changing Twitter APIs all the time, which meant that we were continually fighting builds. So we really, really benefited from being able to share all this code. Because if we had to develop those sacs separately for Android and iOS and Windows Phone and we had to cope with them, it would have been not so pleasant. However, V1 did have a slight dark side. And the dark side was that in V1, we didn't have a portable class library layer. So we had all this file linking going on, which meant we had separate files for every solutions round. So we had separate files for Android and separate files for iOS and separate files for Windows Phone. It was also just a bit fat as a library because it was a V1. And it wasn't so easy to extend or to play with because, you know, it was a V1. So what we needed really inside MVVM cross was we needed a hero. And I don't know where you guys look for heroes. I don't know where heroes normally hang out here in Norway. But we always look for heroes inside Visual Studio. And we found one. And our hero we found in the new project wizard. And it was the portable class libraries. And particularly version two that kind of came out in late 2011, early 2012. And what a portable class library is, is when you choose new, it allows you to target multiple platforms. And you get this little dialogue. And you know, you can say that I don't want to just target WPF applications. I don't want to just target Windows Store. I don't want to just target Windows Phone. What I'd like to do is I would like to target all of them. Now, obviously by targeting all of them, you do get a reduced API set because many of these things, you know, are based on the compact framework. And the idea of the compact framework is it's compact. Yeah, it's got a smaller memory space. So you don't get every API. But by selecting these, this reduced set, you can develop one project that will span everything. So this is what you get by default. Particularly thanks to John Popp's at Xamarin, who wrote a little blog post, which is very helpful. We found a way of getting Mono for Android and Mono for Touch in there. And this is well documented now how to do this. And I think official support for PCI is coming anytime in the next two weeks from Xamarin. So it's going to be brilliant. And once you've done that, then you'll get this API set. And this is taken from the Microsoft documentation. And if you're just targeting the things we're looking at, then what you get is you get this feature set. And so you'll get core, which is things like system.datetime and system.string and all the stuff that you use all the time. And it's really useful having that. Yeah. Don't, you know, underestimate how much value you'll get from having a single datetime and having a familiar datetime to yourselves. Because if you haven't got that, then on iOS, you'll have to know about NSDate, which is actually a long under the covers. And then you have to kind of use a calendar object to get NSDate components out, which you pass a bit. Anyway, you don't want to go there. And you'd have to know about Java. And Java is like a little peculiarity that most things are long under the covers. And there are different types of long. And if you add them together in the wrong way, it goes wrong. And then when you use a month, it's zero base rather than one base. So your code, when you cut and paste between different platforms, it'll go wrong. But it's really great to have that. Another thing that's great to have there is link. It's just brilliant. You know, we all love link. It makes it so much more productive. It makes the code so much more expressive. We've got iQueryable. We've got most of the network class library. We've got most of HTTP web request. And we're getting HTTP client in a moment. We've got serialization there. We've got most of the HTTP stuff, WCF. So if you've got legacy systems, you need to connect to from iPhones and androids and from Windows phones and Windows Store. That's the way through. We've got MVVM, which is quite useful for what we're doing. We've got Xlink. And also coming, because this is a growing API set, we've got async and await. So when I say coming, it's fully there across the modern Windows platforms. And it's in now for at the moment across Android. And I think it's in beta, sorry, across Android and iOS. So I'm not going to show much of that today, but it's coming. It's there. And this set is growing and people are working out how to extend it and extend it. And Microsoft are really quite committed to it now, not least because they fragmented their platforms more and more. And you know, Xbox One is going to come along as well. And it's really great to enable people to share it. So using this technique, what we were able to do is this is kind of, it's actually a Visual Studio 2010 screenshot. And this was taken, I guess, April last year. So just over, what, 14 months ago. And it enables to take Twitter search as one of our samples. And it enabled us to map it down to a really small sample like this. And in terms of refactoring, in terms of tooling, in terms of being able to merge in source control, in terms of the team being able to work on it, it's just brilliant. So there is slight problem, however, in the, as I say, Portable Class libraries give you a reduced API set. And sometimes you want a full API set. So what do you do when you need to access a, you know, something that's phone specific, like actually making a phone call? What do you do when you want to access geo location? Well, there are various techniques to this. You'll hear people talking about Hashif, my best friend in the world. You'll hear people talk about partial classes. But what we use, we use simple abstractions. We use interface driven development. And we've got a plug, sorry, interface driven development. And we've got a plug-in layer over the top of that. And that plug-in layer is simply a system of DLLs, which means that you can just insert these DLLs into your projects. And by convention, you'll get the right things. So again, can I just ask who already knows about IOC or do I need to? Okay. I'll quickly go through IOC. So IOC is really just about if you have things like an SQL engine, which is native or platform specific, if you have things like geo location, which is platform specific, and maybe you have a tax calculator, which is your own code, then you can declare interfaces on those. And you can put them in a big pot somewhere. And then when you need them, perhaps in a view model, then you just declare that you need their interfaces. And at runtime, you get the right implementation. So if you do the same thing and you do it on an iPhone, on an iPhone, you get an iPhone I SQL implementation, or an iPhone location implementation. And you get the same, perhaps, as a portable tax calculator. Then you put them into the iPhone pot. And then at runtime, you'll get the implementation you want. So let's quickly go back to Visual Studio, because I get bored of PowerPoint. And let's close this solution where we started. And let's show you a different way of building a project. And so what I'm going to do is let's create a new portable class library. And so we start here in Windows, and there's a portable class library. And so this is going to be called NDC kittens, which might tell some people what's coming up. You can't have a demo without kittens, zombies, gambling or sex. It's got to have something of that commitment to it. Or maybe an optocat is also available for the GitHub in the audience. So we're going to create NDC.core. And you'll get this dialogue, particularly if you modded it. And we can't support original Windows phone, but that's okay because all the Windows phones have been upgraded to Mango at least. And we hit OK, and Visual Studio goes off and implements it. And then what you can do is obviously this has got no coding at the moment. It's got this class one. We'll get rid of that. And I hope this doesn't make a loud noise. No good. So what we will do is we'll manage the new get packages, and we'll pull in, and I'm not going to use the network because it'll be too slow here. So we're going to pull in MVVM cross. And by default, when you pull in MVVM cross, then you get given an app.cs, which just tells you a little bit about how to initialize your IOC. So it's basically saying that anything ending in the word service, I'm going to put into that IOC pot, into that inversion of control. And then it also says, please, when my app starts, just show the first view model, however you do that on your platform. So what we're going to do is we're going to take a look at first view model, and it's got some default junk in there. We'll get rid of that. What we'd like to do is we'd like to do some SQL work, because that's a plugin that's going to be native on each platform. So let's go and find the SQLite plugin. So we're going to go back to new get, we'll get a local package, and there is a SQLite plugin. And we're going to install it into our portable class library. And once we've done that, then I'm going to not type this live because it would take too long, but I'm going to use a snippet. And this snippet is handily called kittens. Oops, if I could use a snippet. And what you'll see is this pulls in a first of all, it pulls in an ORM class. So it's just a, you know, data entity, which is a kitten. And each kitten has an ID, which is primary key. So if you use the databases, you'll be familiar. It's got a name, it's got a price, and it's got a kitten URL, we'll see a cute kitten. I've then got a service. So if you remember that IOC initialization code, it's going to look at that keyword of service. It's going to think that's special. I'll put that in the pot at the start up. And this is just a way for me to create random kittens so that we can have something to see at demo. And we then got this kitten Genesis service and this kitten Genesis service. Again, I'll just import the namespace. We'll generate me some random kittens and these are the top 20 kitten names on the internet. And then we've also got a data service. So this is our actual kind of repository, if you like. And I've just put some CRUD methods on the repository. So the insert, update, and delete. And then I've also put this select method, which is kittens matching. So that's the interface. And the implementation looks like this. And you'll see that the implementation in its constructor, it's going to take two things. It's going to take a SQL like connection factory. And that's something that's going to come from that SQL like plug-in. On each platform, we'll get a different one. And then we've got a kitten Genesis service. And that's the mock data service up above. So all it's going to do on startup is it's going to try and create the database. It's going to make sure there's a table in there for kittens. And if there aren't any kittens, then it's going to seed it with some random data for me. And if you take a look at what the, and again, I'll just pull in, that's Iquirible coming in. If we take a look at what the methods look like, then the CRUD methods are really simple. They're connection insert, connection update, and connection delete. And the select method is the lovely link-like syntax that we all love, the order buys, the wares, the to lists. So you get full, look, full intelligence in here and everything you really enjoy as a C-sharp developer. So that's our data service. Let's now use that. So back in our view model where we haven't got anything, in the constructor, I'm going to get hold of a data service. So I'll create a private member called data service. And then I'll initialize that from the constructor. And then what I'll do is, let's see, let's use kittens matching. So I'm going to create a property called filter. Yeah, and so that's called filter. And you can see the syntax there for raised property change, which I hope is what you're all used to and expecting. And then I'll create another property. And this property is going to be a list of kittens. And we'll have underscore kittens and kits. And then what I need to do is tie them together somehow. So what I'm going to do is, whenever my filter changes, then I'm going to call update. And let's also call update from the constructor so that we get something on startup. And let's also set the filter to a default value. And that can be C, because I think I saw some kittens with an aim of C. So the only thing I haven't implemented at the moment is update. And update is a pretty simple bit of C sharp, I think. So what I need is that when I'm updating, I'm going to ask my data service to for the kittens which match my filter. Yeah. And that's my core project done. Obviously, I can put a unit test on that. And when I put a unit test, I can pass in a mock data service. And that should work and should give me, you know, real reliability in my UI functionality. So I'll build that. That's built. That's my view model. I could connect a command line console app to that if I want to. But let's, how am I doing time wise? Oh, I'm talking a lot. So let's build a Android app to talk to it. So we go to Android. We go to Android application. And I call this ndckittens.core. So what I'll call the Android application is ndckittens.droid. And Android, if you, this is just the default Xamarin template. And you'll see you get, you know, an activity and you get some resources which are XML. I don't want the default activity because I want nvm cross functionality. So what we do is we go to new get again. And this time we'll pull in nvm cross, the core. And we will pull in SQLite because we want the native SQLite for Android. And this really will. It will be the C++ component that's sitting inside the Java layer and sitting inside Android. So we'll pull it in. And once we've done that, what you'll see is you'll get these default files like set up. And set up is saying please run core.app. So we're going to have to reference that core project. Let's do that. Add reference. Reference the core where the view model is. And then once we've done that, we'll just need to do our data binding. So let's do that. Obviously, we've got a first view generated here by default as well. And that's just going to use this XML file. So let's do our data binding. So let's go to our first view. And by default, we've kind of got this hello example. That's not so useful for us. So what do we want? We want an edit text or a text box at the top. And we're going to bind that to a filter. And then underneath, we want a list. So how are we going to do a list? So if you were doing vanilla Android, you would do a list view. And then you'd give that list view an Android ID with some horrible syntax. And then in the code behind, you would get hold of that. And then you would create another class that is called an adapter. And you would inherit from that adapter. And then you would put in the adapter some get view functionality. And then you would also put some get. Anyway, we're not going to do that. Phew. What we're going to do is we're going to add the magic letters of NVX to the front of this view, which is a class that understands data binding. And in particular, what it understands is just like in WCF and in Silverlight, it understands item source. So I hope this is big enough for everyone in the audience to see. We don't need text size anymore. We do want it to fill the parent with this particular thing. So it's a list and it's going to be big. And we want to bind the item source to the kittens. So hopefully, unless I've made a mistake, we can run this up. Let's have a go. Debug start new. Build started. It's a nervous moment for me. Did I forget anything? Coping applications. Well, it built. It built that ship. It's only fair. So it's running up. And you can see what we've got is we've got some data binding at the top where we bind this thing. And if we start typing, then there are still some kittens with C and O in there. If we go for R, there's no kittens left. Now, that's brilliant, isn't it? Except this is a little bit, yeah, that's just string. We don't really want to string on there. So we've got our RUI working to a first level. But now we need to have a data template for each list item. So if you've done as Amal, and again, apologies for those of you who haven't, I'm moving forward as quickly as I can. Then what you do is you apply a data template. So we're going to do the same thing here. And what we're going to do is we're going to have an NVX item template. And we're going to reference another XML file that's over here in the layout folder. So to do that, it's a little bit of Android syntax. It's layout slash. And then it's the name of the file we want to use. So I'm going to call this file item kitten. And the reason I use kind of these prefixes is just because Android has this horrible flat file thing. And so it's the only way of grouping them together. You can't use subfolders. So that's why I've used prefixes to try and group my resources files together. So that's it. I'm going to use item kitten. And let me just, I'll copy and paste first view. And I will create item underscore kitten. And what do we want in item kitten? So let me remove this. And what we'd like is we would like to have, let's just do a layout which is going to be horizontal. So it's a stack panel. It's going to go across the page. And let's do a image, first of all. And so this is going to be an NVX image view. And we're going to give this a fixed height, oops, NVX image view. We're going to give this a fixed height and width. So we're going to say this NVX image view should be, let's make it 100 dp, which is a fixed unit, and 100 dp. And obviously we'll have to terminate that. And then what we would like to do is we'd like to put the image in there. And I'll come back to that in a moment. But what we'd also like to do is we'd like to put a text view in there. And so the text view we're going to bind to the name. So let's just do the layout width is going to be filled parent and the layout height for the text view is going to be wrap content. And then let's, and again, you can use the designer for this if you prefer. Let's put the font size again, a bit larger so you can see it. So text size equals 40 dp. And let's then bind. So we're going to use local colon NVX bind. And we're going to bind the text to the name of the kitten. So that's the text view done. The remaining thing is really this image view. And what we'd like to bind on the image view is a property called image URL. And the property we'd like to bind it to is to the kitten URL on the kitten. So we do that. And let's just put that together. Now there's one more thing you have to do for Android, which is because, and like with Windows, you're used to the fact that if you just bind images, then they automatically get downloaded using the Internet Explorer cache and they get put into your application. Yeah, with Android, you don't get that. So there's another plugin we have to add just for Android. And basically we have to add the, oh, I have got that one now. Basically we have to add the download cache plugin. And the download cache plugin also relies on the file plugin in order to store these things as files. So you install those and all they've done is added some references in here. And then we should be able to run this up. And unless I've made a mistake, then we should be able to see some prettier lists on our screen. So I hope so. So there's our list. And if we start filtering, so if we start filtering down, then we remove the filter to start with. Then we get all of our kittens and these are in price order because that's the way we set up our thing. And then if we start typing and we'll just look for the pollies of the world. So if we start typing for polly, then hopefully we get pause and polly together in this list and Pepsi. And if we start PO, then we get just the pollies in the list. POL will still get them. If I misspell polly, we lose them all. So that's data binding working. There's no C-sharp code behind in the UIs. Everything's testable and that's the way our applications put together. I've overrun a bit so I won't go fully into the iOS demo to do the same thing. But what I will do is return to the slides and just show you. So this would be what the windows would look like for a list for data binding. For Android, you've just seen. You kind of use these templates. And for iOS, what you can do is you can define table view sources and it's the same sort of approach. And it allows you to bind these things together. And if you want to do custom cells, you can do it. So I'll just skip forward and show you a little bit of this movie. So if you want to do custom cells, then let me just find some custom cells in here. Then you should be able to declare them using the interface designer. So there is a designer for iOS, but it produces really not human-friendly XML file, should we say, called nibs or zips, depending on how you're feeling like saying them. And these files are not the easiest to use. So one of the things you'll discover is people don't use them if they want to use source control very much because they change every time you edit them. So it's very hard to do merges. It's very hard to do team efforts where you want to merge them together or to do revision history and source control. So that's what you do. And then when you put this together as an actual app, you will hopefully see something like this where you get a custom list and you'll get the kittens and the prices, et cetera. So sorry that I can't demo that live, but as I say, the Mac wouldn't connect on the network here, so I couldn't do that. Okay, so that's lists. And that's also, I hope you saw, plugins. So I hope you saw issues in the SQLite plugin. It's the same for other plugins like network plugins and messengers and camera if you want to access and take pictures. And the best thing about this plugin list is it's extensible. Yeah, so if you want to create your own plugins, it's really simple to do. You just create an interface in a core portable class library, like, you know, this is the vibration sample. There's a little bit of boilerplate code so that it'll help the conventions along to load it. And then after that, you can create platform-specific ones. So here's the vibration plugin that works on Android. And that's a native library that plugs in. The most famous example for plugins was the Spharo example I did. So this was a controller for Spharo, which is a robot which kind of glows and spins and does all sorts of things. And this was a, hopefully I won't get sound on this. This is an example we did in Evolve out in Texas. Well, we controlled seven of these from a phone. And this is cross-platform code. So this isn't your typical NVVM sample. You know, this is controlling robots using accelerometer, using speech, using all sorts of native services. But this is what we managed to put together so that, you know, you can see, hopefully, these are going to do a little dance and jig around the room and all sorts of things. So think about it as you move forward into future, you know, platforms. It's not just about static UIs on screens. It's also about speech, obviously Siri and things like that. It's also about controlling external factors and the Internet of Things. So that was the most famous example, perhaps. And that was what NVVM Cross Vnext was all about. It was all about PCLs and plugins. And NVVM Cross was really, Vnext was amazing. We really, really, really loved NVVM Cross Vnext. However, it did have a bit of a dark side. And the dark side was the getting started was described as a learning cliff that most people had to really kind of build it from source. They had to go to GitHub and download it and work out. And it also had some quite of a boast of very long class names, in fact, very, very long class names. And so we knew that we needed to evolve. And so the path that we took for, oops, I'll destroy myself. Hopefully, I've still got sound. The path that we took for our evolution is really a path from NVC, which most of you know has been around since the 70s. I seem to have heard it was invented in Norway, but I may be wrong. And it's been around since the 70s and it's model view controller. And in the middle of the 2000s along came Microsoft and John Grossman and the team inside Vista and Longhorn. And they produced NVVM, which relies on this data binder to have this view model, this model of the view. And this was middle 2000s. It hasn't really changed that much since. There are some notable exceptions, reactive, for example. But what we are heading towards is model view cross platform. And we're really looking at how that code can be shared and can be really empowered across multiple platforms. And it's not just about these phone platforms, it's also about the Xbox. It's also about Google Glass. It's also about TVs. It's also about the future. And the things we've added in the recent things, you've seen quite a lot of them. You've seen the clean binding. We've added Android fragments. We've added WPF. We're adding.Mac. And this is still a work in progress. We've still got a few things outstanding. But at the moment, NVVM cross V3, which is what you've kind of seen demoed, is amazing. And we really love it. And it doesn't have a dark side. And it is a work of awesomeness. There are a lot of people who built it and have contributed. And all of these people, I thank them. And I put them in every presentation to thank them. People are spotted people, they know. And it's a really huge thanks to them. And it's thanks to them that we now have samples like we've got, for example, a fractal sample. So this again is data binding. It's data binding to a mathematical model with a huge bitmap. And you're binding to this image at runtime. And generating at runtime. And this is cross platform. It's across all four of our key targets. So I can also show that running on iPhone. And it's actually very interesting to run it on a retina iPad. Because you get to see some limits of memory and some limits of calculation as you do this. So it's exactly the same code, exactly the same controls around and that UI is. And we can build that forwards. We've also got plenty of other samples. We've got things like Internet minute, which is a scary thing to watch because it tells you what's happening at the Internet in real time. So you can see all the botnet infections that are happening around us. You can see all the apps being downloaded. The email sent is just hideous to look at. And we've got other things that we can show there as well. In terms of real apps, well, obviously, Connect Star Wars was where we started. It's no longer really available because Twitter's broken the API and that, you know, there's no longer a huge need to sell that game. So I won't show you the video for Connect Star Wars. We've got things like this is a company called Bruel and Kaia from Denmark. And they are international. They are leaders in noise and vibration monitoring. And what they have is they had an installed base of Silverlight apps. So NVVM and Silverlight. And obviously Silverlight was no longer the future. And what people were asking for is can I have it on my iPad, please? Can I have it on my Android? And so they took a NVVM across version one and they ported it. So it's not just about text fields on the screen. It's also about maps. It's also about these heat bars. It's about charts. It's all data bound. It's all data bound to the same view models across three different platforms. And it's fabulous. It's by a guy called Thomas, particularly from Cheesebarron who's done this. And it gives them a testable platform for the future. There's a company called Centra Stage who do monitoring and all this thing of networks. And so they allow you to log in. And so they took their web-based system and their kind of desktop trade thing on PCs. And they plugged it in and they managed to build this iPhone app. And obviously their users were all using iPhones and they wanted them. And now their users are all using Android and they're porting to Android. And also they've ported the same thing to Mac desktop. So exactly the same code using Xamarin.Mac now runs on Mac desktop. We don't have this in the core framework at the moment just because we're waiting for a little bit of PCI support before we make the big effort of putting it across. But this is the future again. When a new platform comes along we can do it. And all of the things like the Sony platforms for example are all C-Sharp which is brilliant. And hopefully as well the Microsoft ones will be if they work it out. So Aviva was one of the, again a version one customer. And they've got this platform that monitors your driving and gives you a score out of ten about how safe you drive. And then we'll give you a discount depending on how safe you've driven. I presume there's an underground current where you try and score zero. I don't know. But again this because it was an insurance app and because insurers don't take any risks at all this needed to be heavily tested. It needed to work across both platforms. It had quite a lot of background code looking at geolocation and things. And so this was again another app. The final app I'll talk about is the Lions app. So this is a rugby tour. I'm not going to make the joke I made in America about rugby because I was worried about Texan shooting me. I'm not going to. I'm not going there. But so this is rugby tour. It's very rich. It's very consumer. It's kind of a magazine thing. But it's also got live stats during games. It had a competition in there. It's on Windows phone. It's on Windows 8. It's on iPhone. It's on iPad. It's on Android. It's on Android tablet. It's also on the Kindle tablets. And this was built in two months by a group of three C-Sharp engineers who didn't know mobile. Yeah, they knew ZAML. They didn't know any of the mobile platforms. And back to front, it's C-Sharp everywhere. So on the server, they use a CMS, which is Umbraco, which talks to SQL Server using entity framework. It's then got this web API front end, which is C-Sharp. It uses a PCL block of entities. Yeah, so all of the JSON objects that go across the web API, those are PCL codes. So it's shared between the server. So that's another one of our platforms, really, and the client. The core logic is also always in a PCL. And all of the UIs are in PCLs. So the SQLite on the local database is also the C-Sharp DRMs. So anywhere in there, any of the engineers can feel comfortable. It's not like, oh, that's the iOS code. I can't touch it. It is all C-Sharp. It's all refactored. It's all got IntelliSense and resharper navigation support. In terms of lines of code, and this is kind of where they, these are their genuine numbers of version one, you'll notice that actually some of the code isn't that shared. Like, there's quite a lot of UI code in the iPhone and iPad, for example. The main reason for that is because they wrote a lot of custom controls, and also they didn't want to use these Zibs, so they wrote everything in C-Sharp there. But what's important is everything they wanted to share in the PCL code they could share. Yeah, just the animations and things like that and the layouts on the individual platforms they didn't share. So that is MVVM Cross, and I'm running about right on schedule. And MVVM Cross is very much still a growing platform. Yeah, V3 is hopefully our final big revision. We have cleaned things up quite a lot. But MVVM Cross is still learning, and the path that we have gone along in the last year, in the last 18 months, is we started with version one, which was really about, you know, everything we do is pretty much driven by real projects. There's no point in making up requirements. We've got plenty of requirements, which are real. But it was really about supporting IE Notify property changed on the three platforms. Version two was the real requirements was to make things more maintainable and to allow us to work in bigger teams. I mean, you know, things like the insurers have very big teams of developers, and was allowed to make really testable code. So that was PCLs in version two. Version three is about cleaning it up, adding.mac. And then the future, and the future is wide open, obviously, but it's pretty darn exciting. And what we're looking at now is we're looking at, you know, as I say, MVVM itself has been fixed almost since 2005, and we're looking at other ideas. What else can we do in our view models? If you look in the JavaScript world, where Angular and where, and where things like Knockout have come along, they've done really exciting things in their view models and their bindings. Some of those things, like the computer observables, can they come back into our world? Can they come back and change things? And to some extent, we're now free of Microsoft and we're free of XAML because we've got our own binding framework. So it's a really exciting time in terms of moving forward. Obviously, async, I haven't shown you much of. I can show you a quick. So there's a guy called John Dix who has produced, do you know what Jabra is? It's a chat room or online using SignalR. And he's produced this Android app as a first demo. And at the moment, this Android app can connect and can talk to all the rooms that allows you to post messages, et cetera. And yesterday, I ported that same code across. And it's not pretty yet, but I ported the same code across just by using XAML bindings. So hopefully, this would connect. And I can join the MVVM cross room and I can type in what's up and be immortalized forever that that has been sent into the thing. Oh, there are some more messages at the bottom. So it's a very much a first UI. I'm not going to ship this one to the store. But you can see that everything is in there. And you can pull about the rooms. And all of these pages, you can pull about the rooms. Maybe you can't. And you can join another room. You can do all that. And this is async await code. This is all our modern C sharp and is the future. So it's very exciting. We also have auto views. We have the idea of some of the UIs could actually be constructed centrally, which is kind of based around dialogue. There's a lot going on around F sharp. I don't know if you've noticed this conference. There are a lot of functional programming sessions and F sharp. FOD is an AOP approach. The ninja ID you've seen, but there's also a plug in ID being built for Xamarin Studio, which is brilliant. We're looking at how we can integrate into designers more. You know, I'm kind of XML based, but I understand designers. As Guy in Holland, who's produced proto pad, which is a bit like a link pad for UIs. It's brilliant. There's more patterns we can do. And I can show you that, for example, this is a guy called Pan Homes in Tenerife, who's produced an F sharp view model and an F sharp view. So there's no reason you can't use our C sharp code in F sharp. And things like that fractal sample, I'd love to see how that really gets much smaller in F sharp. And much more flexible and much more tested. And then there's also, so this is the FOD. And FOD, I don't know if you can see this. Let me show you. So if you use FOD and apologies that it's out of focus doing that, then you don't have to do all of that raise, not property change stuff, because it will inject that for you afterwards. All you do is you decorate your class with implement property change, and then it'll come along and actually automatically generate it. And the amount of effort you have to go to get this working is you have to put that attribute in, and you have to pull in the package from NuGet. So that's it. And the future for things like that is also very exciting with things like the compiler from, you know, the Roslin compiler. So hopefully we've covered some of this today. Sorry if I didn't go into introductions as much as I perhaps suggested I would. And hopefully you've got a good idea about how MVVM and data binding can be applied across all the platforms from this. And that is my hope. It's a new hope. And I hope that if you face a future challenge of any description like we did with Star Wars, then I hope you can keep calm and you can write some code. And I also kind of sneakily hope that you can keep calm and use MVVM across. So thank you very much for listening today. Amazingly, I have four minutes left, which is quite unexpected. So if there are any questions, I can actually answer them, or I can demo some more code or anything else. Anyone got any questions? Oh, there are also stickers. So if anybody likes to decorate their laptops, then by all means come and grab me and grab some stickers. Can I do, sorry? So partial views, you mean kind of user controls? Yeah, so yes, you can do partial views. Oops, that's a bit of Darth Vader coming back. Yes, you can do partial views on every platform. So with iOS, you can have a UI view controller for a specific area and give that its own iNotify property changed object and it will work. Similarly, you can do it on Android using either fragments or using our own control, just called MVX Frame Control. You just give its own data context. You can change that data context and it will change and update automatically. You can use it as a dialogue if you want to. You can use it within tab views. That's the way the tabs work. So yeah, it's exactly as you expect. And you, we do have a navigation model. We allow people to use it on our navigation service. But you can also, if you want to, replace that entirely. And you can just manually set up a view and say, here's your data context and go. So for example, the list view is done on exactly that philosophy. So every cell in that list view has its own kind of data context. And the binding works two way on that as well. So there are several ways of communicating through view models. Like you can actually just give them C sharp references if you want to. There is a messenger plugin which will allow you to use the messenger pattern. And that messenger pattern uses weak references by default. So you don't have to unsubscribe. It just kind of unsubscribes itself when you get garbage collected. Or you can use any other messenger if you want to. So if you want to use something like the great tiny messenger, you can use it. So yes, that's the main way that we set up that type of messaging. And you can also use that messaging back to the UI if you want to or between services. That side of the architecture, I deliberately leave very open for people just because there's so many ways you can build these things. And that's to allow it open. So the way you do that is you would have to do a little bit of code behind. And I don't think I've got a sample available by pre-recorded. But basically on every platform you do have to generally override. There's two methods you have to override. One is where you first register the templates on each platform. And the other is where you choose which template you're going to use for a particular object. But there's a very nice sample, for example, which are kittens and puppies, exactly that on iOS. And also if you're using observable collection, then all of your observable collections, your iNotify collection changed, they work across all platforms. And particularly on iOS, iPhone has, you know, the table view is its heart of iPhone. Every standard control, every standard app in iPhone is a table view, is that list view. And it's wonderful when you actually add an observable collection, you get an animated slide in. It's exactly what you expect for that. When you delete something, you can animate how it fades out, for example. So yeah, that templating again is available. You do have to do a little bit of code to choose which template you're going to use. But it's there. And basically on Android, for example, it would just be another file and then two lines of, you know, switch statement, for example, in C sharp. Okay. Is that it for questions? Okay. So you can all go and have a break now. And this was a picture from Worldwide Developer Congress this week of the breaks. And it's quite funny, but it's also not funny because this is, we need to get some more people in that left thank you. And I don't mean gents move over. So if anyone's got any ideas of developer community, how we get more and more females involved, please tweet it. Please try and work out how we solve this. Because I do some, a little bit of work with young, rewired state. And young, rewired state see 50% females all the time. And some of them are up to 70%. So, you know, we're doing something wrong as a profession. Sorry. A little bit of a political bit at the end. But if you can think of any ways of improving that, I'll go and have a break. Thank you very much, guys.
 Good morning. I think we're ready to go. So let's kick into this. This morning's session,  I hope you're all in the right one, is about sharing C-Sharp and it's about using NVVM  to do that. We're going to look at all of the modern platforms. So we're going to look  at all the Windows platforms and we're also going to look at Android and iOS and we're  going to look at C-Sharp across them. There are other modern platforms. There's obviously  the Xbox coming along, the Xbox One. And there is also the new modern platforms like, you  know, PlayStation 4 is coming along, PlayStation Vita, Google to us. All of these are coming  along and all of these will be home for C-Sharp. So what we put in the abstract about what  we talk about is all of this. But I know that, actually can I just ask, who here already  knows about NVVM and does NVVM kind of a... Okay, so it's pretty much the majority of  you. So particularly after all the great sessions that were yesterday from Laurent and Gil and  from Rocky today before about NVVM, I'm going to not go too deep into the NVVM introductions.  But also with the sessions that are coming up from Craig, I'm not going to go so deep  into the introductions into Xamarin iOS and Xamarin Android because you've got plenty of  opportunities to do those later. But what I'm going to try and concentrate today is  really on the core of what I can bring benefit, I hope, to you guys with, which is NVVM on  the modern platforms. And it's about how you can extend portable classes to bring native  features. So in particular, I hope you get to leave here today with kind of a good understanding  about how you can use NVVM across all the platforms. So what I'd like to do is I'd like  to spend the next hour, I'd like to spend the next hour telling a story. And this story  is going to start in a very good way. It's like a classic story. And it's going to start  a long time ago, actually November in 2011, in a galaxy far, far away called London. And  it starts with a project called Social Storm. And it was for the Connect Star Wars game.  The idea was to bring an app together that would bring together streams from Facebook,  from Twitter, and from Xbox. And it would bring them together on Android, and iPhone,  and on Windows Phone. And it would enable kind of this, you know, rich scrolling effect.  It would enable mini games. It would enable features on top of your social streams that  would get you talking about the game. And the idea was you talk about the game, and then  hopefully people would buy the game, they'd hear more about the game. And that was the  whole point of this app, this project. So we looked at it from a technical perspective,  because I'm a techie. I look at things from a geekie. And we could see all of these layers  of things we'd need to write. And we could see, you know, there was service consumption,  about network data, and local data, and GPS, and all sorts of things we'd need. There was  app logic about, you know, if you're going to a certain place, you do this. If certain  tweets came in, you do this. There was all that sort of thing. Then there was UI logic  about how you logged in, about how you retweeted, about how you tweeted. And then at the bottom,  there was the whizzy stuff. There was the stuff that we really wanted to make sure we had,  because we wanted to provide delightful user experiences. So there were animations, there  was nice layout, there was nice graphics, there was retina graphics on the right platforms.  So there was real, like, concentration on making sure we had that. And so we looked  at it, and we knew that we, first of all, had to support Windows Phone. Windows Phone  meant that we had to support C Sharp, yeah. And then we were asked for native. So we knew  for iPhone that the classic route at the time would be go objective C. And then we knew  that we had Android. So we knew that we'd have Java. And we looked at this as a bunch  of techies. And there were five or six of us involved in this. It was a techie project  that was Pavel and Matt and John and a couple of others. And we looked at this, and this  didn't fill us with joy at all, because we thought we're going to have three stacks.  We're going to have a project where we want to do releases over a period of ten months.  We're going to have to maintain these three stacks. We're going to have separate bugs  on each platform. We're going to have separate features on each platform. Maintaining them  is going to be hideous. So we looked and we saw MonoTouch and we saw MonoDroid. And we  thought, can we apply that Xamarin magic? Can we apply the tools that were out there,  before Xamarin iOS and Xamarin Android, the MonoTouch and Mono for Android, to turn it  all into C Sharp? And then if we can turn it into C Sharp, can we unify this layer?  Can we unify those top two layers so that we can share all of the things? So we actually  used things like TweetSharp, we used things like RESTSharp, we used common libraries like  SQLite, IphoneNet, in order to share those top two layers. And that filled us with joy.  We love this sort of thing as techies. We really love to reuse our code and share our  code and do things efficiently. We hate to cut and paste. We like cut and paste. We hate  copy and paste. But we still looked at this and we still saw all of this UI logic. And  we saw that on each platform, we would have this challenge where on Windows, we'd use  NVVM because it's what we love. We use the data binding that's in XAML. On the iPhone,  we looked and we saw what we had to do since called UI View Controllers. And it's a classic  pattern called MVC. Everybody I hope in the room has heard of a Model View Controller.  And it's really baked into the Apple approach and to Xcode and to MonoTouch as a result.  That's how you do your eyes. And on Android, we saw we had activities. And activities,  they are NVC, but actually they're pretty much code behind. So if you've done Windows  Forms, it's a bit more like that. And we looked at them and we thought, well, we can't really  share that code, which means we can't really test our UI logic as well. And you know, it's  going to be hard work and we're going to have to replicate these things. And is there any  way that we can unify those layers as well? So we thought if only we could actually just  apply NVVM across the board, then if we could do that, then we could share our UI logic.  We could test it once. We could have a single set for build and when we could push that  out.  And so this was where NVVM Cross version one was born back in November 2011. And version  one was all about NVVM and it was all about providing data binding across all the platforms.  So data binding. Don't worry, there's not too many slides, I promise. Data binding is  there and it's what enables NVVM. Again, for those of you who haven't really experienced  NVVM before, I hope it's not going to dive in too deep by not going through an introduction  to data binding. But the idea is that in your UI definitions, whether it's a C-sharp definition  of a UI or whether it's a XAML markup or an Android XML markup, you add some additional  information that allows you to bind to the view model to the data.  And so let's just dive in and build one of these. And we've got a plug-in that somebody  in the community has made for us. And it's called the Ninja plug-in. And as you can probably  see, I built one last night just to make sure it was working. But let's build a new one  and we'll call it NDC. And this plug-in allows us, you know, normally in Visual Studio, we'll  go to File New Project. We've got File New Solution because we want to target multiple  things at the same time. And so we're just going to check everything on this list. We've  got Droid, iOS, Windows Phone, Windows Store. And then let's hit Go. And let's hope I didn't  make any mistakes there. And it's going to go off and it's going to generate these things  for us. And at the end of this, we should within very short time have all of these projects.  So as you can see, we start, it's giving us a nice little read-out. This is Adrien,  by all means, send him a virtual beer or whatever to say thank you. This is excellent. And what  you get here is you've got a simple project, just a starter project like you would with  File New Project Wizard. And in there, we've got a first view model. And this first view  model's just got, you know, my property in there, a standard kind of raise property change  thing. And so let's just call this MVX NDC to prove it's live. And that's got what you  expect of raise property change. Yeah, the coding style here is my coding style. This  is obviously a very much style cop type coding style. But it's good because you can use that  in your enterprises. If you've got teams and you've got resharper and you've got style  cop, it really gives you that unification of feel. And you know, it does it automatically  without you having to argue. So that's our basic view model. It's just got one property.  And we're going to just get a data bind to it to start with. So let's just dive down  and let's see dubpf. So, you know, I guessing that most of you in the room have seen dubpf  data binding before. I won't even show you the designer. I can work out how to use this.  And it's just the XML. And you can see that normally when you're using the data binding,  you'll put in these curly brace syntax, you'll bind to my property and you'll do a two way  bind. So we've got two controls here, both bound to my property. And if we hit debug  start new, it'll go off and build it. And hopefully we'll get a very ugly dubpf app.  But you can see, you know, it says MVX NDC. Really, I should have changed it to say hello  NDC. And then we'll be tab away. The data binding happens and everything's updated.  So that's your standard dubpf approach. Similarly, we've got a Windows Store and you'll see very  similar XML in Windows Store. And if we run that one up, then you'll get, you know, an  instant little bit of data binding for Windows Store. All sharing the same view model, all  sharing that same code. So again, if it's hello NDC, we tab away and it updates. Similarly,  if we have Windows Phone, you'll get exactly the same experience. We'll have to stop some  of these debuggers at some point. So I'm just running the Windows Phone. Oops. No, I do  need to do one thing here. I've turned off virtualization in my laptop, just because  I use it for the Android emulator and an Android emulator uses it, then it means the Windows  Phone can't. So I just need to turn down to the old style emulator, if it will let me.  So if I go back to the Windows Phone 7 emulator and I run it up, then hopefully it will connect  to this existing one. And what we should see is you get exactly the same data binding,  exactly the same logic. Ah, without a keyboard. So data binding in action there. So those  are the traditional platforms. Those are also the new platform for Windows. And you can  see that we're sharing code automatically. We're sharing code by default. So if we've  got these unit tests here, by default it's just an empty unit test that's generated,  but you could put logic in there. Then you can test it. So if you want to test validation  of your login credentials, then you're automatically set up when you use this approach to have  that tested across all the platforms. So let's move on to the Xamarin platforms as well.  And we're going to start with Xamarin.Android. And you can see what's generated here is a  default Xamarin.Android project. And just I'm going to go through a bit more detail  of these guys because you probably haven't seen an Android project in as much detail  before. What we get is we, for every platform we have a setup file. And the setup file really  doesn't do very much for a default except it tells where to look for the application  and the view models. So it tells it to look in that core assembly where our view models  are. We also have some linker please and clue, which is a techie detail which I'm going to  pass over. We've got a splash screen and then we've got a views folder. And in the views  folder we put our views. Now the views you'll notice are very much like a Windows view,  you know, a page in Windows phone or in Silverlight or in Dubf. And there's very little code behind  again. Instead of code behind what you get is you get a link to a resource. And these  resources are XML files. Now obviously they're not XAML files. Instead of that they put the  A and the X the other way around and they're A XML files. And you can see what an A and  XR file looks like. There is a design that comes with Android. Let me just stop running  because I'm not using so much. There is a designer which I can show you which allows  you to, you know, drag and drop. I don't tend to use the designer. I'm kind of an XML guy  so I just edit the XML directly. And the XML looks like this. So instead of stack panels  what you get is you get a linear layout. It's exactly the same type of layout as a stack  panel for those of you who use to XAML. Instead of edit text you get a text box, sorry, instead  of text box you get an edit text. And instead of text block which you get in obviously all  the way to XAML platforms, you get a text view. And you can see that what we've got  in here is we've got normal Android attributes. So we've got things which say layout width,  please fill my parent. I hope this is readable enough for even those of you who haven't seen  Android before. And for layout height please wrap to whatever the height of my current  content is. Text size again should be self-explanatory. But what's special, what we've introduced  for MVVM cross are these extra ones, these MVX bind. And what this line says is it says  please bind my text property to the my property on the view model. Now you might have expected  if you'd come from Windows to see mode equal to way there. But actually I don't like  mode equal to way because I always forget it whenever I'm doing XAML. And so we've kind  of made that the default on an edit text because we've now got control of the binding layer.  So we've made that the default. And now let's run this up. Let me just remove what I've  just added. And when we run that up it should run in the emulator. And the emulator is  already here. It takes a moment to deploy. Build started. Just thinking about it. And  then when it deploys we should hopefully see that we get exactly the same experience as  we had before. And if we edit text here you'll see that it actually edits in line so it's  not that kind of delayed tab away. But you can see that it's live data binding going  on. So there's a text view and an edit text bound together. So the final platform that  we've got in the package here is also iOS. And unfortunately I can't run iOS live here  because I did bring the Mac so I could run it and connect across a remote desktop. But  unfortunately the network here won't let me connect on the ports that I want to connect.  So instead of that I've pre-canned the demo part of this. I recorded it in the hotel last  night. But what you'll see inside the iOS is you'll see exactly this, a very similar  type of setup in terms of project. So you'll see we've got a setup. You see we've got that  odd linker please include file. And you'll see that we've kind of just got some default  files like app delegate and main which you get with a normal one-of-touch product. And  then inside the views you'll see that we have a couple of views again. And if you look in  first view then instead of having XML here we're actually doing our layout here by code.  And this is the way quite a lot of iOS UIs are built in code. And you can see that what  we do is we lay out and we have a UI label. So instead of a text block we've got a UI  label. Instead of a text view we've got a UI label. And we put its location at this rectangle.  We add it to ourselves. We then get a text field. And then there's this code here. And  this code here does the binding. And you can see I hope as you read through we've got a  fluent syntax. And actually it's a little bit borrowed this fluent syntax from a guy  sitting in the front row there, Paul. It's a bit inspired by it by the work they've done  in Reactive UI. And it enables us to bind to various properties on the view model in  a very straightforward way. If you'd rather you can do it using text instead of using  this kind of expression based syntax. But this is the way we do it by default. And so  I'll just show you what this looks like when it runs up. This is what I recorded last night.  And hopefully you'll see. So this is running inside the Mac. I just couldn't get them to  remotely connect. Recorded in Oslo, recorded in NDC. And when you run this up, when this  person who ever is stops wittering on the screen cast. When it runs up inside an emulator,  then you'll see that the data binding is exactly the same experience as you had before. So if  you edit the top one, the bottom one goes. And this gives you the testability of your  UI because you can test that view model and you can test it across all your platforms.  So that's binding a simple property. What else can you do? Well, so if you're used to  using NVVM, then no doubt you'll think about things like, well, can I have a value converter?  So let's build a value converter. And we've made portable value converters in NVVM Cross.  And in order to build a value converter, what you do is you just declare one. So let's take  the string and let's add a length value converter. Converter. And oops, I missed a class keyword.  By all means, join in the big programming exercise, the pair programming we're doing  here. And we will add, so it's going to inherit from something called an NVX value converter.  All of our classes inside NVVM Cross start with the letters NVX, which is absolutely  brilliant until you come to document them. And then you zoom through A to A to A2O and  you get there and you get to M, A2O. I don't know my alphabet. You zoom up to M and then  you have to start documenting M and it goes all to pop because every class starts with  M. But we've got this NVX value converter and we'll import the namespace. And what we're  going to do is we're going to convert a string to an int and then we'll implement it. We  implement it by overriding the convert method. So if you're used to value converters, you'll  just notice this is the same as a live value converter, except we've got no objects here,  we've got strong types. And all I'm going to do is return value.length. And then I can  build that. And that value converter will now be available in all my projects because  it's portable. So it's available in all these projects down here. So for example, in first  view in this Android, or I'm going to open it in the other editor, I can, for example,  add another text view at the bottom here. Let's do it. And this text view I'm going to bind  and all I'm going to do is I'm going to apply a converter and this converter is called length.  And the reason it's called length is because over here it started with the word length.  We use convention and we use a bit of reflection to find these things. And so now when we run  up the Droid project, we should see that we'll have another text field that will show us  the length of the current text. So there you go. We've got the things bound together.  And again, if I start editing, then you'll see that everything updates all in sync. And  that's really useful if you need to enable buttons as you change things. If you need  to perhaps display how old you are as you're entering a date of birth, that type of thing,  it's a really great way of putting things together. You can also combine multiple things  together in a value converter. So if you need to take a first name and a gender and a last  name and put them together to give a full title, you can do that using this type of approach.  So that's value converters. What else do you get inside view models? Well, quite often  you get a command. And so we'll add a command. And this command will be the NDC command.  And so we're going to add in an NDC command. And I'll just do this in line. So if you're  used to something like NVVM lights, then you'll have a relay command. We don't have a relay  command. We have an NVX command, but it's a similar type concept. And when this command  runs, what we'll do is we'll set my property to be equal to Bazinga. I should know some  Norwegian really, so I can actually do this in local. Is Bazinga Norwegian? I don't think  so. So as soon as we've added NDC command, then that's going to be available. And if  we want to bind that to a UI element, then we can do it very straightforwardly, for example,  by adding a button. And let's just copy some XML syntax so we can get there quite quickly.  And on this button, I can bind the text to the button as well if you want to. I can  bind it to the length as well. So we can apply multiple things. And then I'll also bind in  the click event on the button. So if you're used to using XAML, you probably might have  a behavior. Or if you're lucky, you've got a command on the control. Here we've got these  events that are there. And we just bind directly to the event delegate. So the click event,  we're going to bind to NDC command. And I'll run that up. And hopefully we'll see in the  emulator that now we'll get a button. That button will have the text, which is going  to be my property.length. And when we click it, we'll clear the text. Maybe the end of  my demo has just, let me just see what was there. Why is it not loading for me? That's  not part of the demo. Why is that happening? Anyone spot on the deliberate error as I typed  through that? Let me remove this because it's not normally in there. But I don't see any  errors that I made. Anyone spot anything? No, I do know, I think. I think the problem  is at the moment that my project probably isn't set up correctly. So I probably haven't  rebuilt my core. It's just in the configuration. So there's still a few little bugs to iron  out in that new solution wizard. But I'm guessing if I rebuild it and then build, it'll run.  If not, then I'll cut this out of the video afterwards. So there it goes. So there's your  binding. If you change the text up here, then you'll see that everything updates. There's  no icky find view by ID or get thing by name or get a tag or try and link all your code  together and then do that. Everything updates. If you hit that, then the text changes. So  that's data binding. If you wanted to do the same thing in Windows, then I hope most of  you here will know about XAML. And if not, then as I said, there were some excellent  presentations yesterday about that. If you want to do it in IOS, then what you would  have to do is in FirstView, you would have to add some additional bindings and some additional  UI controls. So for example, if we wanted to apply the converter here, then we'd do  it using a with conversion. And we would just put the name in, like length, and it would  work. If you wanted to bind to the command, then what you would do is, for example, if  you wanted to have for the tap on the label, then you would actually put the name in like  that because we haven't got a fluent expression syntax for that at the moment. So you put  in that when it taps, I would like to bind to the NDC command on the view model. And  you can see how IntelliSense helps you there. You can see how you can build it out. And  also if you refactor that, it will refactor across the entire project solution. So that's  data binding. I hope that was vaguely followable. Sorry about the mistake halfway through with  not rebuilding. And you can see that for simple properties, we get, you know, Windows at the  top, Android in the middle, and iOS at the bottom. And I hope that's followable for most  people here. If you want to apply a value converter, then that's the way you do it.  And I believe that our syntax is much neater and nicer than kind of the curly brace one  that Windows has by default. And then if you want to bind to commands, then you can do  it very straight forwardly. So that was MVVM cross V1. And that was the social storm project.  And we were very lucky and very grateful to Microsoft and to McCann London to allow us  to open source what we produced. And V1 was brilliant. It was absolutely amazing to develop  these things. And we did have changing customer requirements all the time, which meant we  wanted to refactor. And we did have changing Twitter APIs all the time, which meant that  we were continually fighting builds. So we really, really benefited from being able to  share all this code. Because if we had to develop those sacs separately for Android and iOS  and Windows Phone and we had to cope with them, it would have been not so pleasant. However,  V1 did have a slight dark side. And the dark side was that in V1, we didn't have a portable  class library layer. So we had all this file linking going on, which meant we had separate  files for every solutions round. So we had separate files for Android and separate files  for iOS and separate files for Windows Phone. It was also just a bit fat as a library because  it was a V1. And it wasn't so easy to extend or to play with because, you know, it was  a V1. So what we needed really inside MVVM cross was we needed a hero. And I don't know  where you guys look for heroes. I don't know where heroes normally hang out here in Norway.  But we always look for heroes inside Visual Studio. And we found one. And our hero we  found in the new project wizard. And it was the portable class libraries. And particularly  version two that kind of came out in late 2011, early 2012. And what a portable class  library is, is when you choose new, it allows you to target multiple platforms. And you  get this little dialogue. And you know, you can say that I don't want to just target WPF  applications. I don't want to just target Windows Store. I don't want to just target  Windows Phone. What I'd like to do is I would like to target all of them. Now, obviously  by targeting all of them, you do get a reduced API set because many of these things, you  know, are based on the compact framework. And the idea of the compact framework is it's  compact. Yeah, it's got a smaller memory space. So you don't get every API. But by selecting  these, this reduced set, you can develop one project that will span everything. So this  is what you get by default. Particularly thanks to John Popp's at Xamarin, who wrote a little  blog post, which is very helpful. We found a way of getting Mono for Android and Mono  for Touch in there. And this is well documented now how to do this. And I think official support  for PCI is coming anytime in the next two weeks from Xamarin. So it's going to be brilliant.  And once you've done that, then you'll get this API set. And this is taken from the Microsoft  documentation. And if you're just targeting the things we're looking at, then what you  get is you get this feature set. And so you'll get core, which is things like system.datetime  and system.string and all the stuff that you use all the time. And it's really useful having  that. Yeah. Don't, you know, underestimate how much value you'll get from having a single  datetime and having a familiar datetime to yourselves. Because if you haven't got that,  then on iOS, you'll have to know about NSDate, which is actually a long under the covers.  And then you have to kind of use a calendar object to get NSDate components out, which  you pass a bit. Anyway, you don't want to go there. And you'd have to know about Java.  And Java is like a little peculiarity that most things are long under the covers. And  there are different types of long. And if you add them together in the wrong way, it  goes wrong. And then when you use a month, it's zero base rather than one base. So your  code, when you cut and paste between different platforms, it'll go wrong. But it's really  great to have that. Another thing that's great to have there is link. It's just brilliant.  You know, we all love link. It makes it so much more productive. It makes the code so  much more expressive. We've got iQueryable. We've got most of the network class library.  We've got most of HTTP web request. And we're getting HTTP client in a moment. We've got  serialization there. We've got most of the HTTP stuff, WCF. So if you've got legacy systems,  you need to connect to from iPhones and androids and from Windows phones and Windows Store.  That's the way through. We've got MVVM, which is quite useful for what we're doing. We've  got Xlink. And also coming, because this is a growing API set, we've got async and await.  So when I say coming, it's fully there across the modern Windows platforms. And it's in  now for at the moment across Android. And I think it's in beta, sorry, across Android  and iOS. So I'm not going to show much of that today, but it's coming. It's there. And this  set is growing and people are working out how to extend it and extend it. And Microsoft  are really quite committed to it now, not least because they fragmented their platforms  more and more. And you know, Xbox One is going to come along as well. And it's really great  to enable people to share it. So using this technique, what we were able to do is this  is kind of, it's actually a Visual Studio 2010 screenshot. And this was taken, I guess,  April last year. So just over, what, 14 months ago. And it enables to take Twitter search  as one of our samples. And it enabled us to map it down to a really small sample like  this. And in terms of refactoring, in terms of tooling, in terms of being able to merge  in source control, in terms of the team being able to work on it, it's just brilliant. So  there is slight problem, however, in the, as I say, Portable Class libraries give you a  reduced API set. And sometimes you want a full API set. So what do you do when you need  to access a, you know, something that's phone specific, like actually making a phone call?  What do you do when you want to access geo location? Well, there are various techniques  to this. You'll hear people talking about Hashif, my best friend in the world. You'll  hear people talk about partial classes. But what we use, we use simple abstractions. We  use interface driven development. And we've got a plug, sorry, interface driven development.  And we've got a plug-in layer over the top of that. And that plug-in layer is simply  a system of DLLs, which means that you can just insert these DLLs into your projects.  And by convention, you'll get the right things. So again, can I just ask who already knows  about IOC or do I need to? Okay. I'll quickly go through IOC. So IOC is really just about  if you have things like an SQL engine, which is native or platform specific, if you have  things like geo location, which is platform specific, and maybe you have a tax calculator,  which is your own code, then you can declare interfaces on those. And you can put them  in a big pot somewhere. And then when you need them, perhaps in a view model, then you  just declare that you need their interfaces. And at runtime, you get the right implementation.  So if you do the same thing and you do it on an iPhone, on an iPhone, you get an iPhone  I SQL implementation, or an iPhone location implementation. And you get the same, perhaps,  as a portable tax calculator. Then you put them into the iPhone pot. And then at runtime,  you'll get the implementation you want. So let's quickly go back to Visual Studio, because  I get bored of PowerPoint. And let's close this solution where we started. And let's  show you a different way of building a project. And so what I'm going to do is let's create  a new portable class library. And so we start here in Windows, and there's a portable class  library. And so this is going to be called NDC kittens, which might tell some people  what's coming up. You can't have a demo without kittens, zombies, gambling or sex. It's got  to have something of that commitment to it. Or maybe an optocat is also available for  the GitHub in the audience. So we're going to create NDC.core. And you'll get this dialogue,  particularly if you modded it. And we can't support original Windows phone, but that's  okay because all the Windows phones have been upgraded to Mango at least. And we hit OK,  and Visual Studio goes off and implements it. And then what you can do is obviously this  has got no coding at the moment. It's got this class one. We'll get rid of that. And  I hope this doesn't make a loud noise. No good. So what we will do is we'll manage the new  get packages, and we'll pull in, and I'm not going to use the network because it'll be  too slow here. So we're going to pull in MVVM cross. And by default, when you pull in MVVM  cross, then you get given an app.cs, which just tells you a little bit about how to initialize  your IOC. So it's basically saying that anything ending in the word service, I'm going to put  into that IOC pot, into that inversion of control. And then it also says, please, when  my app starts, just show the first view model, however you do that on your platform. So what  we're going to do is we're going to take a look at first view model, and it's got some  default junk in there. We'll get rid of that. What we'd like to do is we'd like to do some  SQL work, because that's a plugin that's going to be native on each platform. So let's go  and find the SQLite plugin. So we're going to go back to new get, we'll get a local package,  and there is a SQLite plugin. And we're going to install it into our portable class library.  And once we've done that, then I'm going to not type this live because it would take too  long, but I'm going to use a snippet. And this snippet is handily called kittens. Oops,  if I could use a snippet. And what you'll see is this pulls in a first of all, it pulls  in an ORM class. So it's just a, you know, data entity, which is a kitten. And each kitten  has an ID, which is primary key. So if you use the databases, you'll be familiar. It's  got a name, it's got a price, and it's got a kitten URL, we'll see a cute kitten. I've  then got a service. So if you remember that IOC initialization code, it's going to look  at that keyword of service. It's going to think that's special. I'll put that in the  pot at the start up. And this is just a way for me to create random kittens so that we  can have something to see at demo. And we then got this kitten Genesis service and this  kitten Genesis service. Again, I'll just import the namespace. We'll generate me some random  kittens and these are the top 20 kitten names on the internet. And then we've also got a  data service. So this is our actual kind of repository, if you like. And I've just put  some CRUD methods on the repository. So the insert, update, and delete. And then I've  also put this select method, which is kittens matching. So that's the interface. And the  implementation looks like this. And you'll see that the implementation in its constructor,  it's going to take two things. It's going to take a SQL like connection factory. And  that's something that's going to come from that SQL like plug-in. On each platform, we'll  get a different one. And then we've got a kitten Genesis service. And that's the mock  data service up above. So all it's going to do on startup is it's going to try and create  the database. It's going to make sure there's a table in there for kittens. And if there  aren't any kittens, then it's going to seed it with some random data for me. And if you  take a look at what the, and again, I'll just pull in, that's Iquirible coming in. If we  take a look at what the methods look like, then the CRUD methods are really simple. They're  connection insert, connection update, and connection delete. And the select method is the lovely  link-like syntax that we all love, the order buys, the wares, the to lists. So you get  full, look, full intelligence in here and everything you really enjoy as a C-sharp developer.  So that's our data service. Let's now use that. So back in our view model where we haven't  got anything, in the constructor, I'm going to get hold of a data service. So I'll create  a private member called data service. And then I'll initialize that from the constructor.  And then what I'll do is, let's see, let's use kittens matching. So I'm going to create  a property called filter. Yeah, and so that's called filter. And you can see the syntax  there for raised property change, which I hope is what you're all used to and expecting.  And then I'll create another property. And this property is going to be a list of kittens.  And we'll have underscore kittens and kits. And then what I need to do is tie them together  somehow. So what I'm going to do is, whenever my filter changes, then I'm going to call  update. And let's also call update from the constructor so that we get something on startup.  And let's also set the filter to a default value. And that can be C, because I think  I saw some kittens with an aim of C. So the only thing I haven't implemented at the moment  is update. And update is a pretty simple bit of C sharp, I think. So what I need is that  when I'm updating, I'm going to ask my data service to for the kittens which match my  filter. Yeah. And that's my core project done. Obviously, I can put a unit test on that.  And when I put a unit test, I can pass in a mock data service. And that should work  and should give me, you know, real reliability in my UI functionality. So I'll build that.  That's built. That's my view model. I could connect a command line console app to that  if I want to. But let's, how am I doing time wise? Oh, I'm talking a lot. So let's build  a Android app to talk to it. So we go to Android. We go to Android application. And  I call this ndckittens.core. So what I'll call the Android application is ndckittens.droid.  And Android, if you, this is just the default Xamarin template. And you'll see you get,  you know, an activity and you get some resources which are XML. I don't want the default activity  because I want nvm cross functionality. So what we do is we go to new get again. And  this time we'll pull in nvm cross, the core. And we will pull in SQLite because we want  the native SQLite for Android. And this really will. It will be the C++ component that's  sitting inside the Java layer and sitting inside Android. So we'll pull it in. And once  we've done that, what you'll see is you'll get these default files like set up. And set  up is saying please run core.app. So we're going to have to reference that core project.  Let's do that. Add reference. Reference the core where the view model is. And then once  we've done that, we'll just need to do our data binding. So let's do that. Obviously,  we've got a first view generated here by default as well. And that's just going to use this  XML file. So let's do our data binding. So let's go to our first view. And by default,  we've kind of got this hello example. That's not so useful for us. So what do we want?  We want an edit text or a text box at the top. And we're going to bind that to a filter.  And then underneath, we want a list. So how are we going to do a list? So if you were  doing vanilla Android, you would do a list view. And then you'd give that list view an  Android ID with some horrible syntax. And then in the code behind, you would get hold  of that. And then you would create another class that is called an adapter. And you would  inherit from that adapter. And then you would put in the adapter some get view functionality.  And then you would also put some get. Anyway, we're not going to do that. Phew. What we're  going to do is we're going to add the magic letters of NVX to the front of this view,  which is a class that understands data binding. And in particular, what it understands is  just like in WCF and in Silverlight, it understands item source. So I hope this is big enough  for everyone in the audience to see. We don't need text size anymore. We do want it to fill  the parent with this particular thing. So it's a list and it's going to be big. And  we want to bind the item source to the kittens. So hopefully, unless I've made a mistake,  we can run this up. Let's have a go. Debug start new. Build started. It's a nervous moment  for me. Did I forget anything? Coping applications. Well, it built. It built that ship. It's only  fair. So it's running up. And you can see what we've got is we've got some data binding  at the top where we bind this thing. And if we start typing, then there are still some  kittens with C and O in there. If we go for R, there's no kittens left. Now, that's brilliant,  isn't it? Except this is a little bit, yeah, that's just string. We don't really want to  string on there. So we've got our RUI working to a first level. But now we need to have  a data template for each list item. So if you've done as Amal, and again, apologies for those  of you who haven't, I'm moving forward as quickly as I can. Then what you do is you apply a data  template. So we're going to do the same thing here. And what we're going to do is we're going  to have an NVX item template. And we're going to reference another XML file that's over  here in the layout folder. So to do that, it's a little bit of Android syntax. It's layout  slash. And then it's the name of the file we want to use. So I'm going to call this file  item kitten. And the reason I use kind of these prefixes is just because Android has  this horrible flat file thing. And so it's the only way of grouping them together. You  can't use subfolders. So that's why I've used prefixes to try and group my resources files  together. So that's it. I'm going to use item kitten. And let me just, I'll copy and paste  first view. And I will create item underscore kitten. And what do we want in item kitten?  So let me remove this. And what we'd like is we would like to have, let's just do a  layout which is going to be horizontal. So it's a stack panel. It's going to go across  the page. And let's do a image, first of all. And so this is going to be an NVX image view.  And we're going to give this a fixed height, oops, NVX image view. We're going to give  this a fixed height and width. So we're going to say this NVX image view should be, let's  make it 100 dp, which is a fixed unit, and 100 dp. And obviously we'll have to terminate  that. And then what we would like to do is we'd like to put the image in there. And I'll  come back to that in a moment. But what we'd also like to do is we'd like to put a text  view in there. And so the text view we're going to bind to the name. So let's just do  the layout width is going to be filled parent and the layout height for the text view is  going to be wrap content. And then let's, and again, you can use the designer for this  if you prefer. Let's put the font size again, a bit larger so you can see it. So text size  equals 40 dp. And let's then bind. So we're going to use local colon NVX bind. And we're  going to bind the text to the name of the kitten. So that's the text view done. The  remaining thing is really this image view. And what we'd like to bind on the image view  is a property called image URL. And the property we'd like to bind it to is to the kitten URL  on the kitten. So we do that. And let's just put that together. Now there's one more thing  you have to do for Android, which is because, and like with Windows, you're used to the  fact that if you just bind images, then they automatically get downloaded using the Internet  Explorer cache and they get put into your application. Yeah, with Android, you don't  get that. So there's another plugin we have to add just for Android. And basically we  have to add the, oh, I have got that one now. Basically we have to add the download cache  plugin. And the download cache plugin also relies on the file plugin in order to store  these things as files. So you install those and all they've done is added some references  in here. And then we should be able to run this up. And unless I've made a mistake, then  we should be able to see some prettier lists on our screen. So I hope so. So there's our  list. And if we start filtering, so if we start filtering down, then we remove the filter  to start with. Then we get all of our kittens and these are in price order because that's  the way we set up our thing. And then if we start typing and we'll just look for the  pollies of the world. So if we start typing for polly, then hopefully we get pause and  polly together in this list and Pepsi. And if we start PO, then we get just the pollies  in the list. POL will still get them. If I misspell polly, we lose them all. So that's  data binding working. There's no C-sharp code behind in the UIs. Everything's testable  and that's the way our applications put together. I've overrun a bit so I won't go fully into  the iOS demo to do the same thing. But what I will do is return to the slides and just  show you. So this would be what the windows would look like for a list for data binding.  For Android, you've just seen. You kind of use these templates. And for iOS, what you  can do is you can define table view sources and it's the same sort of approach. And it  allows you to bind these things together. And if you want to do custom cells, you can  do it. So I'll just skip forward and show you a little bit of this movie. So if you  want to do custom cells, then let me just find some custom cells in here. Then you should  be able to declare them using the interface designer. So there is a designer for iOS,  but it produces really not human-friendly XML file, should we say, called nibs or zips,  depending on how you're feeling like saying them. And these files are not the easiest  to use. So one of the things you'll discover is people don't use them if they want to use  source control very much because they change every time you edit them. So it's very hard  to do merges. It's very hard to do team efforts where you want to merge them together or to  do revision history and source control. So that's what you do. And then when you put  this together as an actual app, you will hopefully see something like this where you get a custom  list and you'll get the kittens and the prices, et cetera. So sorry that I can't demo that  live, but as I say, the Mac wouldn't connect on the network here, so I couldn't do that.  Okay, so that's lists. And that's also, I hope you saw, plugins. So I hope you saw issues  in the SQLite plugin. It's the same for other plugins like network plugins and messengers  and camera if you want to access and take pictures. And the best thing about this plugin  list is it's extensible. Yeah, so if you want to create your own plugins, it's really simple  to do. You just create an interface in a core portable class library, like, you know, this  is the vibration sample. There's a little bit of boilerplate code so that it'll help  the conventions along to load it. And then after that, you can create platform-specific  ones. So here's the vibration plugin that works on Android. And that's a native library  that plugs in. The most famous example for plugins was the Spharo example I did. So this  was a controller for Spharo, which is a robot which kind of glows and spins and does all  sorts of things. And this was a, hopefully I won't get sound on this. This is an example  we did in Evolve out in Texas. Well, we controlled seven of these from a phone. And this is cross-platform  code. So this isn't your typical NVVM sample. You know, this is controlling robots using  accelerometer, using speech, using all sorts of native services. But this is what we managed  to put together so that, you know, you can see, hopefully, these are going to do a little  dance and jig around the room and all sorts of things. So think about it as you move forward  into future, you know, platforms. It's not just about static UIs on screens. It's also  about speech, obviously Siri and things like that. It's also about controlling external  factors and the Internet of Things. So that was the most famous example, perhaps. And  that was what NVVM Cross Vnext was all about. It was all about PCLs and plugins. And NVVM  Cross was really, Vnext was amazing. We really, really, really loved NVVM Cross Vnext. However,  it did have a bit of a dark side. And the dark side was the getting started was described  as a learning cliff that most people had to really kind of build it from source. They  had to go to GitHub and download it and work out. And it also had some quite of a boast  of very long class names, in fact, very, very long class names. And so we knew that we needed  to evolve. And so the path that we took for, oops, I'll destroy myself. Hopefully, I've  still got sound. The path that we took for our evolution is really a path from NVC, which  most of you know has been around since the 70s. I seem to have heard it was invented  in Norway, but I may be wrong. And it's been around since the 70s and it's model view  controller. And in the middle of the 2000s along came Microsoft and John Grossman and  the team inside Vista and Longhorn. And they produced NVVM, which relies on this data binder  to have this view model, this model of the view. And this was middle 2000s. It hasn't  really changed that much since. There are some notable exceptions, reactive, for example.  But what we are heading towards is model view cross platform. And we're really looking  at how that code can be shared and can be really empowered across multiple platforms.  And it's not just about these phone platforms, it's also about the Xbox. It's also about  Google Glass. It's also about TVs. It's also about the future. And the things we've added  in the recent things, you've seen quite a lot of them. You've seen the clean binding.  We've added Android fragments. We've added WPF. We're adding.Mac. And this is still  a work in progress. We've still got a few things outstanding. But at the moment, NVVM  cross V3, which is what you've kind of seen demoed, is amazing. And we really love it.  And it doesn't have a dark side. And it is a work of awesomeness. There are a lot of  people who built it and have contributed. And all of these people, I thank them. And  I put them in every presentation to thank them. People are spotted people, they know.  And it's a really huge thanks to them. And it's thanks to them that we now have samples  like we've got, for example, a fractal sample. So this again is data binding. It's data binding  to a mathematical model with a huge bitmap. And you're binding to this image at runtime.  And generating at runtime. And this is cross platform. It's across all four of our key  targets. So I can also show that running on iPhone. And it's actually very interesting  to run it on a retina iPad. Because you get to see some limits of memory and some limits  of calculation as you do this. So it's exactly the same code, exactly the same controls around  and that UI is. And we can build that forwards.  We've also got plenty of other samples. We've got things like Internet minute, which is  a scary thing to watch because it tells you what's happening at the Internet in real time.  So you can see all the botnet infections that are happening around us. You can see all the  apps being downloaded. The email sent is just hideous to look at. And we've got other things  that we can show there as well. In terms of real apps, well, obviously, Connect Star Wars  was where we started. It's no longer really available because Twitter's broken the API  and that, you know, there's no longer a huge need to sell that game. So I won't show you  the video for Connect Star Wars. We've got things like this is a company called Bruel  and Kaia from Denmark. And they are international. They are leaders in noise and vibration monitoring.  And what they have is they had an installed base of Silverlight apps. So NVVM and Silverlight.  And obviously Silverlight was no longer the future. And what people were asking for is  can I have it on my iPad, please? Can I have it on my Android? And so they took a NVVM  across version one and they ported it. So it's not just about text fields on the screen.  It's also about maps. It's also about these heat bars. It's about charts. It's all data  bound. It's all data bound to the same view models across three different platforms. And  it's fabulous. It's by a guy called Thomas, particularly from Cheesebarron who's done  this. And it gives them a testable platform for the future. There's a company called Centra  Stage who do monitoring and all this thing of networks. And so they allow you to log  in. And so they took their web-based system and their kind of desktop trade thing on PCs.  And they plugged it in and they managed to build this iPhone app. And obviously their  users were all using iPhones and they wanted them. And now their users are all using Android  and they're porting to Android. And also they've ported the same thing to Mac desktop. So exactly  the same code using Xamarin.Mac now runs on Mac desktop. We don't have this in the core  framework at the moment just because we're waiting for a little bit of PCI support before  we make the big effort of putting it across. But this is the future again. When a new platform  comes along we can do it. And all of the things like the Sony platforms for example are all  C-Sharp which is brilliant. And hopefully as well the Microsoft ones will be if they  work it out. So Aviva was one of the, again a version one customer. And they've got this  platform that monitors your driving and gives you a score out of ten about how safe you  drive. And then we'll give you a discount depending on how safe you've driven. I presume  there's an underground current where you try and score zero. I don't know. But again  this because it was an insurance app and because insurers don't take any risks at all this  needed to be heavily tested. It needed to work across both platforms. It had quite a  lot of background code looking at geolocation and things. And so this was again another  app. The final app I'll talk about is the Lions app. So this is a rugby tour. I'm not  going to make the joke I made in America about rugby because I was worried about Texan shooting  me. I'm not going to. I'm not going there. But so this is rugby tour. It's very rich.  It's very consumer. It's kind of a magazine thing. But it's also got live stats during  games. It had a competition in there. It's on Windows phone. It's on Windows 8. It's  on iPhone. It's on iPad. It's on Android. It's on Android tablet. It's also on the Kindle  tablets. And this was built in two months by a group of three C-Sharp engineers who didn't  know mobile. Yeah, they knew ZAML. They didn't know any of the mobile platforms. And back  to front, it's C-Sharp everywhere. So on the server, they use a CMS, which is Umbraco,  which talks to SQL Server using entity framework. It's then got this web API front end, which  is C-Sharp. It uses a PCL block of entities. Yeah, so all of the JSON objects that go across  the web API, those are PCL codes. So it's shared between the server. So that's another  one of our platforms, really, and the client. The core logic is also always in a PCL. And  all of the UIs are in PCLs. So the SQLite on the local database is also the C-Sharp  DRMs. So anywhere in there, any of the engineers can feel comfortable. It's not like, oh, that's  the iOS code. I can't touch it. It is all C-Sharp. It's all refactored. It's all got  IntelliSense and resharper navigation support. In terms of lines of code, and this is kind  of where they, these are their genuine numbers of version one, you'll notice that actually  some of the code isn't that shared. Like, there's quite a lot of UI code in the iPhone  and iPad, for example. The main reason for that is because they wrote a lot of custom  controls, and also they didn't want to use these Zibs, so they wrote everything in C-Sharp  there. But what's important is everything they wanted to share in the PCL code they  could share. Yeah, just the animations and things like that and the layouts on the individual  platforms they didn't share. So that is MVVM Cross, and I'm running about right on schedule.  And MVVM Cross is very much still a growing platform. Yeah, V3 is hopefully our final  big revision. We have cleaned things up quite a lot. But MVVM Cross is still learning, and  the path that we have gone along in the last year, in the last 18 months, is we started  with version one, which was really about, you know, everything we do is pretty much  driven by real projects. There's no point in making up requirements. We've got plenty  of requirements, which are real. But it was really about supporting IE Notify property  changed on the three platforms. Version two was the real requirements was to make things  more maintainable and to allow us to work in bigger teams. I mean, you know, things  like the insurers have very big teams of developers, and was allowed to make really  testable code. So that was PCLs in version two. Version three is about cleaning it up,  adding.mac. And then the future, and the future is wide open, obviously, but it's pretty  darn exciting. And what we're looking at now is we're looking at, you know, as I say,  MVVM itself has been fixed almost since 2005, and we're looking at other ideas. What else  can we do in our view models? If you look in the JavaScript world, where Angular and  where, and where things like Knockout have come along, they've done really exciting things  in their view models and their bindings. Some of those things, like the computer observables,  can they come back into our world? Can they come back and change things? And to some extent,  we're now free of Microsoft and we're free of XAML because we've got our own binding  framework. So it's a really exciting time in terms of moving forward. Obviously, async,  I haven't shown you much of. I can show you a quick. So there's a guy called John Dix  who has produced, do you know what Jabra is? It's a chat room or online using SignalR.  And he's produced this Android app as a first demo. And at the moment, this Android app  can connect and can talk to all the rooms that allows you to post messages, et cetera.  And yesterday, I ported that same code across. And it's not pretty yet, but I ported the  same code across just by using XAML bindings. So hopefully, this would connect. And I can  join the MVVM cross room and I can type in what's up and be immortalized forever that  that has been sent into the thing. Oh, there are some more messages at the bottom. So it's  a very much a first UI. I'm not going to ship this one to the store. But you can see that  everything is in there. And you can pull about the rooms. And all of these pages, you can  pull about the rooms. Maybe you can't. And you can join another room. You can do all  that. And this is async await code. This is all our modern C sharp and is the future.  So it's very exciting. We also have auto views. We have the idea of some of the UIs could  actually be constructed centrally, which is kind of based around dialogue. There's a lot  going on around F sharp. I don't know if you've noticed this conference. There are a lot of  functional programming sessions and F sharp. FOD is an AOP approach. The ninja ID you've  seen, but there's also a plug in ID being built for Xamarin Studio, which is brilliant.  We're looking at how we can integrate into designers more. You know, I'm kind of XML  based, but I understand designers. As Guy in Holland, who's produced proto pad, which  is a bit like a link pad for UIs. It's brilliant. There's more patterns we can do. And I can  show you that, for example, this is a guy called Pan Homes in Tenerife, who's produced  an F sharp view model and an F sharp view. So there's no reason you can't use our C  sharp code in F sharp. And things like that fractal sample, I'd love to see how that really  gets much smaller in F sharp. And much more flexible and much more tested. And then there's  also, so this is the FOD. And FOD, I don't know if you can see this. Let me show you.  So if you use FOD and apologies that it's out of focus doing that, then you don't have  to do all of that raise, not property change stuff, because it will inject that for you  afterwards. All you do is you decorate your class with implement property change, and  then it'll come along and actually automatically generate it. And the amount of effort you  have to go to get this working is you have to put that attribute in, and you have to  pull in the package from NuGet. So that's it. And the future for things like that is  also very exciting with things like the compiler from, you know, the Roslin compiler. So hopefully  we've covered some of this today. Sorry if I didn't go into introductions as much as  I perhaps suggested I would. And hopefully you've got a good idea about how MVVM and  data binding can be applied across all the platforms from this. And that is my hope.  It's a new hope. And I hope that if you face a future challenge of any description like  we did with Star Wars, then I hope you can keep calm and you can write some code. And  I also kind of sneakily hope that you can keep calm and use MVVM across. So thank you  very much for listening today. Amazingly, I have four minutes left, which is quite unexpected.  So if there are any questions, I can actually answer them, or I can demo some more code  or anything else. Anyone got any questions? Oh, there are also stickers. So if anybody  likes to decorate their laptops, then by all means come and grab me and grab some stickers.  Can I do, sorry? So partial views, you mean kind of user controls? Yeah, so yes, you can  do partial views. Oops, that's a bit of Darth Vader coming back. Yes, you can do partial  views on every platform. So with iOS, you can have a UI view controller for a specific  area and give that its own iNotify property changed object and it will work. Similarly,  you can do it on Android using either fragments or using our own control, just called MVX  Frame Control. You just give its own data context. You can change that data context and it will  change and update automatically. You can use it as a dialogue if you want to. You can use  it within tab views. That's the way the tabs work. So yeah, it's exactly as you expect.  And you, we do have a navigation model. We allow people to use it on our navigation service.  But you can also, if you want to, replace that entirely. And you can just manually set  up a view and say, here's your data context and go. So for example, the list view is done  on exactly that philosophy. So every cell in that list view has its own kind of data  context. And the binding works two way on that as well.  So there are several ways of communicating through view models. Like you can actually  just give them C sharp references if you want to. There is a messenger plugin which will  allow you to use the messenger pattern. And that messenger pattern uses weak references  by default. So you don't have to unsubscribe. It just kind of unsubscribes itself when you  get garbage collected. Or you can use any other messenger if you want to. So if you  want to use something like the great tiny messenger, you can use it. So yes, that's  the main way that we set up that type of messaging. And you can also use that messaging back to  the UI if you want to or between services. That side of the architecture, I deliberately  leave very open for people just because there's so many ways you can build these things. And  that's to allow it open.  So the way you do that is you would have to do a little bit of code behind. And I don't  think I've got a sample available by pre-recorded. But basically on every platform you do have  to generally override. There's two methods you have to override. One is where you first  register the templates on each platform. And the other is where you choose which template  you're going to use for a particular object. But there's a very nice sample, for example,  which are kittens and puppies, exactly that on iOS. And also if you're using observable  collection, then all of your observable collections, your iNotify collection changed, they work  across all platforms. And particularly on iOS, iPhone has, you know, the table view is its  heart of iPhone. Every standard control, every standard app in iPhone is a table view, is  that list view. And it's wonderful when you actually add an observable collection, you  get an animated slide in. It's exactly what you expect for that. When you delete something,  you can animate how it fades out, for example. So yeah, that templating again is available.  You do have to do a little bit of code to choose which template you're going to use.  But it's there. And basically on Android, for example, it would just be another file  and then two lines of, you know, switch statement, for example, in C sharp.  Okay. Is that it for questions? Okay. So you can all go and have a break now. And this  was a picture from Worldwide Developer Congress this week of the breaks. And it's quite funny,  but it's also not funny because this is, we need to get some more people in that left  thank you. And I don't mean gents move over. So if anyone's got any ideas of developer  community, how we get more and more females involved, please tweet it. Please try and  work out how we solve this. Because I do some, a little bit of work with young, rewired state.  And young, rewired state see 50% females all the time. And some of them are up to 70%.  So, you know, we're doing something wrong as a profession. Sorry. A little bit of a political  bit at the end. But if you can think of any ways of improving that, I'll go and have a  break. Thank you very much, guys.
Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_0_803.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_804_2519.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_2520_2723.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_2724_7991.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_7992_10607.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_10608_14963.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_14964_29723.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_29724_29831.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_29832_29927.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_29928_30659.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_30660_34835.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_34836_37379.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_37380_37931.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_37932_39575.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_39576_39947.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_39948_41471.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_41472_41531.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_41532_42563.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_42564_43703.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_43704_43847.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_43848_45083.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_45084_49283.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_49284_51047.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_51048_55583.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_55584_55655.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_55656_57647.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_57648_61283.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_61284_61331.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_61332_61967.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_61968_63203.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_63204_63251.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_63252_63299.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_63300_63419.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_63420_64571.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_64572_64631.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_64632_65495.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_65496_65591.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_65592_65771.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_65772_66287.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_66288_68135.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_68136_68711.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_68712_68771.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_68772_69047.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_69048_69599.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_69600_70007.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_70008_70295.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_70296_73379.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_73380_76199.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_76200_76523.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_76524_78959.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_78960_79019.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_79020_79079.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_79080_79223.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_79224_79811.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_79812_80003.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_80004_80855.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_80856_81779.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_81780_82295.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_82296_82619.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_82620_83099.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_83100_83147.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_83148_86819.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_86820_88643.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_88644_89195.png Stuart_Lodge_-_Sharing_C__across_Windows__Android_and_iOS_using_MvvmCross-68375201_89196_89756.png