 All right, all right, let's get this started. Good morning, everybody. How's it going out there out in Twitch and YouTube land? My name is Jeff Fritz, and I'm joined today by Demetrile Allen and Daniel Jacobson. Hey, good morning, guys. How's it going? Good morning. Good morning, Jeff. Hey, hey, Jeff. Oh my gosh, I am so looking forward to today. This is one of those days where we're doing a workshop. I love that you guys are in Channel 9. We're going coast to coast. Channel 9 over there, we got Seattle covered. I'm over here in Philadelphia. We're going to talk about Windows development, Windows application development. Oh my gosh. Guys, I cut my teeth building Windows applications, but I understand new things are happening. There's cool stuff happening for Windows developers, right? Yeah, always. Definitely. Well, we're super excited. I mean, this workshop is something we've been talking about for a while on the team. Maybe some introductions are in order. So my name is Demetrile Allen. I'm one of the PMs working on the tools for .NET developers building for Windows, and this is my colleague Daniel. Hey, my name is Daniel. I'm also a senior program manager working on the same team. Really excited to show you some of the work we've been doing in Visual Studio 2017 and in upcoming 2019. And really hoping to teach everyone something that they can use to be more productive and obviously be a better Windows developer. Awesome. Awesome stuff. All right. So we've got some content. We've got some slides to go in here to get started, to introduce the topic, don't we? Yeah. All right, let me cut over to your slides. You can get off, OK? Sure. All righty, there we go. Look at that. It's like we planned this. Almost like we planned this. So just to start it off, we're beginning with today's full agenda. As you can see, we have a full day packed with content around .NET desktop development, beginning with some tools that you can use today that are already available to empower you and your sample development primarily, and then focusing heavily on modernizing existing desktop applications with Windows 10, and especially with .NET Core. If you haven't heard the news as a Windows developer, WPF and Windows Forms are coming to .NET Core and are doing so in the open on GitHub. So we've got lots of really exciting content. Later on in the day, we've got some MVPs coming in to talk about building applications using Prism or even using Reactive MVVM on .NET. So it's kind of a different paradigm for building Windows desktop applications. And then like I mentioned before, the modernization aspect with .NET Core, XAML Islands, Windows 10 functionality, and then finally, introduction to Xamarin Forms. So if you are a XAML developer and you have a requirement to bring your applications to mobile, we want you to be able to reuse your existing skill set and just be productive across all platforms that .NET supports. Last but not least, an often neglected topic in the client or the Windows development world, which is DevOps. So how do you create a CI, CD distribution system and automate pretty much everything so that when you check in code, you have a new package ready to go. Oh man, okay, that's a ton. I'm not a normal XAML developer. So some of those things that we're going to get into there, I'm really interested to learn more about because I'm typically a Windows Forms developer. So I love seeing that we can do XAML now in all of these cool places. Yeah, and I think this really brings us greatly into the next slide that we have here, which talks about, you know, what is desktop development like today for a developer? And the way that we see this ecosystem is that wind forms and WPF are very important and very productive frameworks. We see lots of developers, in fact, millions of developers building against these frameworks, including UWP as well. And we really believe in empowering those developers to be really effective and have access to all the APIs and all the controls and also all of the modern things that are coming to the .NET framework. And this is what the day is all about. It's to go through the tooling developers can use today to talk about what's coming for developers with things like .NET Core 3s, ML Islands and lots of other technologies, much more Windows 10 goodness coming to these folks. And also to highlight our open source efforts because we've really pushed heavily, as you know, Microsoft for open source and in this particular case, we finally have goodness to share, which we couldn't have shared a year ago, which is wind forms and WPF is open source and we're committed to building that in the open. The Windows UI, Wind UI is as well being built in open. So lots of good news there to talk throughout the whole day. Cool. I'm noticing a couple of comments saying that there's audio issues or that audio is too low. If I sit closer to the microphone, does it improve? We will hug the microphone. We can hug the microphone so you can hear it. No, no, I'm trying to cut some of that little bit of clipping that we're getting in your audio. So I see one comment, make UWP open source as well. We're actually doing that with the controls. So if you can see at the bottom of the slide, when UI is open source, if you go to the website aka.ms slash when UI, that is essentially the Windows 10 UWP platform controls. AKA.ms, when UI, you said? Yeah. All right, we'll put that into the chat room there. Cool. There you go. So not all of UWP is open source, but at least the XAML part. Yeah, there we go. Cool. I think the reality is there's a lot of things we could be open sourcing. It's gonna take Microsoft time to figure out what are the right pieces and we never wanna do open source without ensuring that our team can try to make it sort of a productive repo that's actually been worked on open as opposed to just putting code out there. It's easier for a code and open. It's much harder to really do open source. So keep the feedback coming. I think the community has driven a lot of the decisions Microsoft has made and without you, we wouldn't know the right things to do. So keep telling us what you think the right things should be. Very cool. I'm wondering if we might be able to get colonized to sneak in there and check some of the levels on your microphones just because they're a little bit hot and they're clipping. All right, sounds good. Give me just one second. I'll be right back. Okay. Oh, Jeff's idea is always first class. He is the master of audio. Yeah, I'm sitting here. I'm trying to pull. I'm hearing the low end cut on you guys. I'm like, all right, let me cut the bass a little bit and ah, no. Well, this is the joy of Twitch streams. We can go a little bit crazy and Gomez can pull the wires out and plug things back in until we get it right and then we'll keep going. We have a great hour of content. We really appreciate all the people that are already watching and we will check what's going on right now. We've got Gomez in the studio. Oh my gosh. And in the meantime, since I think Jeff is the one you can hear the best, he can find a way to entertain you all. Hey, I'm just doing a thing. We're gonna write some code. We're gonna... So Jeff, maybe go back to the agenda and show people what the day is gonna be about. We're gonna kick back there so maybe you can... There it is. So... Okay. XAML tolling for WPF and UWP. This is really where we need to get in for those folks that are just getting on the bandwagon. You haven't built Windows applications in a while. You're not used to seeing XAML. You haven't done WPF yet. You wanna get in, you wanna get a little bit more familiar with these topics. That's what we're gonna cover in this first hour. Prism and what Brian Lagunas is gonna bring us in the next hour after that is it's a great framework that you can use to standardize the way that you build and lay out your applications. It's... Right, it's... How would you guys explain Prism? Well, Prism is all about enabling MVVM, which is the pattern that a lot of developers building desktop applications finds suits that sort of application really well allows for a lot of testability, code reuse, and really enables the kind of clean separation of code that makes moving fast possible as a team as long as you have the kind of the baseline where everyone's coding at the same level. I've done many projects around MVVM where it really did take about a week or so for the team to get oriented, make sure everyone's following the right patterns, but after that, we were usually golden. Yeah. I see one question. Will there be any talk about DirectX? Do you have any specific questions? I don't have any content planned specifically about DirectX, but I'll try to answer a question. Yeah. Yeah, absolutely. And guys, your audio sounds a lot better now. All right, cool. Big thanks to Golnaz out there for putting that in. Yeah. Awesome, and we're getting some comments as well. Oh, that's much better. Yeah, look at that. That's much better. Great, thank you Golnaz. Thank you so much. All right, fantastic. Yeah, Ancient Coder says audio is fine now. I trust Ancient Coder. Cool. That is great. All right. All right, so how about we restart from the beginning because I feel like those people coming in later on demand will appreciate a clean cut and then we have plenty of time to get the session done. Welcome. Hi there, my name's Jeff. Welcome back. Welcome back, attempt number two for those watching when we cut the other stuff out. Yeah, absolutely. So really, this is a full day to show folks how cool Windows development is now, how much there is that we can do with these things so that you can get, not just, I mean, it's okay to build a website, but when you actually need to build an application that has to attach to sensors, that has to do things richer on the desktop, you've got a lot of options. Yeah, definitely. So we've got a great day for you here. You know, then you'll take the first shot of the agenda, I'll take a second shot. It's, today's all about desktop developers. Today is a day where here's the agenda. We've got seven hours of content, both from Microsoft product teams where Daniel and I work from our MVPs, which are, if anybody doesn't know, is the community at Microsoft, the people that we saw nominate as champions of our technology that don't work for Microsoft. And then we go back to, again, product teams, cloud developer advocates and others who are gonna walk you through all sorts of desktop related topics. We're gonna start with what desktop, like WPF and UWP developers can do today in Visual Studio to make them very productive. We're gonna jump into Prism and reactive NVVM frameworks to talk about the right patterns to implement for your desktop applications. We're gonna jump into the future. We're gonna look at .NET Core 3, which is coming to WinForm and WPF. We're gonna look at modernizing UIs, XAML islands, and things like the Windows 10 APIs. And we're gonna close the day with an introduction to XAML Informs, which, you know, lots of people still love to see because lots of people haven't really started. And XAML Informs keeps evolving. So if you haven't looked at XAML Informs in a while, I think you'll be surprised just how much easier it is nowadays to get started there. And we're gonna end with my favorite topic, DevOps, CI CD for desktop applications, something that, honestly, we should have been talking more about the whole time, but we weren't. And now we are trying to fix that and bring that to a forefront because, you know, it's one thing to invest into technology. It's another to actually talk about it and make sure people know so much is going on. Absolutely. Yeah. Some of the themes of today is just trying to make you, as Windows developers, more productive and show you some tools that you might not be familiar with. Absolutely. Now, go ahead, Jeff. I was gonna say, there's a comment here in the chat room about even being able to put UWP apps on things like a Raspberry Pi. Yeah. Yeah, one of my first demos at Microsoft was building like a shop analytics thing that had a couple IR beam sensors so that when something went through it, like a person walking through a shop, it connected to an Azure server and sent a notification and recorded it in a database all on a Raspberry Pi. It was pretty amazing. Oh, very cool. That would make sense if you wanted to track things like how many times people walk into, into the changing room at a store. Oh my gosh, that's, okay. Yeah, so some highlights that Dimitri covered before and now we're kind of switching roles since we restarted. There are so many developers that still use Windows Forms and WPF to build desktop applications today and we constantly hear that they're just super productive. They're familiar, they're powerful and they're easy to get started. So we're kind of re-energizing that community and re-investing in that community with modern tools, with .NET Core, with bringing everything open source and this is kind of just one way to talk to the community and make sure that we have an open channel of communication. One of the beauties of open source is that this isn't the end. We want you to engage with us kind of throughout this process. Tell us what works. Tell us what doesn't, give us feedback, engage in those repositories on GitHub and ultimately we want to build the best solutions for you. So I'm really excited to be a part of this community and I hope you are too. Daniel, you make a really great point there. Being open source isn't about dumping source code. It isn't about saying, oh, here's the code, you go figure it out. It's about becoming part of a community, getting that feedback, getting that rich interaction so that when we do build things folks say, this doesn't make sense, what the heck are you doing? And or being able to say, you know what? This really helps another scenario that's really cool and valuable to my organization. Here's an issue for it and here's a pull request that maybe it's not 100% best code but it gets Microsoft, gets the project maintainers in the right direction. Really a lot to say about opening the community for Windows development. Yeah, and that's what we're doing. So we kind of already belabored this point with our previous conversation but just to drive the point home, Windows Forms, WPF and Windows UI XAML Library, the Windows 10 controls are all available today on GitHub and we're constantly adding more code to those repositories as we just kind of build up that infrastructure and working with the community to make them awesome. Finally, just talking about some desktop improvements we are making that are kind of new and modern for desktop developers is XAML Islands and XAML Controls. We've got a full talk on it today and later on in this actual hour, we'll do kind of an introduction to that. And we're also making it really easy to access all of the Windows 10 APIs in your existing.net desktop applications or in desktop applications targeting.net core. Last but not least, one of the things we've been doing since kind of the very beginning of supporting desktop applications in.net core is we're working with real customers building large-scale applications to understand what it is they're most looking forward to and understand how we can migrate their applications. And some of the things we hear time and time again is just deployment flexibility. If you've been building.net applications for a long time, you are probably familiar with the pain that is.net framework updates and deploying.net framework updates to a large community of devices and that prevented kind of agility in our ability to innovate. So customers couldn't take advantages of updates because they had to do.net framework updates. We had to be really, really extreme about compatibility guarantees so that they could actually take those updates without breaking the world. And that's made it difficult, but with.net core and the ability to deploy side-by-side machine-wide frameworks or even an app local framework, you can innovate at your own pace and we can deliver new value to you with every new.net core release. In addition, we have some core runtime and API improvements. And if your application has heavy file dependencies, heavy networking dependencies or SQL IO dependencies, you may also notice a runtime performance benefit. So it's another good advantage of.net core. And with that, we're gonna start getting into demos. Today is gonna be a huge demo heavy day. It's all about demos. Yep, so just some takeaways at the start so you can kind of keep the theme in mind as we go on. But I wanna make sure, hang on, I wanna make sure that we make it clear, this isn't just demos, right? We wanna make sure we hear from our friends there in the chat room. As we're going along and we're showing things, interrupt us. Tell us what it is that you want to see or if there's somewhere that we need to jump off and we didn't explain something quite well enough for you. That's okay, let us know. We'll back up, take a look and dig a little bit further into it if it's not clear for the chat room. This is about teaching you, the folks and friends that are watching out there. We give these presentations all the time. We wanna make sure that you get the content you need. All right, go ahead, I'm sorry. Cool, yeah, so from this first hour, some of the takeaways we hope you get is just becoming a more productive XAML developer. So you can see lots of XAML in our little bulleted list there. And one of the things that we're gonna do is go through each of these tools and show use cases of why they're valuable or why they may be productive for you. And then we also have a distribution list that you can all reach out to and send us feedback on XAML tools specifically. And this will actually reach to metering myself as well as the engineers building the XAML tools. So if you want a direct line to the product group working on a lot of this stuff you're about to see, send us your feedback. We definitely wanna work with you to make things better. But Daniel, we mentioned that Windows UI GitHub repository out there. Can we open issues there? Is that someplace that we know we've got engineers and program managers checking things out? Yes, so we look regularly on the GitHub repositories. If you file tools specific issues, you might get a redirect to file it in Visual Studio feedback, mostly because the engineering teams operate a little bit differently. So from a XAML tools filing issues, you can report a problem in Visual Studio using the little feedback icon in the top right. But if there's an issue with the platform or the runtime or any feedback or suggestions just to make WPF better, that would be encouraged on GitHub. We would love that. Yeah, yeah, right, this is the difference between Visual Studio is being still developed in the close, it's behind scenes here at Microsoft. But the frameworks, you can impact, you can make a change in out there on GitHub and watch what they're building. That's really cool. Yep, yeah, so let's get started. And for those XAML enthusiasts out there, I'm actually gonna start today with Blend. And one of the reasons I like to start with Blend is just it gets me into that design-focused view. And just for prototyping the UI, I think it's a little bit cleaner for me. So I'm gonna create a new project. We're starting from scratch today. And I'm actually gonna create a .NET framework WPF app. And let me set a little bit of context before I make too much progress. Right now, our desktop support for .NET Core is still in preview. We don't yet have all of our tools built up and ready to go. And so the XAML tools talk wouldn't be super useful. That said, most of today's content is going to be focused on .NET Core. And our goal with .NET Core is to make sure that you have a fairly similar and familiar experience if you're already coming from .NET framework. So while we're doing framework, most of what I talk about will also apply to .NET Core. And I'll call out several exceptions if there are any. I mean, to be clear, Daniel, you're right. It's been 15 years that we've built up WPF and all the frameworks that are going on around WPF in Windows to be able to announce .NET Core 3 and have something available as a preview in less than a year. That's pretty amazing. Yep, so we're going to create a project. I'm going to call it the map game because we're going to have a little bit of fun today. And it's going to be a really simple lap. So my goal is to build the entire thing in just about 15 minutes. So Dimitri has plenty of time to show off some other really cool tools. We're writing code in real time. What can go wrong? Chat room. Exactly. Guys, guys, we can make it better. All right. So here you can see I have a blend open and some of the default settings in the XAML designer and blend are with design focus in mind. I've got this toolbar on the left. I've got the grid lines enabled by default. And the way I view my controls is a little bit different. Instead of the toolbox, I have the assets pane to manage my controls and break them up into different categories and things like that. So just thinking about the layout of my application to get started, I'm going to want to kind of break up my UI into four quadrants. I'm going to have a big title at the top and then I'm going to have a column on the left side that allows me my user to do input. So in this case, all I really need is the longitude and the latitude, the coordinates of where I want my map to zoom. And then the majority of the content, so this entire section is just going to be a big map. And so to start, I'm going to build my layout. And fortunately with the XAML designer, I can go ahead and just add in some layout controls by clicking here. I can add a new column separator and here I can add a new row separator. So that's the gist of the layout, but I'm going to go in and edit the row definitions to be a little bit cleaner. So let's make that one star and make this five stars. And that way I've got a big enough column to host a couple buttons and a couple text boxes. And then I'll do the same thing on the left. So let me zoom out just a little bit and again one star and let's do this about four stars. The last thing I'm going to want to do is I'm going to want to put the button on the bottom left just for some styling. So I'll add one more column. And actually let me adjust my column settings once more. So I'll make this two stars. I'll make the bottom one, one and a half star. And then I'll make the majority of the content 15 star. I'm eyeballing it. This is what I like to blend for is it kind of gets me into that design mode and I can just visualize exactly how I'm creating this. Maybe 10 stars is ready. That looks pretty good. Cool. Last but not least, I'm nitpicky today. So the button's going to go here, which is going to search. I've got a couple of fields that are going to go on the left side and then I'm going to have a title on the top and then the map is going to take up the rest. So let's go ahead. Now you've been using this star here. Is star just a way to say this is a percentage of a... It's proportion. A proportion, thank you. That's a great question. So if you think about it in context, one plus five is six stars. So this column should be one sixth of the total width and this is five sixth, or this is 20% of the size of this basically. It's much easier to do than using Bootstrap with 12 columns and I've got to divide by... Okay, got it. So the first thing I want to add is just a text block for my title and I can drag it and drop it onto the designer. And then if I click on it, I can actually have it span across both grid columns. So it's automatically setting the XAML behind the scenes. And with snapping, I can actually get reasonable margins relative to the layout control. So I'm going to just put it there. One of the pieces of feedback we've gotten fairly regularly using the XAML designer is that the XAML that it generates behind the scenes is a little messy. We haven't fixed that yet, but we're working to make that better. And this is one area in particular we would love your feedback. So again, that XAML designer feedback at Microsoft.com. This is something you're interested in. Let us know. That's it, I'm going to go ahead and change the text to say, where is Windows Dev Day? And let me make it a little bit bigger. 40 pixels. And it's getting a little cut off on the bottom. So let me actually make this three stars. And make this big to account for that. There we go. Cool. So now on the left side, I'm going to add in my other field. So what I'm going to need is two labels so that I can label longitude and latitude. So those are going to be more text blocks. And then I'm also going to need text oops. I almost forgot one thing. Text oops is my favorite. Text oops is my favorite. So when I'm thinking about the layout, I could do another grid layout here and position everything relatively with margins or things like that. But again, if I'm just thinking about it from a layout standpoint, all I want to do is vertically align all of the controls in this column. And fortunately there's a panel for that. There's a stack panel. So I'm going to go ahead and drag in my stack panel into that section of the grid and just make it take up the entire column so that every control placed in the column will automatically be vertically aligned and just on top of one another. So now let's add in my control. So I can add in a text block and a text box. And this will allow me to label longitude or latitude and then have someone enter that. And then I can just go ahead and select both of these by pressing shift and click and holding down the alt key to duplicate them. So I'm going to need two, one for longitude and one for latitude. Just trying to make things go a little bit quicker. Some of the other things that I really like in the XAML designer as well is if I select all four controls by holding control or holding shift, I can go ahead and modify any shared properties. So all of these controls, text box and text blocks have a margin property. And let's go ahead and set that now using the property editor. So now they're a little bit more spaced out. I think that's a little nice. But I think I want these two to be a little bit further down from the ones above it just to separate the fields. So in this one in particular, I'm going to add a little bit more margin to the top. Now in the text boxes, I'm going to clear out the text because the user's going to enter the text or when we're running the app, we'll enter the text. And then I'll add longitude and latitude here. Longitude. Last but not least, I need that button that I was talking about. And so I can search for it in my assets pane and drag it to the bottom of my grid. And again, just using the margins and things like that, I can make it take up a little bit extra space. And what this button is going to do is it's going to search for those coordinates on the map and zoom the map into those coordinates. So let me change the content of the button to search. So Daniel, you put labels next to the text boxes. A lot of folks when they're building web pages, they like to put the label actually in the text box as a placeholder. Is that something you can do with these controls as well? There's ways to do it with some more advanced styling and there's a bunch of content online. Like if you search for stack overflow, there's definitely ways that you can do that. But for now, I kind of prefer this way. I like the old school style. Sure, this is the in the box controls. Yes, and when you think about it from the scenario standpoint, if I enter in just like a random number here and then that shadow text disappears, I might not know what that means anymore. Like, okay, why did I, which one is longitude? Which one's latitude and things like that. But yes, there are ways to do it so that you can replace shadow text in a text box. Cool, great question. One of the other things that I like about Blend is just styles and resources management. This is one feature that is not yet available for the UWP designer. And this is also an experience we kind of wanna rethink and make it better in the future. But that's just resources management. So I can right click on any control in the designer and select edit style, edit a copy. And in this case, I'll call this label style. And I'm actually gonna place it at the application level. So one of the great things about using the designers, you can create these styles, put them in your app.xaml file. So if I click okay, it places it there. And now I'm in the process of editing that style. So I can edit it here, or I can actually go to app.xaml and I can see it here in the xaml itself. So when you say it's at application level, it's got global scope across the entire application that we can access and reuse the same style. Yes, so if I have multiple views, I can apply resources for my app.xaml, global resource dictionary to pretty much any control. So here you can see the style as soon as I created it, it's here. And right now it's just the default text block template style. But if I right click edit, it takes me into this edit view. And this is something that is exclusive to blend. So if you wanna see the types of styles that you're creating, you can go ahead and do that here. The other thing you can do, and I just wanna add that this is super useful. Like a lot of people have really complex applications. I mean, this app is really simple, but when you have an app with a lot of styles you'd be able to go in and preview you to make sure it's the style that you expect. That really works well. We talked to one customer that was even having really complicated styles that were actually hidden by default. So even if you try to preview them, you couldn't. But what he would do is he would go in and just make him visible temporarily, just to check them. We're always looking to learn from examples like that. Maybe in the future we can make it even better. But the point is that there are paths forward to make you successful even when you're doing something very complicated there and keep the feedback coming. We're here to answer questions. Yep. Yeah, and so obviously when I first do that it's difficult to see the text block but there's fortunately a little toggle button. So when you're working with styles that may be difficult to see on a dark background you can just toggle it and switch it. And so here I am editing the style of the text block. So what I can do is change the fonts and then let's make it a little bit bigger. Hang on, let me hide your camera there so we can see it since it's in the lower corner there. There you go. Now we can see it. So all I did was change the text. So Sego UI Lite and I made it 16 pixels. And if I return to my main window I can see that the update has been made and I can toggle the art background. So I like the dark background a little more. And you can see it applied to that text block. One of the other great things about Blend is you can just drag and drop styles onto controls. So if I get rid of this selection mode and select the text block and drag the style onto the text block I can edit the style and apply them that way. So obviously this is kind of a simple example but fortunately I prepared a couple added styles beforehand. And since Blend is now in the Visual Studio shell we do have the XAML editor which is one of the benefits of having the two together. So if I go ahead and make the XAML full screen and paste in a few more styles what you'll see on the right hand pane before I do this all of the styles are gonna populate there immediately just like that. And you can see the target that they apply to. So here's the button, here's another text block, here's a text box. And now let's go ahead and style the rest of my application really quickly. So I've got rounded buttons which should apply to the button. That looks pretty nice. I might need to add a margin there. Rounded text box. Style, okay. Oops, the wrong thing. Ah, as you can see if you double click the resource it takes you into the resource editor which is a misclick. But again, that's one of the benefits of Blend is you can see the changes you're making to that style. Well, I really like this idea, this concept of being able to drag a style onto whatever control it is in the user interface. We didn't really have this with CSS for web developers but to be able to do it naturally like this feels like something that a designer, somebody who's focused on user interface they don't have to think about what property do I need to set or wherever. This is the style I want, just put it on this thing. Gosh, I think there's a lot that we could learn from that in normal, in full visual studio and not just Blend to make it a little bit easier experience for folks that are building applications. Yeah, absolutely. And that's really the goal here and that's kind of why some people really, really love Blend, myself included. It's just, if you think about it from like a cognitive context switching exercise too it's, this is my design tool. Like when I'm in design mode or art mode I use Blend, when I'm in coding mode I use Visual Studio. So just thinking about it that way is interesting. So I've got my layout pretty good. One of the other benefits of Blend being in Visual Studio is you can run your application directly from Blend. So I will hit F5 and I can at least take a look to make sure that it doesn't look crazy. So that looks pretty good. My button's a little wonky. But let's go ahead and take a look at why and I'm jumping the gun here just to make something. For some reason it put it in the wrong row. So I'm going to fix the row and remove the margin and actually just make the margin five. And that still looks kind of weird. Let me make this. Oh, some of the layout got messed up. That's why a good row span is two. I don't want that. You know, one of the things I'm going to do just to get this right the first time is let's remove this button and try again and make sure that it ends up in the right place. I think earlier when I was messing around with all the grid row sizes, I was messing things up with it. So let's try to make sure it lands in the right spot only in this grid row and column. There we go. So now the margin seemed a little bit more reasonable which means I think I'm in the right spot. Now let's go ahead and apply that style one more time. There we go. And now I can make it a little bit bigger. There we go. That looks good. Last but not least, I need to edit that content one more time to search. And this is just kind of like when you're thinking about your application, it's good to figure out the layout first and then build the experience. There we go. So now I've got my search button and that looks pretty nice. I can hover over it and think. So there's no code. All that you've done is literally build the facade. This is what it looks like. And then we can go wire that up to code later, right? This is that division of responsibilities. Yes. And one of the things that's nice too is I even have like tab targeting because these two controls exist in a stack panel, one on top of the other. So I can tab between them, which is great. But now we're gonna go into code. So now I'm gonna do that context switch. And fortunately, I can just right click on a file and select edit in visual studio. And now I have visual studio 2019 launching. Adam, were you, so there's some feedback in the Twitch chat that I wanna call out that saying, when I'm looking at the grid lines and the road lines, although the colors are different, it isn't so easy to differentiate them to my eye. Is there a way to adjust that color difference? Can you please send us that in an email? I definitely wanna make that better for you. And I think that's an easy win that we could do. So they would do that, Adam would do that by clicking the feedback button at the top of blend? You could click it in the feedback button at the top of blend or visual studio or just send it to XAML designer feedback at Microsoft.com. Cool, I'm gonna drop that email address in the chat room so that folks can get that XAML designer feedback. Thank you, thanks Adam, that's awesome. So this is visual studio. As you can see, if you're familiar with the blue theme, things are a little bit different. This is 2019, we updated the theming just a little bit. But it's still your familiar IDE that you're probably already used to. Here you can see I have my full XAML view but I'm going to switch it to be half and half. And now I'm gonna start adding some features. So the thing that I wanna do is I wanna get the data from the longitude and latitude box when I hit the button and search for that on the map. And this is, I wanna take just a moment here to show off one of my favorite new features. This is currently available as an extension to visual studio and it's called IntelliCode. And I can see, I think Jeff's face is covering it so I'm moving it higher up on the screen. Hang on, hang on, I can hide my face here. That's easy for me to do. Yeah, yeah, Jeff, can you please like, poof, is there like a smoke effect did you do? So let me, let me explain this next feature with an example. So in the button control, if I hit space at the very beginning of the control, my intelligence shows a starred recommended list of properties that I probably wanna set given the context of where I'm making that edit. No, wait, those stars aren't part of the name. That's, it's saying these are suggestions. Yes, these are recommended suggestions that are driven from a machine learning model sampled off of tons and tons of GitHub repository data. So open source projects. So it kind of enforces the most popular patterns but it typically makes sense if you wanna find the name of your control that's what a lot of people do first. So I'm not gonna enter that just yet. I'm gonna just change the context within the same control. So I'm still editing the button but I'm at the end of the button. If I hit space, it recommends a different set of properties because those are maybe more likely to be at the end of the control. So if you think about patterns in an organization or things like that, everyone starts putting these properties in kind of a similar order. It makes the code a little bit more legible and easy to read. Wait, hang on, hang on. In telecode isn't just telling you these are the important ones that a lot of people use but at this position, this is the one that, oh man, all right. I've already been sold on this. Amazing. For example, it is so cool because of just the declarative nature of the language. It just makes it so like you pretty much just hit tab to code. So there's my name. I'll call this search button and then I'll hit space again in this context and click is the third one. That's what I wanna do. I'm not gonna do MVVM because we're going quick. That's the next talk. So then I need a couple of names for my text blocks as well. So I'll call this, whoops, not text blocks, the text box. I need to get the text property later. So again, name comes up first. I'll call this long box or my longitude box, not because it is a long box. And then again, same here, lat box. And then I will actually go into the click event handler. So let me go ahead and here, I can right click to go to the definition of this event or just press F12 and it takes me to the C sharp definition. Now, the last thing I wanna do is I don't even have the map control yet. So now I'm gonna add my first external reference. I'm gonna go into manage new get packages and I'm gonna search for one that's called the Microsoft tool kit for WPF development. And you'll hear more about this later in the XAML islands talk, but in this toolkit, which is produced by a team at Microsoft, we've made some of the more popular controls that you might wanna use that are UWP controls in WPF available. So let me show you how easy it is to actually just add in a map control that is the UWP map control. So I added that reference and we're getting to one of my next favorite features that we added in Visual Studio, I think it was early 2017. So some of these things have been around for a couple updates, but they're still relatively new. So I type map control and I'm getting this quickly because I'm missing that namespace reference. When I first started XAML development and I was just learning, oftentimes I would refer to websites or sources and I would add in a control and it wouldn't work and I wouldn't know why. For those of you that know why it's because of the missing namespace, we have a control.experience or the light bulb experience to go in and just add missing namespaces automatically. So here you can see, I put the map in the top left, I don't wanna do that. So let me put it in the right row. In this case, I'm gonna put it in row one, column one, and I'm gonna make it span across two rows. One thing you'll notice because this isn't a first party control or it's not super popular on GitHub, you don't get the IntelliCode suggestions. We can only make those suggestions on data that we know about and this is the one that we don't have that data. So no stars for stuff like this. But I will give this a name, I'll call it geo map so you don't get it confused with like the object type map and then I will go back into my click event handler. And ultimately what I wanna do is I want to figure out the location. So the way I'm gonna code is I'm gonna just use the Visual Studio tooling to look at the properties and the methods so that I can figure out how to write this. You could also just go to the documentation which is surprisingly great for this toolkit, it's really, really good and they show you exactly when it's going to work, how it's going to work, all of the properties, all of the methods and what they do. So if I go back, I can hit my dot, filter to just methods and I'm probably gonna wanna set the view or something like that. I'll just sort to set. So I see a couple of different methods, try set view async sounds about right and that takes in a geo point object that they call center and I can also give it a double zoom level. So I'm gonna work backwards, I know the objects I need, I need a geo point and I need a double. So I'm gonna comment that out for now. Using a keyboard shortcut for those of you that don't know, control K, control C, comments out a single line of code and then I need a geo point. So geo point and again, I can use control dot. So I'm trying to create a geo point object. I don't have the reference but the visual studio can get that for me and I'll give it a name geo point equals new geo point and this has a constructor that takes in a geo position. So again, working backwards, I can get my basic geo position. Again, I'll use the recommended name equals new basic geo position and this does not have a constructor but it does have a couple properties. So I'm gonna just go ahead and use C sharp to create those properties in line. So latitude is going to be equal to, I've got my lat box, don't forget that I created earlier. And again, I have in telecode and C sharp. So I think one of the, this might be an obvious example when you're trying to call an object that is a text block or text box, sorry. The first thing that shows up as text totally makes sense. But this is actually a double. If I hover over it, I can see this is a double field. So I need to do convert dot to double and then I need the same for longitude equals converts dot to double and then long box dot again, text. And then last one at least. So now I have my geo position. I can construct my geo point just like I can comment out with a keyboard shortcut. I can also uncomment with control K, control you. Can you do me a favor real quick? Can you increase the font size there to about 16 point? Is that better? Yeah, that works. So I've got my basic geo position objects. I've got my new geo points. I can create that. Last but not least, I can try to set the view of my map based off that data. So let me go ahead and make that geo points and then I'll zoom into a zoom level of about 14. And now why would you choose 14? Where'd that number come from? So I came from here. You've done this before. You've seen the example. Even in the docs, they kind of give you a hint. So when you see the tricep view async that they use, they use 12 and that gets you to about this zoom level. That's also in the documentation. And I want to go a little bit more zoomed in than that. Okay, so 12 is like at the city level. Yes. Gotcha. Yeah, that's about right. And we're going to go, you're going to see exactly where we are in the channel nine studios when I run this application. So I'm going to try to run the application. There's a comment unrelated to this. Well, Visual Studio changed the keyboard shortcut for commenting to match that of VS Code. I thought VS Code uses the same keyboard shortcuts on Windows for commenting and uncommenting. Well, it's all customizable too. So I'm actually not sure. I've never paid attention to that detail. But if it's not matching today by default, when you install both, I would be a little bit surprised, but it doesn't mean it's not true. So I am f5ing the application and. You're f5ing. You're starting it. You're starting it in debug mode. Yes. And I have an exception. And this is by design. I want to make a point there. So one of the things that you need to host XAML Island content is a package identity. And what that does, again, we're getting more technical here. So for those of you who really want to know the details of why, one of the things Windows 10 does is it can change the behavior of your application based off of some of the properties in the package manifest or the identity of that application. And this is so that if you test your application on a version of Windows, there's an update of Windows that might change the behavior. Well, because there's a max version tested property of your application, your application will behave just as you expected. So fortunately, one of the other new things in Visual Studio from Visual Studio 2017 is a new project template called the Windows Application Packaging Project. And this gives you a package and a package identity. So if you just think of like the Windows 10 packaging concept, that's what you get. So I can see Windows Application Packaging Project. I'll call this package. And then it gives you the option to set your target version and your minimum version. I can just leave the defaults. This is an insider preview SDK. So it's again, bleeding edge. And now what I'm going to do is just change the context of how my application is going to run. Now, if I'm building this and I'm not using an insider build of Windows 10, I don't need to go into some of that depth, right? Do I need to set that? So for the XAML Islands controls, you will need a Windows Application Packaging Project. Okay. And what that does, it gives you other things too, especially when you think about the DevOps talk at the end of today, you'll see some of the value of using the Windows packaging concepts. We can do automatic incremental behind the scenes updates for your applications, which is really cool. Okay, so it's the only reason that you had to choose an insider's build is because on your machine, you're using an insider's build of Windows 10. XAML Islands, some of the features in XAML Islands are still preview. The features are coming up and they'll be released. So like this is bleeding edge stuff. So you need it for the island. Very cool, okay. So now I changed my startup project to be the package and all that's going to do is make it run with the Windows package context. And so you'll see a slightly different taskbar icon and things like that. All of those are configurable by editing the package at the Xmanifest, but this is XAML Talk, so we're not gonna go there yet. And once this runs, I think this computer running Skype and PowerPoint and DS and all sorts of stuff is. Run all the things. Yep, but it should be just about done. And so now what I can do is, there it's loading. So while this is loading, just to respond to the chat room, there's been some talk about XAML Studio and what I would say is we build that project. There's an experimental project here at Microsoft. It's not built by the primary tools team that Daniel and I work on. So we were very transparent about things like this to say that Microsoft has a lot of people coming up with a lot of cool things. And if you really think that XAML Studio is really solving a particular problem for you, please let us know. That's what we're here to hear about. And we hope to take good things and bring into future products. We just can't obviously guarantee anything, but XAML Studio as a thing is not, a primary tool that we work on. So we really would love to extract the things that work there really well and bring you to the real products. The real developers are using Visual Studio and Blend to keep that coming. So here you can see now I have my map. This is the Windows 10 built-in platform map control. And this is new. So this is something that is kind of coming up that you'll be able to do. And it's really just that simple for a certain set of controls that we're building. So let's go ahead. I think it's important to kind of note why that's so special, right? We've had a map control in the past. The point is that we're bringing some of the UWP controls, including giving you a lot more flexibility which ones you can use back to WinForm and for WPF developers. There's a question that I can address immediately as well in the chat. Is it possible to remove this black bar? Demetri is gonna go into details about the functionality of that. But yes, if you select this button here in the top left in the live visual tree pane, that black bar goes away. So I've entered in a longitude and a latitude. Let's see if the application works. So I'm gonna search. It's zooming, it's zooming. And there we go. So this is actually where we are right now hosting this live stream content. And just for some fun today, I've got one other coordinate because it's a special day. At least we're celebrating here in the U.S. Don't tell me you're finding my house. Don't tell me you're finding my house. We would never do that. We would never show your house. Maybe your state. Maybe. This is the middle of New Mexico, Pytown. I just looked this up before the stream though, so maybe not. It's still rendering. Yes, it is still rendering. There we go. Let's zoom in on it. Let's see if it says Pytown for Pytown. Drum roll. There we go. Yeah. So happy Pytown and there's our Where's Windows Dev Day, pretty simple. There we go, look at that. Pytown with Pytown, nice. Some of the tools to get up and running quickly to style your UI, to build the simple layout, things like that. And now I'm gonna hand it over to Demetri to show you some more advanced tools for really diagnosing and troubleshooting those tricky issues. All right, so I'm gonna go ahead and share my screen with you guys. Hopefully you can see it. There we go, we got it. Awesome. All right, so let's talk about some more tools in Visual Studio. So I'm gonna go ahead and introduce an app that I'm gonna use as my demonstration. This app is open source, so everything you see me touch today will be available. The link is already kind of in the show notes, so make sure that's easy for folks to find. So this is an MSIX catalog app. One of my teammates built it because he wanted a tool that could easily demonstrate some of the things we were working on, quite frankly, so this tool is used for us internally by the team to test certain things we were working on. But it's also a cool tool that lets you see all the side loaded applications, all the ones that are installed under developer mode, all the ones installed by framework. So it's a great little app. Let's see the manifest, let's you open the folder where you can find the application itself, things that are actually not super easy to do on Windows. So it's a cool little application. And I'm gonna use this to basically demo all the things I wanna show today. So let me just interrupt you just to make sure everybody's on the same page. An MSIX, right, an MSIX, that's the application package distribution format. Yes, yes, that is the way, one of the ways you can install things on Windows and this application lets you see various things that were installed using MSIX or... There it comes, there we go. Okay, all right, let's hope this stays stable. There we are, all right. All right, awesome. So I'm just gonna have to point my laptop at the microphone. I mean, the camera is gonna be really awkward. Yeah. All right, so let's talk about the tooling inside of Visual Studio for working with XAML. I'm gonna take you folks on a little bit of a journey through the various tools that we have built and hopefully show you something that you've never seen before or maybe show you a part of a feature that you've never seen before on one of these panels. So I'm gonna start with the very, very basic thing. When you open a XAML page, so let me go ahead and open, let's say, main page that XAML. Doesn't really matter what this XAML page even does, I just wanna demonstrate what the tool does in regards to this page. So of course, you're gonna get the normal designer loaded and you're gonna see the XAML code behind. One of the things that I wanna point out is this app, if I didn't change the background color of my designer, wouldn't have been super great. So I wanna point out the stuff that is customizable. Like if you are seeing that your app is not rendering super well in the preview of the designer, because of the theme of Visual Studio you selected, I like the dark theme and that was causing me some problems. You can actually go ahead and change that in settings. Pretty simple to go ahead and do. So if you really want the hot dog theme for your application, you can do that and you can adjust the way Visual Studio presents it so that it's visible. Yes, yes, there you go. Because sometimes, while you're in dev mode, it's something that could be a little more painful than the real app itself. So just wanted to point that out. So coming back here, I wanna point out a tool that we've had for quite a while called the document outline. This is this window here on the left. This tool actually lets you see how your XAML is put together in a hierarchical view. So you can go ahead and expand, let's say, the stack panel and see what's hosted inside the stack panel. In this case, this right here MSIX catalog, this icon, this is all part of the stack panel. So if you're new to XAML and you're looking at some sample app where you're working with a complex application, sometimes it's just really useful to be able to jump in here and see how it's composed from kind of visual hierarchical view. But you can also do some other cool stuff. People don't realize, I say people don't realize only because I've talked to customers, I've asked them questions and they didn't realize this feature was here. So one of the features is this hide icon. If you click the little I, you can actually make things go away. Now this is not changing your code at runtime. If you run the app, these things will still be visible, but if you're just kind of designing, that's really cool because you can preview what it would look like if something was or wasn't visible. You can also do something that some folks don't realize inside of designers as well, which is you can hide the grid or you can show the grid. Some people think that the grid's only available, for example, inside of Blend, but it's actually available here as well. So there's little things like that that you might not have realized. Coming back to the document outline though, it is another cool feature, which is the lock. So you can lock an element. So let's go ahead and lock this icon. That means that I can drag other things around it. So I can actually go ahead and make other changes. See they're kind of draggable, but this is not going to be draggable. This is going to be locked. So this lets you lock sometimes a very fine element when they're really close together so that you don't accidentally drag the wrong thing around. And it's just a little useful tool to know about. And you can really easily see how the page is composed. In fact, in preparing for this demonstration, we're working with this app, actually found a bug by using the document outline. So I was looking at the document outline and I was clicking around and then I clicked over here. And I realized that this stack panel had three text blocks. So that made me go to XAML and I took a look at this and I said, okay, well, in my opinion, and there's more than one way to get this done, but in my opinion, this isn't the best way to do it. You should use one text blocks with three runs inside of it to make this composed a little bit cleaner. So I'm going to save you folks the typing, but basically I went ahead and I created that XAML to replace it. And I was able to go ahead easily come in here and change that out. And now there's one text block, three runs. This is a bit cleaner. In my opinion, it lets you control things better. So there you go. This tool can already help you find something by inspecting things in a hierarchy versus just sometimes looking at a lot of XAML which can get a bit confusing. And there's one question from the chat. Can you reorder them by drag and drop if you want to try to do that and then undo it real quick just to show you. Yes, you can. There you go. You can definitely do that. This is a place where you can see what something is named. Like if you give it a next name, you can see that. You can see what type of control it is. You can move things around. You can make them hidden, unhidden. And sometimes you can find a bug. So it's a really useful tool. This is the visual in visual studio. Yeah, this is all visual studio and the document outline is there for you as you're building your XAML. When you run your app though, the document outline is read only. So you cannot interact with it while your app is running. But we're going to show you other tools that you can use. So let's go ahead and start the application and talk about the end-to-end experience of debugging your running app. Because I find that a lot of folks don't realize we have some really great capabilities here. And all of this is available in VS 2017 and even before. So definitely should be available. If you don't see the window, just go into the quick search at the top. VS has a little quick search thing and you can type document outline and there you go. There's a document outline control. All T I guess is the default keyboard shortcut. All right, so the app runs. We have inside of the app something that we put automatically there. This is there for WPF and UWP. This is this bar right here at the top, this collapsible bar. You can click to collapse it or to not collapse it. You can't move it unfortunately, but it's always here at the top of the application. This gives you some debug features. Really awesome ones. I'm going to show them in a second. But first let me once again answer the question that was asked before. What if you don't want to see it? Two ways you can get rid of it. You can actually go into settings and turn this off. I don't fully recommend that because turning it off means if you ever do need it to debug something, it won't be there for you. You'll have to stop Visual Studio from running the app, go enable it and go use it again. So that's not a great experience. But what you can do is click this button here in the visual, live visual tree. But let's assume that you don't even have a live visual tree. There you go. I collapsed it. You don't know what a live visual tree is. You don't understand how it's connected. Let me explain all of that. There's a button inside of this in app toolbar again, the app bar right here at the top. If you click on this, it actually opens the live visual tree. Just to show exactly what happened here, I clicked this button right here and it opened up this panel right here. You can also, once again, use the quick search at the top to type live visual, so there you go, live visual tree. So you can open it that way as well. But just wanted to point out that this is a really nifty shortcut to get this thing open. Once it's open, as in once the live visual tree is open, you can click this very first button called show runtime tools in application. And if you click it, if you go back to the app, you see that this bar is gone. I have had to do that for real applications because sometimes it's not useful for me to have this is blocking something I'm actually trying to look at in the app. So there you have it. So I'm going to turn it back on and I'm going to show you the first feature that I want to kind of demonstrate, which is right here, it's called enable selection is the second button in. Hang on Demetri before you get too much further here. You've been using Visual Studio 2019 to show some of the features here. Yes. Are the features you've been showing, are they exclusive to Visual Studio 2019 or some of these also work in Visual Studio 2017? So this works in 2017, 2018 and 2019. We are actively working in some of these. So if you get into the latest version of VS and stay there with all the updates that are going to come out throughout the year, you're going to have the best experience, but a lot of the things I'm showing here have been in VS since like VS 2016 actually or even before that in 2015. 2015 with the updates. Got it. Yeah, so it's been quite a long journey. Try it if you don't see it there. Well, it might be in the future version that you're not using. You can install VS and give that a try to see if the features there. You can ask us questions on Twitter over here to help you. Yeah, Brian's asking about Visual Studio 2018. No, there was no Visual Studio 2018, just 2017's patches. Yeah, I always think about VS 2018 as VS 2017 with a lot of patches on it. So I'm just as confused as everybody else, but there you have it. It's all out there. All right, so now I'm going to show some features. We only have less than 10 minutes. I want to try to get to at least a few of the things here. So one of the really cool features is this enable selection button. When you click this button and you start moving around your applications, it actually lets you highlight different elements that are in your running apps. So in this case, if I click on that MSX catalog, it will actually expand the live visual tree in the left if folks noticed what happened there. So Jeff, we're going to need you to maybe vanish. Come on, poof. Seriously, I got to get out of here. You're fucking my toolbars. Come on, man. Love you, man. Oh, God, all right. So let me show that one more time. I'm going to unclick it so it goes back to where it was. I'm going to click it again and click on MSX and show how that expanded. The reason why we needed Jeff to move was because he was right there covering the button that I wanted to press. So you see this text block here? If I click on the little button next to the text block, it will actually take me to where in your XAML, the code is defined. It's a really great way to do that. So I'm going to do something first. This will just help me because of my resolution and because of the screen. So I'm going to go to my solution. I'm going to go to main page.xaml. And I'm going to make my app topmost. This will enable me to still have it visible while I'm making XAML changes because that will be important. So I'm going to set topmost to true. This forces my app. There you go. My app just appeared. This forces it to be always on top. So let's do this. We're going to move the app slightly to the bottom and we're going to go for this example. Again, we're going to click on here. We're going to click on here. So now we're actually looking at the XAML. My app is running. There's my app. You can see it. But you can see also the XAML that's making MSX catalog, say MSX catalog. But then I can do this. And in real time, it will update the UI to add whatever I'm typing. This is something that we have in the past called XAML editing continue. We don't think that was the best decision necessarily. In retrospect, a lot of things are clear. So we're going to call it going forward XAML hard reload because that's really what it is. It allows you to change the XAML while your app is running. This works with WPF and UWP. And there are a few small things that don't work for WPF that we are going to include in future releases. Hopefully we're doing our best. We're working on making this even better. So XAML hard reload is a feature that basically says that as long as your app is running and as long as you attach by hitting F5 because you can't, this doesn't work if you like attach debugger later. But if you hit a five, your app is running, you see the in-app toolbar, that's a good sign that means most likely this feature will work, then XAML hard reload is going to start working. So I'm going to show you another feature that's part of the family of the tools. So I'm going to go back in here and I'm going to again use this mechanism. I'm going to go in and I'm actually going to look at something deeper. So let's go click on framework. Hey, Demetri, there's a comment here. I think it's a pretty good one about the reload, the hot reload feature. That's not hot reload. Jerome says that's live editing. It is live editing. So we spent a lot of time thinking about how to name this feature well. And we came to this because if you look at what people are defining as hard reload and other frameworks, this matches quite a bit and why create another way of talking about something if a developer from another space comes in and they look at the feature and it looks like something that they're familiar with. So we're just trying to bring familiarity at the end of the day. Police talk about it however you want. It's really does live editing, 100%. That's true. It's a hot reload feature. That's just what we're calling it. I don't want to get too caught up on the name, but it's really good feedback. If folks really hate the name, we can always change it. We're pretty agile around here. Naming is hard. Yes, naming is hard. But if you think about all the other UI frameworks out there, everyone has a hot reload. So it's kind of a familiar experience to developers and we don't want to be the odd one out from a developer experience standpoint. It's similar. You're right. It's better in that it is live, but it also serves a similar purpose. Yeah. So let's go ahead and look at a few more things here. So in this case, I'm going to show you yet the third panel that is in Visual Studio. It's really cool. This panel allows you to do something unique. So let's work for what we did so far. We use the- I'll disappear again for you, Dmitry. Go away. We love you, Jeff. First, we use the enough tool bar to select an element. We showed you that. We showed you how the live visual tree shows you the tree that the element is part of. It lets you find the code where that code is defined for the element and we change the element and we got the app to change with hot reload. So we showed that end to end. But that's sometimes not the experience you actually want. Sometimes you want to experiment and sometimes you want to experiment with a comparison. This is a scenario that's come up many times in the real world for me. And unfortunately, sometimes it's hard to demo these things, but I can assure you I've been a XAML developer for a long time. This really is a useful feature and that's to change something temporarily and very specifically. So in this case, as you can see, there's three icons. All the icons are generated by the same styles. In other words, any changes I make to XAML are going to change all of these icons. But what if I want to experiment and I want to compare icon one to icon two to see how to make this a little bit better? So what I can do is- A little AB testing there between the two. There you go, AB testing. So you can click on this icon. I can then click inside of my live visual tree and then I can go up here to this button called show properties. Now this is not going to show the normal property view. This is actually going to show something called the live property explorer. This is a way to make changes that are completely temporary. It doesn't apply to XAML. If you restart your application, it will just go away. If you just reload the view, it'll go away. In other words, it's really temporary but it lets you experiment with how to make something better. So in this case, I'm thinking, man, this button seems a little bit too much close to the borders on both sides. It's maybe cutting off some of the icons and some of the cases. So sorry, some of this is just me moving the app around so that I can show you everything that I want to show you. So let's make that slightly smaller. All right, so I'm going to go ahead again, click on the button and now I'm looking at the live visual tree. So visual tree showing me that this button is actually composed in code. So things above grid don't have the icon next to them because this is just part of items control, things that you didn't write. But starting from grid is code you've written. So if you click on grid and you click on the button, you will actually go to the grid that defines it. And in this case, I can already spot a problem and I'm going to go ahead and change that for everything because I realized right away when I was testing this earlier that this should have been a bit better. So we're going to make this slightly bigger and I like to be pretty verbose even though this is the default. So I'm just going to be verbose that the right side of this right column here should take up the rest of the space but the left should have a little more space. So that's already great. But now I'm going to play with the icon specifically. So I'm going to click back in, click on the first icon and now I'm going to look at the border and this is where I'm actually not sure what changes to make. So I can go ahead and explore. I can say, well, what happens if the border was like half or really small? Okay, that's not going to work. What if it was bigger? Okay, that's maybe something interesting. What if I added a margin to it? Actually, margin is here. So let's go up here and I'm going to say, what if I had a bigger margin around it? 10 all the way around. All right, so you can see how this button is now starting to change and it's different than the next button down. So we're running out of time. So I don't want to be kind of be this point. I already messaged Brian that we're running a few minutes late. So we don't need to rush too much. Awesome, but I do have an after. So this was me writing the code in using this tool to experiment. Once I was done experimenting, I knew the final values I wanted and I went ahead and I implemented this as my final implementation. So this set of tools allowed me to kind of go throughout the whole app, go from where is this visual inside of my tree? Where is this element from the tree inside of my code? Can I experiment? Can I make changes to the XAML? So you can go ahead and use these tools to really go all over the place. So that's kind of cool. Another thing that we can do with hard reload is not just fixed bugs, but we can add features. So this is probably the last thing I'm going to show. So I'm going to go ahead and make some changes. So once again, to save a bunch of typing, I've made some handy clip nodes here. I'm going to go ahead into my view model and I'm going to go into package view model. And this is using an MVVM light pattern. So inside of my view model, and I had to stop my app to really do this super effectively. We're looking at that too, but it's harder. So we've got some fields that we need to add in order to add another feature to the application. So I wanted to add a feature to copy the clipboard. So I'm going to go ahead and populate parts of this MVVM view model with all the code that's necessary to make this work. So I'm going to go ahead and add this and add that. And this is not part of the main demos. Don't worry about it. There you go. I basically added the code that will now make it work. I'm just going to fix the using statements, which is the last thing. And I'm actually going to commit these changes if you can believe it or not to the real app. So we're making real improvements here. All right, so what did I do in recap? I added the command. This command can be bind to from the XAML. This is the clean way in MVVM to build this kind of application. I instantiated the command and set up my constructor and I provided a method that actually is some very basic code that use a string builder to build a string and then allows you to copy the string to the clipboard. So I'm going to go ahead and run my application now that my view model is in place. And I'm going to think about how to build a UI around this feature. So as soon as the app runs, we're going to see that even though I've added all this code to the view model, this code is not actionable. There's nothing in here. So let's click on some random view here. Nothing in here allows me to copy the clipboard yet. So how would I do this now that I realized that this Visual Studio tooling experience allows you XAML hard reload. I could do this. I could stop the app and I could make changes. But I can actually make these changes in real time. I do not have to stop the app. That's a really cool thing. So I'm going to go back in here and in fact, I'm going to let's use the tools, right? I'm going to click on this. I'm going to click on open folder and I'm going to think about, all right, so where is this open folder code? Okay, so it's right here. So I was able to find out where the button was, find out where it was in the tree, find the code behind it. And now I see what style composes these three buttons. So now I'm going to go ahead and I'm going to copy one of these buttons. Yeah, I think you can use Control-D to duplicate the line immediately below. Oh, there you go. Something new. Sure, so copy to clipboard. So you're getting that same hot reloading of your XAML code, the code that's doing the layout, the user interface, the design that Daniel was showing us earlier and it's going to still use the same C-sharp code that you've built and is compiled. Yes, exactly. We can't change the C-sharp on the fly but we can change the XAML on the fly. Yeah, you can pause, you can hit pause right here and you could change some C-sharp. But when you're creating a brand new view model, you're making substantial changes. You do have to stop today. That is the one limitation. But once you're done with that, a lot of my real world work in the past has been then tweaking the UI to get the view model to show up. Like it's easy to pull data from a database. It's really hard sometimes to make the UI represent that data beautifully in my application. XAML hot reload is what makes this possible. So let's go back in here. I made a copy of the button so it's still not doing what I want. It still has the wrong command binding. So I'm going to go into the command binding and I'm going to say using IntelliSense. We can move this down a little bit. So IntelliSense, look at that. It says copy to clipboard, which is what I added early as a command. So the view model binding is working. And now we have a button that says copy. So I'm going to disable the hot selection. So enable selections off now and now I can interact with the app. I'm going to hit copy and I'm going to start notepad. And in notepad I'm going to be able to paste. So there you go. We've created a full UI. I mean, this was a really, really simple example, but you can imagine how complicated this could have been. So this shows you the power of hot reload and the ability to keep editing and we're looking for all the feedback you can give us on making this feature even better. Another thing we were going to demonstrate but I want to give Brian the time that he needs was LiveShare. So we purposefully left some bugs in here and Daniel was going to join me on LiveShare and fix them. LiveShare does work more or less. We have one limitation today where if I use LiveShare and navigate to a class file that works, Daniel sees me navigating to it or opens for him. If I navigate to a XAML file that doesn't work, but we're going to see if maybe we can make improvements to that. So we know about this limitation. We're working on it. But no matter which file I was in, if Daniel did open it, he could see my cursor, he could do a code review and he could have helped me fix the fact that my tooltip was wrong and the fact that my copy had a duplicate on one of the lines, you know, little phone bugs we added but there you have it. The all the stuff is super possible. For the sake of time, I added the LiveShare documentation in the chat. So definitely go take a look. It's pretty awesome. All right, so with that, Jeff, I'd love to give Brian all the time that he needs. He has a really great session and folks, we're so thankful that you're here with me and Daniel this morning kicking off the event. Please stay on the whole day if you can or jump back in or come back and watch live on demand. All this stuff is going to be available for you. We're excited about desktop development. We hope you're also excited about desktop development and if there's anything that we can make better for you, please let us know how it's affecting your real world working with the certifications. I'm also going to add our Twitter handles in the chat as well. So you have again a direct line to us. Ultimately, as Jeff alluded to earlier on, this is about community and building community. And we definitely want you to be a part of our community as we build up the .NET Core platform, the new tools, all of that. Very cool stuff. Thanks so much guys. That was a great way to start and show the basics of what the tools are capable of. Yeah, you needed to learn a little bit of XAML to really get in and know what's going on here. But to see what it's capable of, even simple samples like we saw and how quickly you can build an application that does mapping and zooming in on things. Really neat stuff. Thanks so much for sharing. Great to be here. All right, I'm going to, where did it go? There it is. All right, now we got it back. All right, oh my gosh. You can read, sorry about that. My apologies. Let's get Brian on the phone here and see if we can start working with him. Hey, there's Brian. And we should get my video coming back to you. No, of course it's not going to right away. How's it going, Brian? Let me bring up the, let me bring up the, that's not right. It's still the other one. Hang on, hang on. I'm running a little slow. There we go. I've done this before. Thanks so much for joining us today. And let's put up some name plates so folks know who we are. There we go. Hey, Brian, how's it going? It's going, I'm not seeing you. I know, I don't know what happened there. You're like, you're gone. I'm gone. It's all blacked out there. I'll see what I can do to get that to come back here. Thanks so much for joining us and you work on, well, why don't you give folks an introduction, who you are, what you work on, where you're from? Yeah, well, my name's Brian Lagunas and I'm known as the Prism Guy, if you will. I work out of a, my home office here in Boise, Idaho. Are my audio levels okay? I'm looking at the chat here and it says, something about audio. Yeah, I'm bringing up your audio level right now. You know, I'm using my little, my headset here, but I can switch to my big mic if I need to. I was trying to keep it easy so I can walk around, but no, no, you're good, you're good. All right, sweet. But yeah, so I work out of my home office in Boise, Idaho, and I work for a company called Infragistics. We're a control UI vendor and we create all kinds of kick-ass controls for just about every platform you could imagine. So if you're looking for some UI controls, of course I would highly recommend looking at Infragistics. But yeah, but today I'm looking at showing off some prism stuff. Okay, terrific. Now, what is prism? We touched on it briefly when we did the rundown at the top here. What would you say prism is? Yeah, actually, prism's kind of morphed as definition. Historically, prism's never been really an MVVM framework. It's always had this reputation for being this real big, heavy MVVM framework. Well, technically, prism for WPF doesn't really care if you use MVVM or not. I will always recommend you use it, and every code sample I show will use it, but you don't have to use it. But I mean, you know what, we'll say, just we're not gonna play the semantic game. We'll say, sure, it's an MVVM framework, but essentially it's an architectural framework that provides guidance on how to build modular, loosely coupled applications. Basically, it shows you how to use patterns that you should really be using anyways and really helps you enforce those patterns more consistently. Okay, so we fall into that pit of success. We get a better maintainable application. Exactly, it's all about guiding you down a path to success. It doesn't mean you can't write some really, you know, not so great code, but it's a lot harder to do in a prism map because it really sets you up for success. Cool. Do you wanna share your screen so we can take a look at some code? Yeah, sure. I think it should be this one. Let me know if you see that. Yeah, there we go. All right, let's go over to your screen. There we go. Should be Visual Studio, right? Oh yeah, we can see it up there. And actually it's cut off a little bit. I'll fix the trim there, but go ahead. All right, so yeah, so I just saw a comment. Just now, it's overkill for smaller projects but great for large ones. That's another myth. That's a huge myth. Okay. Prism is great for any size project and as we start kind of playing around in here, you'll see that you can use it for anything. It just makes development easier. It'll get to a point where you won't be able to tell the difference between what's prism and what's WPF. It's gonna be so natural to me. Okay, and when you say that, that makes me think the line that's blurred between ASPNet and MVC. Exactly, you've got this very popular pattern but it's kind of baked into ASP.net now. So you really like, where's that line of separation? Okay, cool. So what do you wanna show us today about prism? Well, we're gonna start from File New and we're just gonna kind of make it organic. We'll just talk and we'll just write some code. I don't have anything planned. So I just figured we'd have more fun with it. This is Twitch. We're doing live coding friends, look out. Stand back. So I do wanna note, I am using the preview. We will be using .NET Core 3. So, as with any preview, don't be surprised if we get some type of bug or something that pops up but I am using the latest and greatest. And I will also mention if we are using ASP, ASP, you got me on ASP. .NET Core 3, you have to use Visual Studio 2019 preview or RC. So you can't use this in 2017 for this demo. Okay. Okay, so first I wanna start off, the biggest questions I get about .NET Core 3 in general, not even prism is, man, what's the big benefit about it? Well, one thing I like the most about it, I'm gonna go ahead and open up a .NET Framework application here and I'm just gonna unload this .NET Framework project and I'm gonna show you the project file and this is just for file new, right? That's crazy. Oh my gosh, yeah, right? As somebody who has to maintain source code and you're looking at that, there's a lot of chances for stupid collisions when I'm trying to merge and manage things and I'm accidentally overwriting something. Oh yeah, adding projects and references and oh my God, it's a nightmare. However, I'm just gonna close this because I don't wanna look at that mess again. I actually threw up in my mouth a little bit. Oh, let's go ahead and create a new .NET Core 3 prism app and I'll show you the difference. So I'm in Visual Studio 2019 preview and before we create anything, I wanna show you, I want you to go to your extensions and I want you to go install the prism template pack. This is gonna get you set up to create new projects, new items, this is gonna have project templates, item templates, code snippets, just to help you be a little more productive in creating any type of prism application. Okay, so let's go ahead and create a new .NET Core 3 prism app by saying new project. We're gonna get the new dialogue experience which I personally am not a fan of but since I know what I'm looking for, I'm just gonna search for prism and I'm gonna see this prism blank app .NET Core 3. Okay, so I'm just gonna hit next. Sheryl, I don't care what it's called and we're gonna create this. Now the first thing we're gonna see is that we are prompted with a wizard called select your container. Oh man, what the heck is this Brian? What's a container? So one of the patterns that prism enforces is basically inversion of control, okay? So inversion of control basically says, hey, this class here has some dependencies and I'm not gonna create them themselves, right? I'm not gonna create it. I'm gonna let something else create it and give those dependencies to me. That's all it says. There's many ways to create those dependencies and in this case, I'm gonna use what's called a container, a dependency injection container. Oh, I know about this from ASP.NET. We've seen it over there. If we're web developers. Exactly. And so out of the box we have Unity, dry IOC and actually AutoFax is gonna go away because it's now a immutable container and that's not supported anymore. But I'm just gonna pick dry OC. I used to use Unity but Unity has some breaking changes that I haven't fixed yet. So I'm gonna use dry IOC. And it really doesn't matter what container you use. As you'll see, there's some abstractions around containers where you really won't know what you're using. Okay, so here is a blank prism application file new. Now let's just start. I wanna show this comparison on the project file. So we're just gonna hit edit. All right, hang on. Let me hide my, wait a sec. I didn't have to hide my screen. My camera there. You don't have to hide anything. That's it. All right, hang on. Can you zoom in a little bit there? I don't think we can actually write it. We need at least a font size 16. That's too small. That can't be all of this. That's it. That's all it takes. That's including my NuGet package reference here. Okay, so, hang on, hang on. This is, it says Windows desktop. Is that a Windows Forms application? This is a WPF application. The Windows desktop is SDK for .NET Core 3 we're using to provide all the tooling and the building for actually creating this project. Okay, so if I wasn't using the prism dry IOC package, I wouldn't even have that, those lines eight through 10. No, it would look more like, oh, the great Control-X dialogue. But yeah, it would look like that. Technically, you see this is simply named? Technically, that's not even needed. So it would really be this. Wow, okay. I'm a little more verbose in my templates. So, but that's it. That's one of my favorite parts. Like you said, with get and merge conflicts and just adding new projects and new references and like this is, it's a no-brainer. Okay, all right. All right, so because this is a preview, the first thing we're gonna wanna do is update our NuGet packages. And I'm going to use the my get feed for prism. So prism provides a my get feed for our CI builds. My get is that private location where you can manage things outside of the public NuGet repository. Yes, exactly. It's like NuGet, but it's not. It just allows us to, you know, ship more continuously without cluttering our NuGet list on the actual NuGet site. So we have our prism.dryoC, we're at .639 and I need to upgrade to 1137. So I'm gonna go ahead and update that real quick. Yeah, that's fine. Yeah, I guess we'll accept some licenses. Does anybody read those? Yeah. What, you don't? Never. Okay, so we should be good. I'm gonna build right quick just to make sure, because you never know, because what happens is when prism, when prism's nightly build kicks off, we actually grab the latest version of the .NET Core 3 preview SDK and compile against that. So you never know what's gonna break. And then I'm gonna run the app just to verify we're all working before we start typing any code. And what monitor is this gonna launch on? I've got like four monitors, I'm looking for it. Oh, there it is. I'll drag it over here. Okay, so our app runs, we can safely start coding. Now I do wanna mention, if you're curious in getting started with .NET Core 3, getting everything set up, go to my YouTube channel, youtube.com slash Brian Lagunas. If you scroll down towards the bottom, I have a ton of videos on .NET Core 3, most of them are about breaking changes. It's the very first one is hey, this is how it used to work, but things change, you know, that was done four months ago, but things change every day. And now you get to the point where, oh, it doesn't even work in Visual Studio 2019. So if you're curious about that, go ahead and check out those videos. All right, so let's go ahead. I've shared a link to those videos in the chat room for anybody who's looking for it. Perfect. Okay, so let's go ahead and see kind of what the difference is out of the box WPF in a Prism app. First, we'll start by looking at the app class itself. Now, we'll take a quick look at the XAML. The XAML will derive from a Prism application instead of WPF application. Okay, and you'll also notice there's no startup URI here. We don't do that in Prism, okay? So when we hop into our code behind, we'll have two methods here. These are abstract methods. So if you're doing this manually, you're gonna be forced to actually implement these. One is create shell and the other is register types. First, let's talk about create shell. Create shell is where you're going to resolve an instance of your, we call this shell, but it's like the host of your application, right? It's like a master page, if you will. It's basically gonna contain the area of the app where you're gonna start just throwing stuff in, okay? In this case, we have a class called main window and you'll see that I'm not returning, I'm not saying like return new main window, right? I'm not doing that. I'm saying return container.resolve main window. Now, the reason I'm doing that is because I want to use our dependency injection container to resolve our objects. Everything we create, I wanna use the container because if we have to add any type of dependency to this class, we'll get injected automatically and we'll see how that works. It's actually pretty freaking cool. Okay, the next method is called register types. Because we're using a container, we have to register various objects, classes or views or whatever with the container so it knows how to resolve them or create them for you. We'll see how this works later, we'll come back to this. Okay, next, we have a main window and a main window view model. Now, let's talk a little bit about MVVM because Prism does MVVM differently than you would expect or that you've probably seen in any other framework. And in honor of Pi Day, because I've been watching my Twitter feed and everyone's doing this Pi stuff, I have to provide a Pi, okay? So, my Pi is showing off, does that use MVVM, the percentage of people who complicate it versus the percentage of people who keep it simple? Yeah. And you can guess who keeps it simple, right? Prism users, they keep it simple, right? Everyone else just complicate it. That's a joke. Don't take that seriously, please. Thank you, thank you. Yeah, yeah, very good. Okay, so our main window, I'm actually gonna, I don't wanna talk about regions just yet, we'll get to that. Our main window is acting as our host, right? So in our at.zaml.cs, we said, yeah, this is gonna act as our shell, perfect. So we know that the main window is our host that's gonna host our application. It also has a view model, but if you look at our XAML, you'll see no instance of a data context. And if you jump into the code behind of the main window, there's no data context. Yeah. So how in the heck is that getting set? Well, if you look right here on this line, line five, we are using an attached property called view model locator. And we say view model locator, auto wire view model equals true. Now what this does is it uses a naming convention. And this convention says, take the name of your view that has to be in a views namespace and then look in a view model's namespace for a class with the view name plus view model. Once you find that, create an instance of it and boom, you're done. And so it will go and resolve that, automatically set the binding context and you're ready to go. That simple. Now this is different than most of view model locators you are probably expecting. Like I'm just gonna jump into the code behind here. A lot of times what you see is you'll have some type of like static class, right? View model locator. And in here, you'll have a property. What's the, I think it's just prop, is it? Yeah, it's prop. You'll have a prop. Oh yeah, the snooker. The VM, you know, and it's my VM. And then maybe it returns, you know, an instance of your VM. Then you go into your main XAML and then you set the context to an instance of that static member. And that's just, not only is that a ton of work, not only are you breaking so many development rules out there, the open close principles, one that comes to mind. But that's just a ton of work and I'm pretty lazy. If you see my shirt here, it says code like a boss. It's because I'm lazy. I like to keep things simple. Can you do me a favor? Can you push up the font size there to about 16? Yeah, you want me to just zoom in or do you want me to? Nah, we're gonna need to get it in the other windows also. All right, let's go options, fonts, and we'll go 16. How's that? Yeah, there we go. It's a little bit harder to see when you're on Twitch. Oh, okay. All right, so now that we know how the view model's being set, and I think I mentioned that we do use the container to resolve this view model and that's gonna be important later on. Let's talk about a little bit about commanding. How about commanding? Cause that's another popular thing we do in view models, right? So I'm gonna have to add some stuff here. Let's do a grid. I think we need some row definitions. And then let's throw a button in the first one. And how about a, I don't know, a checkbox? So let's start with commanding. I'm gonna go into my view model here. And a lot of times you have, everyone knows I'm assuming a command, right? An I command. We just saw an example of that in the last session that you had with Dimitri. Well, a person provides what's called a delegate command. So I'm just gonna type cmd. Actually, I don't wanna do that. I don't wanna confuse everyone. We'll say delegate command, my command, and we'll just provide a simple getter setter. And I'm gonna include my namespace here. And it will say my command equals new delegate command. And I don't know, we'll say execute. Look at you. Yeah, that seems pretty simple, pretty straightforward. Okay, and then so I call that my command. So let's bind this button to my command. Now I guess we'll give it some content. Click me. All right, that looks good. We're gonna probably wanna put this checkbox in the grid.row2, right? Our one. So I'm gonna hit a break point there. Let's just make sure I got everything hooked up right. Man, my machine is really struggling to keep up. I got too much stuff running. Where's this? Oh, here it is. Okay, so we have this click me. If I click this button, I'm hoping that I hit my break point, my output window. Did it go hide somewhere else? Control Alt O, right? Let's see. Control Alt, Control Alt O. Oh, now it's behind me. All right, I'll go away. Fine, fine, I see how this is. There it is. Well, let's see. Ah, my command. Did I misspell something? Oh my gosh, I'm retarded. Why didn't you tell me I didn't make that public? I didn't. Come on, guys. Oh, there, yeah. Come on, guys. Geez. I thought that's what switches for. Oh no, look at that. Niketsu in chat is calling that out, public. Yeah. Oh, thank you. I need my real-time debuggers. All right, there we go. We hit the break point, beautiful. So it works. Now, one of the things about commands is managing state, right? So I have this checkbox. One of the popular things for commands is having what's called a can execute. Can execute. Oh my gosh, can you spell today? Right, you're talking about some sort of a check that says, can you actually press this button? Can you actually do this thing? Exactly. And normally we have a property to control that. So I'm gonna use this prism snippet. Is enabled. Is enabled. And we're gonna return is enabled here. And this is gonna tell us if we're allowed to enable this command or not, right? So Vigil Studio 2019 is really slow for debugging for some reason. It's taking forever to pull these windows up. Okay, so we're returning false. The default value of a bool is false. So it's false, we can't click the button. So what I wanna do is I wanna be able to control that is enabled state by binding it to that property. Binding is enabled. So the idea is when I check this button I want to enable the command, right? I mean, our state has changed and I want my command to be able to be invoked. So when we check this check box, oh my gosh, this is really slow. Live video does that. Yeah, when we check this check box, this button should enable, but it's not what's going on. I mean, I don't get it, we're changing the value. Well, the problem is we have to notify this command to re-query the state of the can execute. And it doesn't matter if you're using delet command or not. This is just commanding in general, okay? So what we have to do is we need to find a way to raise the can execute of this method. Now there's a couple of ways to do this. One way to do this is let's just go into the setter of the isEnabled property and we're gonna say my command.raiseCanExecuteChanged. Okay, let's try that. Let's see if that works. Basically we're manually forcing the raising of this command to recheck the state or the value of the can execute method. So hopefully I click this and there we go. So as I toggle this button, we can see the state of that command or that button change. Well, that's pretty cool, but you know what? I'm pretty lazy and I really hate having dirty setters. I mean, if I can avoid putting code in a setter, I avoid it because I don't like it. I like my setters nice and clean. So what's unique to delegate command is we have an option here called .observes. Oh, I'm on another line. Oh, there it is. Observe property. What I'm telling this command is we want to observe the isEnabled property for state changes. And that the value of this property changes, we're going to automatically raise the can execute changed and check the result of the can execute for you. You don't have to do anything, it just does it. So we are observing state changes in that property. So this is one of those things Prism does for us to allow and enable that enabling and disabling and binding of the command. Exactly. So now I'm clicking the button, it's the same functionality. It's the same thing, but it's just a little cleaner because we don't have all this crazy setter code. Now, you guys might be asking, I don't see a question yet. There is a question about I property notify. Okay, where is it? I don't see it. Isn't there, Stelzi79 asks, isn't there an I property notify? There is an I notify property changed and you see this bindable base. This was, this is a class provided by Prism that implements that interface. So if I hit F12, we'll see that it does in fact implement I notify property change. And when I call this method set property that exists on bindable base, it is calling I notify property change for you behind the scenes. So you're not gonna have that on property change called like this manually. That's not gonna happen. It's done for you. Fantastic. I need all of that stuff, all of that goo that yak shaving behind the scenes. Let me focus on writing my code instead of wiring up plumbing. Exactly. Now, another interesting thing about this is you can observe more than one property. You can just keep tacking these bad boys on to your heart's content. Obviously, if you have like 12 properties you're reserving you might have some code smell there and might wanna reevaluate that but you can observe multiple properties. Another thing you can too, you can do is let's say you have like a person class. You can say, yeah, person.address.zip, right? So you can actually observe nested properties if you need to. Okay, well, something else that's pretty cool about the prism delegate command is, we're looking at this and we're saying, you know what, all our can execute is doing is just returning a boolean. That's all it's doing. I'm not doing any complex logic. It's pretty simple. It'd be great if I could just remove that somehow. Well, you can. Instead of observing the property, we're gonna hit our IntelliSense. We have an observes can execute. And what observes can execute does is it will use this property. Not only will it observe it for state changes but it will use the result or the return value of that property as the can execute method as that delegate. So I can actually remove an entire method and just say observes can execute. So if I go ahead and run the application and go make some coffee while I wait for my app to run. That wasn't coffee, that was water, come on now. I don't drink coffee, I gotta have water. All right. So, and it works the exact same. To the end user, there's no difference but to the code, there's a huge difference. It's a lot cleaner, okay? So, commanding is a lot different than a lot of the other frameworks that are available out there and it's all about just making you a little more productive and your code a little cleaner. Things just easier to do. The next thing I wanna talk about is about navigation. Cause navigation in Prism is pretty freaking badass if I don't say so myself. Remember I had this region in here? I removed it. So let's go ahead, I'm gonna leave that button there and I'm gonna add a content control and I'm probably gonna wanna wrap this in a stack panel cause I already know, probably gonna add more than one and we'll set the orientation to horizontal here and I'll need to make sure that this, no, hey, what happened to that great intelligence I'm supposed to have? It's there, it's there. Okay, so in Prism, we have this concept of regions and all the region is, it's a placeholder for you're gonna stick some content. That's all it is, okay? Back in the ASP.net days, you had your master page, you had that little template page and it's just like that. You're basically gonna say, hey, this element right here, this is a placeholder and I'm gonna stick stuff in here and the only thing I need to do to specify an element as a region is I'm gonna use the prism, region manager, region name, let me scroll over so everyone can see here and I'm gonna call this content region. Cool, now we can start doing some navigation. All right. Okay, how much time do I got? Okay, I'm gonna- Oh, plenty of time. 20 minutes, we're good. I'm gonna introduce a new concept right quick at the same time. I'm gonna implement a module. So one of the things about prism is we talk about loosely coupled apps. You know, we want our clean separation of concerns and this includes modularity where we have major functional areas of our app separated into smaller chunks where it's easier to maintain, it's easier to extend, we're not stepping on other people's toes. Oh, sure. This is the promise of namespacing things. You put stuff so that it's isolated and it doesn't have, it has the same name but it doesn't step on toes, yeah. Yep, so I'm gonna go ahead and I'm gonna add a prism module. Prism module.net core three. And we'll call it module, I don't know, A. My go-to, module A is my go-to module name. Naming is hard. And then I'm gonna right click because I need to update our packages here. Now I wanna make sure I'm going against our CI builds. Let's update this very quick. And notice that this module here, if we look at what's installed, we don't have prism, we don't have a container installed in this module. Keep that in mind. We are not referencing any container in the module. So just remember that. Sure. Okay, so we have a view called view A and it's very simple. Looks like we have a view model that we're bound to, it has a message property and we're saying view A from your prism module. Great. Now the first thing we have to do is let our main application know about our module. So we're gonna go into our app class and we're gonna override, configure module catalog. Configure module catalog. Okay. So you're inside your app and you're saying there's modules here that you need to be aware of. Yes. Got it. Add module and we'll say what I call that module. Module A. A module. And then we're gonna add a reference and there we go. Okay, so there's a couple of different module catalogs in prism. I'm doing it in code right now but you can do it via an app config file. You can do it via XAML resource file. You can even scan directories on disk if you wanted to but we're keeping it simple and we're just gonna just hard-code it in there. It's fine. Okay. Okay, so now what we wanna do is let's go, I'm gonna close that. I only want that available. Let's come into our module class and see what makes up a module. A module is just a class that implements iModule which has two methods, initialize and register types. So register types is where you're going to register any of your views or classes with your container. So in this case, I'm gonna say container registry.register for navigation, view A. Okay. So because I want this view to participate in navigation, I'm gonna say, you know what? I have to specifically register this view for navigation. So my container or the prism app knows about this view and knows that it's gonna participate in navigation. Gotcha. All right, all right. Now let's go ahead and go back to our view model because there's two types of navigation inside of prism. You have view discovery, right? So view discovery basically says that I'm going to go ahead and let the region discover the view when it's ready. Whenever this region is initialized, it's gonna automatically just show it and I don't control it. I have no control over it, okay? And then you have view injection. View injection saying I'm going to manually do this. Mm, okay. So you're literally taking the contents out of this library, this module, separate projects, separate assembly and you're gonna spot weld it into your application so it's available where you need it. Exactly. So what happens here is when you registered this for navigation, you are assigning a key to the navigation system because prism doesn't navigate based on view models or views, that whole view first, view model first, it's really not a thing, okay? It doesn't matter and prism, it's a key. And in this case, the key is view A. However, I can just say my cool view and now that's the key. Make sense? Oh, yeah, okay, so I'm not a fan of having I'm not a fan of having these magic strings like that floating around. Yeah, well in that case, you can use constants, right? I mean, there's lots of ways to get rid of magic strings. You can do resources. I could do a name of. Well, you could, but I personally don't do that and the reason I don't do that because that is creating a coupling. Even if you're doing view model first, right? So if I'm inside main window view model and let's assume that I'm not referencing, you know what, let's just go ahead and implement this. Let's go ahead and I'm gonna ask for the I region manager because that's what we need to navigate. So I need to using prism.regions and I wanna create a initialize a field back here. Now remember when I said I use a container for all my stuff, this is why. Yeah. All I did was ask for this region manager. You didn't see me knew it up. You didn't see me have to go and do anything special. I just asked for it. And it's just available for you. Nice. It's just gonna give it to me. So when I execute, I'm gonna say regionmanager.requestNavigate the region name, I think we called it content region. See, this is where your constants come in handy but I'm live coding. Yep, I call the content region, right? So where I want it to go and then the key of the view, which is viewA in this case. Pretty straightforward. Let me see if I can shrink this just to fit a little more code in here. All right, makes sense. So in the module, we registered this view for navigation but in the main window or the main window in the main application, we're gonna navigate to that view, keeping in mind that it's possible that we don't even have a direct reference. Like if we're using an app config or an app config or if we're loading this from a directory, this project has no hard knowledge that that even exists but I can still navigate and communicate with it. So let's go ahead and see this my command click me. Okay, let's go ahead and run the application. Oh, come on, these build times are killing me. No, no, we're good. We're all right, we're all right. This is when it gives you time to think, to contemplate, did you build things properly? Is the code written properly? Why did I forget to write those unit tests? There it is. Oh, yeah, and. That region is taking up a little bit more space. Yeah, well, and I also forgot we have this little enabled or checking returned false and let's check this here. Yeah, that's right. Okay, so our button should be good now because remember we had that checkbox there where we were controlling it and I removed the checkbox so it defaulted back to false. Maybe I should do that hot reload. Hot reload, love the hot reload. Yeah, so theoretically if we did everything right, I can just click this button and then we'll see there's the view that got injected into that region. I mean, that's pretty freaking cool. Right, so you're bringing content outside of, you took a direct reference here because you hard coded it, but I like what you were saying about, you could move that reference into an app config and as long as that DLL, that output, content, that output assembly is somewhere where you can recognize it. You can swap that in and load it on the fly. Exactly, think of how MEPH, the extensibility model kind of works where you can just kind of drop an assembly into a folder and then functionality just appears in your app. Yeah, just like that. Here you go, you can do something similar with user interface. Exactly, and not just user interface, complete sections, complete functional areas of your app. So you can release, like, look at Outlook for example. Outlook has the mail, the calendar, the contacts, those, think of those as modules and at any time I can release a new module and it just magically appears to your user. Maybe they paid a premium price and they get to have a calendar and boom, you load a calendar for them when no one else gets it. Sure, sure, a resource scheduling module. Oh, okay, well, you know, to add only the folks that have a paid subscription and it loads that module on demand because they have it. Oh yeah, I get it, okay. Okay, now let's talk about view model participation. Or not view model, but navigation participation for your view model. So navigation is one thing, but an important aspect of navigation is being able to know when you're navigating and getting parameters and information from that navigation process. So in WPF, Prism provides an iNavigationAware interface. iNavigationAware, I'm gonna add my using statement and I'm gonna implement the interface. Now, this comes with three methods. It comes with an onNavigatedTo, an isNavigationTarget and an onNavigatedFrom. Here, we're gonna just return true. So these two onNavigatedFrom and two are pretty self-explanatory, right? When you say onNavigatedFrom, we're navigating away from this view or this view model. When you're navigating to, of course you're navigating to the view of ring model. Now, this isNavigationTarget is actually pretty cool. And if I had time, I could show you how this works with tabs, but essentially, isNavigationTarget controls the instance of this view. So for example, let's say you're doing customer details and you say, hey, if the cust ID equals two, you know, then return true, otherwise return a new instance of this view because we're dealing with a different customer. Does that make sense? Yeah, it does. Go ahead, I'll let you go. Okay, so let's go back to our main window here. And what I wanna do is I wanna pass some parameters. So I'm gonna create some parameters and I'm gonna create some navigation parameters. And there are a couple of ways we can do this. First, we're gonna do it all in code here. It looks like I need it. New, did I misspell that? Navigation parameter, are you? Oh, I didn't do new. Right. There we go. Okay, so we can do an object based. So we'll say, you know, p.add, we'll give it a key, like ID, and then an object of value. In this case, it'd be a stream because I'm gonna put it in quotes and I'll just say, you know, hello. And then I can pass those parameters along with my navigation call. So when I come into my view model, when I navigate to this, I can say, you know, var p equals navigation context.parameters.getValue and I'm gonna cast it to a string. And what was, I think I called it ID. Okay, so now I'm gonna get that parameter I passed and let's set our message to that value. That looks good. Okay, so let's go ahead and run this real quick. We go back, close that and run the application. And now we contemplate life again. Here we go. Yes. Why, you know, when you use multiple monitors, one thing that really bothers me is if I'm using multiple monitors, why don't we just open up the app on the same monitor my VS is running? I don't know. Okay, so I'm gonna hit the click me, the page loads, but now we see that our hello message that we pass as a parameter to that view model. And no longer it says the original message, it's what we pass to it. Okay. Now, one thing I wanna mention is, you know, we're talking about strings, like I don't like these magic strings. Why do you use a string? Well, technically navigation as prism is URI based. It uses a URI, like an HTTP URI. And that gives us a lot of flexibility with how we handle parameters. For example, instead of saying hello in here, I could go ID, I need my little ID equals hello. Well, that's pretty cool. Well, what's even cooler is I can come to my view, question mark ID equals hello, and not even pass in that P or it gets even better. We can pass in different parameters differently. They're all combined into one. So if I come into here, we'll hit a break point around the application, and we're gonna see all of those parameters that were created in different approaches, all consolidated into one parameters object, and you'll see all three options in there, even though they were created differently. And it's interesting to me as a web developer, because I'm seeing query string pairs coming through here, very easy for me to pick up and pull that apart. Exactly. And then there's three, and here's our parameters, ID, name, and our car. And then you can handle those parameters. Now, what's really cool about this is let's go to our view, because sometimes you need a little code behind. Like it's okay, but you still need access to those parameters. Well, you can do that. You can have your view and your view model. Come on, here we go. Implement these interfaces, and it will be called on both the view and the view model of your target navigation. So I'm gonna hit unnavigated to, we'll run this again, just to prove that we are hitting the view and the view model. All right, I get it. Loading, loading. You know what, you need a compiling song to play. Yeah. You're gonna add that to your repertoire. So here we are, we're in the view code behind, and we hit the unnavigated to, and then of course we hit the view model because we have our logic that just ran. Now, another common scenario, how much time do I got? Oh, I got a few minutes. Another common scenario is preventing navigation, right? We wanna prevent navigation. Well, let me just move up. We have a way to do that too, as long as I stop my debugging session. I confirm navigation request. Oh, okay, okay. So this basically says, oh, and just so you know, the reason you get these methods is because if we look at it, and I don't like the way this was first written, because this was way before I took over, it actually implements iNavigationAware. I personally don't think that should have been the case, but it is what it is. So that means I gotta come through here and delete all these so we don't get any. Exceptions. So I confirm navigation request will tell us if we're allowed to navigate in the first place. And the way we do that is by calling this continuation callback, right? So we'll get the parameters. We can handle any parameters, show any dialogues, and then we'll have this callback, and we'll say false. Just, I'm just gonna hard code it to false. There's no fancy logic here. It's just like you did with the command where you said, can execute. You're doing the same thing here. Can I navigate into this thing? Exactly, and this invokes before the navigation process even begins. See, this is where we need that little sound bite of it. We need that music. Maybe it's like the Jeopardy theme. I do have the Jeopardy theme, but copyright. But so yeah, when you're navigating away, and in this case, it won't work because I'm actually navigating from the main view model. But essentially, all we're saying is, hey, we want to cancel navigation. If we want to allow it, we say true, and then it will continue on. I got like two minutes. Yep, we are right up against. Okay, well, it'd be something cool. Is there anything, I haven't been monitoring the comments here. Is there anything someone wants to see that I could show real quick? Prisma is great, says one, one F Blanco. Prisma is great, I wish modules, dynamic loading regions could be portable to UWP, Xamarin forms, et cetera. Yeah, unfortunately, UWP doesn't allow the dynamic loading of assemblies, though I think that might be changing. If Jerry Nixon's still online, he could probably comment on that. I thought I heard a rumor that that was gonna be supported, but I'm not 100% sure. So do not quote me on that. Jerry would go to answer that question. Sinclair Nader's asking about passing complex objects between view models and views. Well, yeah, let's say, where's my parameter here? So let's say your ID was a person and you passed your person object, no problem. You need to create the person object, but... Yeah, you would have to create it, of course. This is assuming you have a person object to pass around. But yeah, you could totally do that. You see, you know what? I'm gonna show one thing. Let me open up a project that's already built and it's a project everyone can play with. If you go to the Prism website, where is my... And while you're looking for that, there's a question from the chat room asking if the code that you've gone through here today will be downloadable if you have a GitHub repository you can share it from. Yes, I do, and what I'm trying to do is tear off this freaking tab. Here we go. So I can show you where to find all these samples. So if you go to the Prism repo on GitHub, github.com.prismlibrary, and scroll down till you see prism-stampals-wpf, and you'll see there's 30-something samples in here that cover just about every single feature that Prism has. And it really simplifies all the concepts and very modular, very focused samples and they all build in each other. For example, composite commands are pretty freaking cool. You know what, let's show a composite command in the last few minutes I have. I'm gonna go to the GitHub samples because composite commands are unique to Prism. I haven't seen anyone else do these before. I sure will say that. So a composite command is essentially a parent command that invokes child delegate commands, okay? So essentially you register any number of delegate commands or I command implementations doesn't have to be a delegate command, but you register any number of commands with a composite command and it will invoke all of those commands at once. So think save all, right? So in this sample, we have a tab control with multiple tabs and I can save each one of these individually right? And these can execute control one each individually but I have a composite command where if I click this it saves all of them simultaneously because they've all registered to this composite command. Now things to keep in mind when using composite commands is that the logic flows of, okay, I have all these child commands registered. So if just one of the can't executes of those child commands returns false then it's false for the composite command. So you can see tab A we're returning false but composite command is disabled, okay? So they all like I can't click that composite command because it's just one of them returns false. But if all of them return true being they're all dirty for example so save only the dirty ones then you can invoke the command. You could also have what's called an active command. So commands are pretty cool because they're extremely flexible and Prism you could have your delegate commands can actually be monitored for activeness. Like is this active? So when I select this tab B, this tab is active I can set this command as active. And what that does is that allows me to save just the selected tab from this global composite command because I tell it, hey I only want you to worry about the active commands and only the commands you marked as active those will be invoked. So it's really, really cool and really flexible. I wish I had more time because as you can see that I closed it, I did close it. Let me just open this up. We actually have a documentation as well that we're working on. Let's go to prismlibrary.com and just click on the documentation here. We do have some docs. We're trying to add videos to all the topics just to kind of make it easier. So if you scroll down through commanding, you can see delegate command. There's a video that explains it with code and just kind of explaining how things work. Composite commands are the same thing. Explaining how they work. We have a accompanying video and we're trying to do that for every topic and just very time consuming. Sure, but you've already got a good bit of documentation here. Yeah, so we have commanding composite commands in the model locator. All these things are documented fairly well. There we go, yeah. And then for WPF, we are rewriting the documentation. So under the legacy is where you'll find all the docs for WPF, but we're rewriting the docs to make it a little easier to follow because honestly, when you look at stuff like this, it's just a big wall of text and it could be very confusing to really understand what's going on. A little daunting to navigate. So this is great. Thanks so much for sharing all the stuff about Prism. So prismlibrarygithub.io and you also went to prismlibrary.com to get there, right? Yeah, so prismlibrary.com, it just redirects to prismlibrary.github.io. So either way, we'll get you there and then it has a link to get you to GitHub. So if you click on that, it'll take you to the source code because it is open source and you can download it and fork it and do whatever you want. Yeah, find those samples because the samples are actually in the main org. So when you get to the source code, just click back a level to the main org and then you'll see the samples for WPF there. Terrific. And yeah, there's tons of them for every single concept that prism has. All right, well, thanks so much for sharing. I learned a lot about prism here with you, Brian. Thank you very much for joining us today as part of the workshop. That was fun. Cool, all right. And we had a lot of great questions there from chat and they're asking for, if you could share that little application you mocked up with us here today, if you could share that out to your GitHub or somewhere, we'll attach it to this video later so that folks can find it. But I think the samples are a little bit better here. Yeah, the samples are much better. They're more cohesive. What I was doing was just very random off the top of my head. Everything I showed is here, like regions, custom regions, right? Create your own region for maybe you're using some inferences controls and you want to use its docking manager as a region. So when you inject a view it actually injects a whole docking pane like that type of stuff. That shows you how to do that. Very cool, very cool. All right, thanks so much, Brian. We'll catch you later. Thank you so much for joining us. Yeah, thanks for having, I appreciate it. Alrighty, and we're going to, let's see if I can do this right this time. There we go. And we're out. All right, that was great. I learned a lot about Prism there. I like how we have tools, how we have features. We have capabilities that we can bring in from these libraries and extend and make our projects a whole lot easier to manage, right? And that's really kind of the key here. It's one thing to build a one-off quick application. You just need to write some code real quick. But when you need to manage a project for a long period of time, that's when it becomes important to invest your time in a framework so that you can have good testing. You can have good ways that you can extend. And I think Brian really showed us that nicely. All right, we're going to get, we're going to get our friends from the Channel 9 studios back up and running here. Oh, let's see. We can get them dialed in. All right, here we go. All right, let me give them a call. Let's get them added into the mix here. There's the Skype music. All right, hey, next up, look at that. It is Jeffrey Huntley joining us. Give me one second here just to get that connection turned over. Hello, Jeff. How's it going? Doing well. Oh my gosh, it's so great to, gosh, we've swapped messages on Twitter for a long, long time here. And it's great to finally have a chance for us to talk in person, face-to-face kind of over Twitch. But gosh, why don't you introduce yourself and let folks know who you are real quick. Sure. Oh, and I asked that right as you're drinking coffee. My apologies. Hi, everyone. My name is Jeffrey Huntley. I'm a Microsoft MVP and an open source maintainer of quite a lot of projects in the .NET ecosystem. And here today to talk about reactive extensions and looking at programming in a reactive manner with desktop applications. It's so good to see you, Jeff. Like if you're here next week for the MVP Summit, I'm in town for it, we'll go for beers. It'll be really good. Absolutely, we'll definitely have to do that. Using late night FM radio voice. Who are you referring to there, Jerry Nixon in chat? So reactive extensions, let's talk about that a little bit. So we saw MVVM with Prism. What's reactive extensions? Yeah, sure. So the reactive extensions were made here at Microsoft. Around about 2009, 2010, I forget the exact timing. So MVVM is a way of basically separating your business logic away from UI layer. It's a design pattern. It's model, view, view model. Now, reactive extensions has nothing to do with MVVM. But what we'll be talking today is how to use the reactive extensions with the MVVM design pattern. Okay. And so the question was like, what is the reactive extensions? So, yeah, so reactive extensions is a way of programming in a declarative manner. When you look at the way that we typically program with objects or collections, well, typically we either have an object. Sure. We have a collection. And both those two things are synchronous. And then we start moving into the world of tasks. And that's a single value over time. And then we start moving into the top right, which is the observable collection. Oh, sorry, no, observable collection, apologies. That's how observable. Okay. Do not get observable collection and observable confused. I'm so sorry. And that is multiple values over time. So reactive extensions is a way of handling events over time in a declarative manner. I'll be showing a whole bunch of examples of what this means and how this can be used to actually simplify your view models. Okay. So let's do this. Let's join your machine so that we can share your screen. Why don't we join your machine into the Skype call? Let me... That's great. Yeah, yeah. Let's do that with... Oh, good. I need to add another person. Actually, on your machine, you just added me on Skype. Go ahead and call me on Skype from your laptop there in front of you. Right, I'm assuming that's what you're doing. Hey, look, there you are. Excellent. All right, and you're gonna wanna mute that microphone on your laptop. Okay, I'm muted. Fantastic. And then you can share your screen from over there. There we go. All right. Beautiful, and just a quick check. Right now you should be able to see Slack. And if I change across, we see a virtual machine. Yep, there we go. Everybody can see that now. All right, we're good. Beautiful. All right, so... And some of the folks in the chat room were complimenting the stickers on your laptop. You got some mad stickers there they're saying. Thank you very much. This time I went for music rather than software. Oh, okay. It actually opens a different type of conversation with people, it's actually really cool. Interesting, all right. You ever thought about it? Go music stickers, not software developer stickers. Right, okay. So we're in PowerPoint. That's not code. We are quickly in PowerPoint. Code is coming. All right. This is not a bait and switch, it is coming. Oh, good. Good. I'm just gonna quickly restart PowerPoint. All right, so thank you everyone for joining us. We're here today to talk about Reactive UI. Once I get PowerPoint working again, because there's a couple of things I'll be showing you in PowerPoint. It's reactive programming requires you to think a little bit differently. It's a different type of paradigm. So I'll be showing some examples and teaching people how to think that way. And more importantly, where to go to learn more information about Reactive UI and Reactive Programming on .NET. The first thing you go check out is ReactiveUI.NET. That's its website right here. I'm gonna share that in the chat room for the folks that are joining us. Thank you very much. No problem, there you go. And right up at the top right hand corner up here, this is probably the main thing I recommend to people. Please tap that discuss link. You come join us in Slack. You won't be able to get a full grasp of Reactive Programming in the short amount of time that we have. And we find it's really important to have mentors. And this is why we have our Slack channel over here. So you've got a place for beginners to ask questions and get mentoring so that they find success immediately. Exactly, right? This became our feedback loop. So the last couple of years, we've rebuilt our community. We have a channel just for maintainers and people are looking to get involved with open source software in .NET. We've got plenty of things and we're always looking for people to help out. And we also have a main channel for Reactive UI for the general users. So in this Slack channel, it's really interesting and the one reason people should also join is it's also the hangout ground for all, pretty much all Reactive Programming across ecosystems. Okay, not just .NET. Not just .NET. So we've got the maintainers from RxJS sitting out here. Like it's a tight click Reactive Programming is something that once you learn the concepts, it's a paradigm. And so once you learn that, you just apply it a little bit differently. Like you start looking at the operators for each one of the programming languages. It's just a little bit different, but it's the same concept. So if you know what you're looking to do, you can actually just express that in that programming language. Okay, okay. So let's quickly kick this off and I'll minimize the amount of time and PowerPoint and go straight to... Straight to the code. Straight to the code. Yes. So spoilers. Up the top right hand corner over here where you got this.Wanney value. This is an example of what programming with the Reactive Extensions or using Reactive UI. And this is typically how you express your code. And there's a couple of things going on here. What we're essentially doing, and we've got this application and I'll switch across over to this application and it's gonna search NuGet. It's gonna search NuGet for some packages. And... Okay. There's... If you think about like what you normally do when doing software development, like it's not just like executing command. There's business logic of when a command can execute and there's business logic to happen to make sure that no duplicate requests are in flight at the same time. Sure. And when you start going down this path with Reactive Programming and using Reactive Extensions, a lot of these really complicated concepts are a singular operator. Oh, okay. And I'm already seeing some keywords here that aren't typical to when I'm doing a database query or I'm doing an HTTP client query. I mean, throttle, observe on, invoke command, distinct until change. These sound pretty powerful right away. They really are. These high level abstractions for working over a collection. So this is basically, we're programming using link. Link over objects and Reactive Extensions when you're programming or you're basically just using link. So if you know your link operators, it's very similar and there's some extensions. That's why it's called the Reactive Extensions. There's an extensions for Reactive Programming over four sequences over events. So we look at this really quickly. What we've essentially got is this dot when any value. And what that's doing is it's listening to the search query. Okay. So that lambda, the X dot is actually a view model. So it's a string on the view model. And we're listening to the I notified property changed and that I notified property changes any time that value changes. We're starting a subscription where we're going to listen to these events. Now, you caught up before the throttle operator. Yeah. The throttle operator is really cool. It's a thing of RX. So here's an example. If you're having like a new get application, like a application to search new get loaded up here into code. And if the user is actually typing some search queries, well, normally you have order completion and you don't necessarily want to invoke a single HTTP request every time a user types a letter on the keyboard. No. No, you probably want to wait until there's a little bit of a pause. Yeah. So that's exactly what this throttle is. Ah. We've done this before, can you tell? Yeah. So we're starting a chain. We're chaining sequences over time. Everything becomes a sequence. So we're starting listening any time the search query changes. And after a period of inactivity, it'll do a network request. But if I'm typing things right here right now, well, it's not satisfying the throttle. Okay. And so thus it's not doing any network requests. And I'm being able to essentially reduce, say if I type 50 characters here, that's only going to be a network request after one second or 0.8. Does that make sense? Okay. Yeah. And we have another operator, for example, that we're trimming off any white space off there. So that's the next sequences of events. We're trimming in the white space off the search quite because you don't really want to send the white space there. Yeah. That's ridiculous. Yeah. And then there's distinct until changed, meaning that the evaluation, the sequences are kind of paused until it changes. So if I've got reactive UI, and that's search new get, and this is connected to a new get.org that's doing actual searches. This is actually, it's not gonna, it's not gonna, until like the value changes again, it's not gonna evaluate. Okay. So even if you put another space in there at the end, if you put a bunch of spaces on the end there, because you're trimming it, it doesn't see a change. It's not gonna evaluate again. Exactly, Jeff. Exactly. Okay. Okay. I'm feeling you. All right. And this is where we start getting onto the next operator, which is the where. So that where is essentially taking the value from the search query. And that's, so we're taking from line one, the X search query, and we're passing it into the where and was just saying, look, like make sure it's not null or white space. Like don't send any invalid. So we've now moved from request deduplication and network request deduplication and ensuring that we have perfect efficiency. And we're now moving up into the next, like one layer up, which is the business rules. Oh, okay. All right. So I could do, I could put a filter in there and not just make sure that something's keyed in here, string is null or white space is, you know, a knot on that. But I could also make sure that it's a valid new get package name. If you tried to search for dollar sign, I could put a check in there. It says, this is a special character. Don't even proceed. Exactly. Okay. And the cool thing is these operators you're starting to see, they're starting to chain, but any of these operators can be like extracted out into their own separate method. So if you're concerned about re-usability of some business logic like that, that can be extracted out and then you just have it as an extension method on your chain and then you can start code sharing that some of those operators. Now, are these executed as they're reached in that command? The throttle, then the select, then the distinct or are they like link, are they built into a query plan and then invoked when you finally execute invoke command at the end? Okay. So it's executed top to bottom. Okay. Top to bottom. So I've been talking about sequences. Yeah, can you zoom there a little bit? That's... I can. There we go, cool. Now, let's say what today is. This is an example of when I talk about sequences. Here is a visualization for sequences. It's written in RXJS, but the concepts for reactive program and reactive extensions, they're universal. If you learn how to do reactive extensions for .NET, you also know how to use RXJS if you're going over to Angular and doing front end development. So here's a sequence. So what we've got is we actually have a series of events and what we're doing is we're creating a sequence of what the day or the month is, what the month is, what the date is and the year and each one of those new lines going down, they're forming part of the sequence or part of the pipe. So when I'm talking about over here, where we're talking about this, you start thinking along the lines of events or distinct things that are happening until you take that and remix it. You take that and remix it into the next sequence. So you take a small sequence and then you can pose the sequence together until you get the outcome that you desire. Okay, all right. And to finish this off, we have the observe on. This is how we control which scheduler that you're going to be running on. So this is the threading. So we can decide to run on the UI thread or we can decide to run in the background thread. All right, I can buy that. Or if I've got a thread pool, I could throw it to any one of those threads as well. Yeah, it's completely like customizable in that regard. So there's this concept in reactive programming called schedulers. Schedulers allow like probably the easiest way to explain schedulers. Schedulers allow you to specify threads and also allow you to abstract time. So I'm going to explain abstract time. Yeah, abstract time sounds a little nebulous there, sounds a little out there. Yeah, so here we have a standard application that has a dependency of a clock. The clock in .NET is a static. It's not something that can be mocked and easily replaced. And with that, there's no real way to fast forward time or rewind time. So if you had like a set of traffic lights, if you had a set of traffic lights and you wanted to check that the lights changed every 10 seconds between red, green, red, green, yellow. Normally, if you think about a traffic light, that's a sequence of events. So we have a controller controlling a sequence of events. This is a domain that works very well with reactive programming. Now a scheduler is essentially an abstraction above that and it can work as like your clock. And if your sequence of events takes a scheduler or a clock, well, that clock, that schedule allows you to rewind time and fast forward time. All right, so that makes testability a little bit more interesting, right? That's exactly where I'm going, perfect pickup, Jeff. So this allows us, when we're writing tests, when we're saying things are more testable, over here on the second line, the throttle, I can actually write a test to that asserts that when the search query changes, that it's not gonna invoke a network request. I can also write a test that says after like 0.8 seconds of inactivity, it does invoke a request. I can actually test the due duplication. Now that test is not gonna take 0.8 seconds. That will happen instantly because I'm able to mock the scheduler. I'm able to fast forward and assert like scheduler.advance by a milliseconds. I can advance and rewind on a millisecond interval. So that means if you had a traffic light and you wanted to assert all of the particular, like the traffic light change intervals for 30 minutes, that wouldn't take 30 minutes to run. Like this, that would be, we were talking about like 180, 100 milliseconds. And we're able to assert all these conditions of all the time. So the time, it finally becomes unit testable. That's very cool, right? Just think that piece through. Time becoming unit testable, something dependent on time being unit testable is huge. Right, I know- Yes. Yeah, go ahead. Especially when you're developing user interface applications, right? There's so many times where you're using the concept of time and like, people don't even bother like testing it. It's a really hard thing. It's classified as an edge case. But here, it's something that we embrace and we can actually assert any requirement regarding user interface being enabled or disabled or request duplication or anything like that can be disabled or can be like tested. Yeah, that makes a lot of sense. That makes, that's, gosh. All right, the number of issues that I would have in normal application user interface development that minimizes immediately. So glad to hear it. So how about I do a quick shout out to people in the team? So Reactive UI is part of the DotNet Foundation. Very cool. We joined two years ago. It's really cool. And we have a core team. And recently we've had Rodney, Glen and Atrim and Colt really helping out. So I wanna thank them like for so much they're done. I've actually gone through some motions of succession and handing over the reins. And it's been really cool to regrow the community. We're alive, it's growing and it's awesome. It is. It's always, it's, that's definitely a testament to the health of a community when you're able to have changes in leadership, additional leadership come on and continue growing and building a project. Oh, completely. Reactive UI is financially sustainable to a point where we have revenue coming in from open collective. And we're starting to use these funds for hiring tech writers. We're starting to use these funds for paying people to redesign the website or work on GitHub issues. So it's the dynamic sustained a change. We don't have much revenue, but we have revenue and we're able to use this to attract people to the project that we were not typically able to get access to because software developers come to open source all the time but getting access to a designer or a tech writer. It's really nice to actually be able to pay them rather than saying we do it for free, you should do it for free. This is not a great place to be. So we're going past that area. Cool, all right. So folks, please come join us in reactiveUI.net slash Slack. You hang out with these super cool folks. And let's just do a quick recap. I'm assuming no knowledge of Reactive UI and what it can do. Sure, I think that's a good assumption. Yeah. Beautiful. All right, so Reactive UI is a MVVM framework, but we kind of like joke that it's not a framework because it's actually a set of extension methods that you would normally write if you were doing reactive programming to build a desktop application. Okay. And I'll get to that. So whereas Prism and MVVM Cross, it's more of all-encompassing, this is the design pattern, this is how we use, we essentially just have lots of extension methods that enable you to do reactive programming with .NET. So we target all the platforms. We've got WinForms, WPF, .NET Core. We're starting to have some experiments with Platform Uno, WebAssembly, Xamarin, iOS, Android, and Winnet Standard, and it's sweet. So like you said, it's a series of extensions. It's not a framework, but right to borrow a line from our friend Donovan Brown, you're going to sprinkle a little reactive on it. That's exactly it. Okay. All right. So for example, very quickly, normally when you're doing Android development, you would have a fragment or an activity. It's one of the core primitives. And we have what's called a reactive fragment or a reactive activity. And all that does is it extends a couple additional hooks and these hooks will allow you to compose outcomes using the streams which we'll get into. And those outcomes are normally things like before it's created or when it's terminating and all these other things. So we just provide hooks. We take the native events that would normally be used in a... A lot of people should be familiar with the event handler pattern. Oh, sure. Yeah. So the event handler pattern can be converted to observables. It can be converted to the reactive extensions. So what we do is an example of these... An example of this is we take the event handlers that would normally be on Android. For example, when a fragment or activity shuts down a suspense and we convert them into one on an observable. When we say we're extension methods, that's kind of what we're talking about. We just convert existing paradigms into something that works with reactive programming. Well, that makes sense. You already know how to do this. Let's just make it easier for you. Exactly. So let's teach people how to think in a reactive manner and start with a common problem and then we'll get into the code and actually see what this actually looks like. So here is a problem. This is a really common problem I see in desktop applications. But we have a cool view model and we have this Boolean code. It's busy and it has a getter and setter. What's not visualized there is it implements iNotify property change. So it raises property change notifications. And in a desktop app, you would normally be binding or loading an activity spinner on this. Sure. Sure. It's really simple. And like the first requirements come in, it's like we need a load button. And when we're loading, we need to set the loading indicator on and off. So we have a command and when the command is executing, we set it to true. When the command is finished executing, we set it to false. Right. You're saying at some point down the line, display that spinner that says, oh, I'm loading and then when you're done, hide the spinner. Okay. I get it. Exactly. Super simple thing, but there's a problem here. It's a race condition. Oh. What happens when the user taps on the load or the save at the same time? What happens when there's more operations than just that naive example of loading and saving? We no longer have a single source of truth for where the business logic is busy is actually defined. It's defined in so many different places. Yeah. Look at all of them. Yeah. So I've paired them out with particular colors here to show that we don't really have really good separation of concerns. And this is very common in desktop applications. We don't have very good separations concern. The logic for defining if something is busy is like in a class is at the top of the class. It's the bottom of class. It's in a method. And it's really hard to reason about your application. So here in blue, we've got at least two different places in a singular method. We're defining whether the busy should be on and off. In the red, we've got this network request and all these things have been merged together. Yeah. And I like how you called out in green there. What happens when there is an exception here? Now we got a problem. If the exception happens in green, we've got a problem. And it's not just is busy. It's like all these variables that have been mutated by hand are a source of bugs in your application. And when you start using the reactive extensions, that disappears. And I'll show you what I mean now. The entire thing has been segueing to this, Jeff. That's Excel. It is Excel. What did you do? What are you doing to me here, man? I don't think people were realizing that this was coming. They come to a coding workshop and it's now Excel 101. Don't know. No. Oh, yeah. So if I was to say that my accountant is a better programmer than me. Shut your mouth. I know, right? It's true. OK, go ahead, show me. So here's the properties of reactive programming. This is reactive programming, right? So I've got two cells, A1 and B1. And we've got C. And I'm going to go like this. In C, I've put in a formula. And this is in a declarative manner. And I've said any time A or B changes, please automatically update C. OK. Yeah, it's implicit in there. It's not explicit, but yeah, OK. I can buy that. And if I change A or B, C updates automatically. Right, sure. Congratulations. You now know reactive programming. You tricked me here. Yeah, so reactive programming is essentially you can look at iNotifyPropertyChanged without the reactive extensions. And that is a form of reactive programming. Before we had iNotifyPropertyChanged, and we used to do button.setText or button.setLabel. When iNotifyPropertyChanged came along, we no longer had to do that because we have data binding. Yes. And so this is an example of this, of reactive programming. So iNotifyPropertyChanged is reactive programming. Now, but now we're about to start talking more about reactive extensions, which is like the next level up from iNotifyPropertyChanged. It's about realizing that everything is a sequence of events over time. Like if we look back from the forest from the trees in a normal application. Our applications are waiting for the user to do something or we're doing a network request or we're saving to a cache or we're saving to user interface. These are all sequences. These are all sequences. There's sequences and they might be running on a task asynchronously and you want to make sure that when they're done, you trigger the next thing appropriately. Correct. So let's flip this a little bit. If we go back to this, the isBusy, what would happen if that isBusy is instead defined as a sequence. It's a subscription. It's listed. That is column, that is the, that is the column C. Okay. Gosh. Go ahead. We can actually start declaring any time A or B change equals true, then that should be true. Else false. We can start doing things like this and we now have a singular source of truth in our application about when isBusy or showAlert or all these other things, it's all in a singular place. So this is being building up to actually showing a code. This is a coding workshop. So let's actually show some code, huh? Yes, please. Yeah, and that's really small on screen for us. Okay, thank you. I will bump it. Apologies to folks for the dark theme. No, no, you're good with the dark theme. You're good. Let's see there. It's a little bit bigger too. Yeah. All right. So here's our application. This is the application that's searched Nuget for a package. We have a standard, we have a standard search term and that's data bound to a text box. And anytime because they're data binding anytime the text box updates, it's raising I notified property change and it's bound to that sort of when that value is changing, we get the contents of the value of the search term. So the package that we're searching Nuget for. This is very similar. If you're looking at other MVM frameworks, this pattern is nothing different. This is where it gets a little bit different, however. When you use reactive programming and using the reactive UI, what happens is you define everything in the constructor of your application. Like when the view model gets constructed, what you're doing is you're defining in a singular place all of the actual rules and the business conditions. So it's not sprawled. Yeah. Can you scroll that up just a little bit so we can see the last line there? There we go. So let me get this right. You're defining, here's how to respond, here's how to interact with data, with this thing that could be changing and you're defining that up front so that it wires up that event listening, that reaction so that when that property, when that field changes, that's when this method that we have here on line 80 through 88 will actually trigger and go do its thing. Correct. Okay. So I actually ran into a little bit of this problem the other day writing some code and I wasn't using reactive extensions, but this is now making me rethink what I was doing. This might make sense to use a little bit of, in C Sharp, we have partial classes and this type of setup, move it over somewhere else into a partial class. So I've got it hidden and it's over there and it says this is how to configure the rest of the class to react and then I've got just my properties that I'm listening for in my methods to find over in another class file. Where's that overthinking? It's a little bit overthinking. Okay. It's the one thing to look at this code. A lot of people normally when they read .NET code, they're used to the idea of you do an operation and you assign the value to the operation. Right. Right. So if you're looking at line 80 down to line 88 here, it would be very easy to assume that it's just doing an assignment and evaluating once. But what's really happening here is we've created a sequence and this is going to, the search results is going to continually update. This is why it's happening in the constructor. We're starting a subscription that anytime the values, anytime the business logic from line 81 downwards changes, we'll assign it back up into the search results. Okay. Sure. And then that makes, yeah. Okay. And this is how we get our singular source of truth. So this is the only place where the business logic for how the search results field gets populated is defined. It's in the constructor in a singular place. These can be extracted out. If you feel that your constructor is getting quite large, you can extract them out into methods within your class. But typically what we do is, well, we know exactly how the application works because we only need to read the constructor. Okay. Anytime we get a request coming back, we're assigning it back to the search results. Previously, we quickly talked about the show error. Right here, when you're using the reactive extensions, when you have observables, there's two concepts that are really important to understand. There's onNext and onError. Okay. This represents what you should do when there's a new value that was successful. Likewise, we have an onError. This is what should you do if there's an error. And this is the search results. So what we're doing here is we're defined at the top here. This search results is we're listening. It's doing searches over the network. Anytime the value changes. But if there was a network error or some sort of error, we're subscribing to the search results and the errors that were thrown by the search results. And the line directly below that, we're actually defining what should happen. And similar to above, we're defining this in a singular place in your code. And essentially, it's very much like functional programming. You're working with tiny small blocks of code or functions or sequences. And you're composing them together towards an outcome. Okay. So what we talk here is we've defined the search results, defined when it can occur, and now we're consuming the error conditions and then we're composing that together to create a new sequence for what to occur when there is particular errors for the search results. And then so when we get down into where is available, this is very, the logic here is very similar. This is actually how it is busy. We're defined in a singular place like when we're able to actually search or not. An example I normally use when doing desktop applications or mobile applications is something like is network, there's network connectivity. Or instead of is available, is there network activity? And I would normally compose that. I would set up a sequence that listens to network events and looking at the type of network connectivity available. And then I would use something like looking if it's like 4G or Wi-Fi or other things. And all these particular states and the business logic that I want to compose, I just do it in a singular place. So that feels extremely valuable. Like you're suggesting with a Xamarin application, something I'm writing to run on iOS or Android on a phone. And I'm going to make sure that there's a network connection present and when it does become present, go sync, go finally do that search, whatever it was that I was trying to do. Correct. So, here's a classic example. You've made an application that uploads to YouTube. It uploads to YouTube. So there's a couple of things. So what you would do is you would set up a stream or a subscription. And this is what this is. It's a stream and subscription. And I'd be listening to the network events and that would mutate a variable automatically in a reactive manner for is their network available? And that would be one subscription. Then I'd move into a next level of subscription. I would have another value on my view model for is it on 4G or Wi-Fi? And then I would then make that automatically update. Very similar to the search results. So I now have two subscriptions occurring. And then I would go, well, is the use of roaming on cellular data? And that becomes a third subscription. And these three things are defined in a singular place, automatically updating, perfectly efficient. And then I come along with the requirement for the requirement I need to implement for the business. And when it comes to the requirement for the business, I start using this high level language again of this.whenanyvalue. We started this right up here, this.whenanyvalue. So if you have an application and the requirement came in that you want to upload to YouTube, but when it's on only when there's network activity, only try with the network activity, do it only when it's on Wi-Fi, or do it only on 4G, but not when roaming? You've got me thinking of the OneDrive application, right? Upload my photos from my phone only when I'm on Wi-Fi, or sometimes when I'm in 4G, right? I have, there's a switch there as well. Yeah, okay. Yeah, so exactly. So we're now, because we've set up our base subscriptions and the subscriptions are network-available, roaming and type of network, we can then use very high-level operators like selected, select many combined with reactive UIs when any value, and we can start chaining them. Like there is, you can chain together like, we can chain together like 10, 20, 30 of these conditions. And when you're reading this code, it makes so much sense. What we're essentially doing is we're going to pan upload equals, create subscription, any time that there's network activity, any time when there's 4G, but not if it's on roaming. And that would, when you're looking at here, it's going to look very similar to this code here. And it's going to be perfectly efficient. The business logic is defined in a singular place. If it involves time, you can unit test it. And you can actually just know exactly what's going on because your code is in a singular place and all these subscriptions in a singular place and you're not scanning all of the code base to figure out what's going on. Okay, okay. That makes sense. I'm mindful of time. I want to thank you everyone for tuning in and Jeff for having me. There's one particular slider I would love to share. So the timing is, this is not a new concept. This came out in 2009. Once you learn how to program in a reactive manner, you can actually, there's implementation in all your favorite languages, right? All the languages of the world that it is possible to do this. And it's heavily used when doing Android development with RX Java. So once you learn this, it's actually, it's like unit testing. It is something that you're going to take with you for the rest of your life. It's agnostic to the implementation. So for me, it's highly valuable to actually be able to identify problems that involve sequences over time and compose them together to get better outcomes. So highly worth learning. This is something I'd like to wrap up and like kind of talk about is there are times when it's the correct choice to do reactive programming or reactive extensions. And there's time that's not. Sure. Here's just a quick way of classifying and I'll talk through each one of these quadrants on where you would use it. So if you have a singular object, a singular value, and that's synchronous, you just knew up the object. It's standard.net. If you have a synchronous collection of multiple values, iNurable or any one of your standard data structures. Now, this is where it gets interesting. When you're doing reactive extensions, you should choose the right data structure for what you're trying to achieve. I remember when I first learned reactive programming and I changed the file system IO, like file.copy made it something that is reactive. I made a reactive implementation. You can do this. It's not a good idea. You don't need to do it for a file system copy on a local file system. That's not really something that requires a level of asynchronous. That's not something that works really well. But what works really well is maybe if you were monitoring a directory for changes in that directory, monitoring for changes in that directory, and like a file system watcher. And all of a sudden, we normally would be doing event handlers. We've now got singular or multiple values changing over time. And if you have a singular value, you should use task. But if you have multiple values, you should start looking at using observables. And this is where reactive extensions and using RX is using observables and it's programming with observables. And there's operators to convert you from singular tasks into multiple values. And you can take multiple values and convert them into tasks, but it will truncate because task is a singular value. But when you choose a program and reactive extensions, it's not all or nothing. You pick it out for the right task and activity that you want to do. And if we look into the code base over here, this is where we're doing the search. We're actually doing the search of newget.org. And we're converting a task. We can take tasks and turn them into collections and our collections into tasks. It's not mutually... You don't have to take your entire application to reactive extensions. The way that I would recommend people, especially for getting started with this, is focus on your conditions where you don't have your source of truth like this. Is busy, like your business logic. Focus on that and have that as sequences. But things like network requests to a REST API, well, that's a singular call that's asynchronous and you should keep that as a task. So use your view models as sequences and define in a singular place how it works. But when you go externally, consider just keeping them as tasks. Unless where you go externally, there's some sort of property that you need to... You want to subscribe to some updates or things that are going on. Or it has the... For something like SignalR, it's a good example and a good match for using observables, for example. Because there's going to be multiple values over time. Sorry. Yeah. Oh, yeah. Well, very cool. I think... Wow. I mean, we are right up against. All right. So we can mix and match this with a bunch of different frameworks that we already know about when we saw WPF a little bit. Certainly C-Sharp. What do you got there? So this is... In the time that we got, I think it would be good to just quickly point out REFIT. Okay. So REFIT is a HTTP client or it's an automatic REST library. And one thing we'll go into here really quickly. You'll notice if you go to GitHub Flash Reactive UI, you'll find there's a whole bunch of libraries underneath there. One of these is REFIT. And you'll notice there's normally two implementations with all these libraries. There's a task when you want to do singular values. And there's a servable when you want to get multiple values. So here's an example of this. If you just wanted to get the users, like a singular HTTP request, use a task. But if the raw response comes back to you and it's streamed as values over time because it's quite large, you could actually have it as a stream rather than using pagination. And you just go as long as it's connected, it just keeps sending me data until I disconnect. So it's very much like a telephone. Okay. But really cool. So I think we're at time. I want to thank everyone for dialing in and listening and Jeff as well. I hope to see people jumping into reactiveui.net slash slack. I didn't get too much into code. It is very hard topic to get into debugging of code if it's your first experience with this. Just know if you join our slack community because it's a different way of thought, we will teach you how to think in that way and how to achieve it. If you're wondering who is using reactive extensions and reactiveui, a good example I can just show straight away is it's in Visual Studio. Reactiveui is in Visual Studio. And when you do the Visual Studio installer, you see the GitHub extension and all that. That's programmed with reactiveui. So if you want to see a complete, massive application that's been open sourced that uses reactiveui and you want a good way to learn, if you want to ask the chat channel, that's great, but if you also want to just look at code and see an example and how you can actually unit test time and all that cool stuff, GitHub slash GitHub slash Visual Studio, that's the extension, it's got all the unit tests, if that's exactly what ships in Visual Studio and uses reactive programming. Very cool. And there's a question in the chat room. Is there a Pluralsight course on this, something on YouTube, maybe LinkedIn learning? Yeah, sure. The best place to go to learn more about reactive programming for the next step, if this is your first time learning about it is reactiveui.net slash videos. Okay. And there's a particular talk by Michael Stonis. And he goes into and explains how to use the, how all the operators work, how on next, on error, on completed, and how the streams work. I didn't focus too much on the stream side of things because I feel that it's too much to learn at first. Someone's got to show you the benefits of reactive programming and the problems it solves because it's not something that you're just going to pick up. It's going to, when you first were learning how to do unit testing and learning how to do ISE, there was a barrier where you had to learn. And that's why we focus on introduction of some of the concepts and problems it solves. And then we direct people to the Slack channel or to looking at these videos by Michael Stonis. Cool. Very, very cool. Thank you so much, Geoff, for joining us and sharing. A lot of folks are, yeah, saying thanks. Great presentation. Awesome job. Yeah. Thank you so much for sharing. And there you go. There's the book. Indeed. So one of the maintainers, Kent, has written a book on Reactive UI and it's the forative source. It is a really good example and it comes with some really out there and amazing examples. And unfortunately, I don't have time to show. But if you go to his GitHub address there, you'll come across some examples for WPF that are absolutely amazing. The book is good. The examples are amazing. Awesome. All right. Well, thank you very much. And I think we're gonna end there. The chat room is a fantastic presentation they're saying, lots of cool stuff. A lot for them to follow up on. Really like getting hands-on with a book, with follow-up videos, and certainly going to reactiveui.net and learning more. Thank you very, very much, Geoff. And thanks for having me, Geoff. All right, we're going to mute on your side and get our, because our next speaker is actually there in the studio. So I'm going to mute on your end while we transition and bring in our next speaker. All right, there I am. Hello, oh my gosh. Wow, we've done a lot already today. I feel like this is, there's so much going on here with great content for folks that want to build applications for Windows, right? And even the reactive UI extensions that we saw there with Geoffrey, it's not something that you're coupled to do just Windows, right? It also works with Xamarin. It also works with .NET Core. You don't have to be doing just, right? You don't have to be on only WPF for Windows forums. It's a tremendous asset for those, but we can go forward and we can build cool new things using this technology in all these other places. Ancient Coder says, good stuff, exciting. I agree, very, very exciting. And I'm absolutely thrilled that we were able to get a chance to dig into it. And yeah, we didn't write any code, but conceptually, there was a lot there to learn. I hope you found value in this. And I think our next speaker is just about ready to go. My gosh, this is amazing. Quick turnover, they're making stuff happen over there in the studio. My gosh, it's like we've done this before. So much to learn so little time says Codebase Alpha. I agree, right? And that's why, and I hope you find workshops like this one very valuable here on Twitch. How are we doing over there in the studio? Are we ready to go? I see our next speaker, Olya, over there. Y'all set? Let's see, I'm going to unmute in just a second here. Let me know, give me a wave if you're ready to go. Just keeping an eye on things. Yeah, look good. Brave dude to highlight all the spaces. Nah, it's all right. It's good. All right, here we go. Let's bring on Olya. Oh, get the headphones on so you can hear me. That's a good idea. Can you hear me now? You good? Can you give me a heads up? I want to make sure she's ready to go before we get started here. This is, this next section we're going to be talking about is around .NET Core. So we've done, we've been talking about Windows Development but .NET Core with Windows Development. That's something new. Now let's see. Ready to go? Is that Olya? You ready to go over there? Yeah. All right. And we're getting your screen into the mix here. Fantastic. Go ahead and mute your laptop. Mute the microphone on your laptop. Sorry. Yeah, there we go. All right, let me, let's bring on our next guest. There she is. It's Olya Gavrish. Hey, Olya, thanks so much for joining us today. Of course. Thank you for asking me. How are you doing, Jeff? Oh my gosh. I'm, I'm, what, a couple hours in here, we've learned so much about the tooling that's happening in Visual Studio and what's been happening with WPF and some of the frameworks that our MVP friends out there are working on, like the Reactive Extensions and Prism. But you're working on .NET Core. Why don't you introduce yourself and I want to hear about .NET Core. Of course. I'm a program manager on .NET team and I'm working on desktop story for .NET Core. And as you might have heard, Jeff, they're bringing bin forms and WPF to .NET Core 3. We open sourced it in November last year. We're actively working on it right now. We're enabling runtime features as well as bin forms and WPF designers. And it is already available for you to try. Like the latest preview version 3 is out there so you can play with it. You can see if .NET Core is an option for you. Okay, so it's in preview mode. I can download it like all the other open source .NET things that Microsoft's been building. I can try it out. I can figure out what works for me. I can file bug reports. Exactly, yes. And since it's open source, you can see how we're developing in the open. You can contribute. You can file issues or even submit your PRs. We really appreciate input from the community. We have actually a lot already. Yeah, all right. That is very exciting. Oh my gosh, Jess. It is tremendous when the community picks up on something and starts not just saying this is broken, but when they contribute and say those suggestions is phenomenal. So you wanted to talk about today how we can get into .NET Core 3? Do I have that right? Yes, yes, you're absolutely right. So since now for our desktop developers, there is an option before desktop was .NET framework only. And now they can choose .NET Core as well. So the question I keep hearing all the time is what is better for my application? What are benefits that .NET Core has to offer? What is the price I have to pay? Is it hard to migrate my existing .NET framework application? And by the way, we have 2.4 million users running desktop applications in Visual Studio every month. Okay, that's a lot. That is a lot. Yeah, so what is the story for those applications? Should they be migrated to Core? Should they stay on the framework? So I'm trying to help our users first to understand this and then understand how much work will it be to port. In some cases, it's very easy. In some cases, it might not be that trivial or not an option for you at all. And at the end, we would grab an application. Me and you will port it together. What do you think? Oh, yes, please. This is something that I haven't looked at .NET Core 3 yet. But I want to know how I can take that existing WinForms application and get it over there, get it into the new model and start realizing some of those benefits. Yeah, that's what we're going to do. Terrific. All right, so go ahead and share your screen if you want to start. Of course. If you got slides or we're going to go into Visual Studio. And then... Can you see my screen now? I actually see Skype on your screen. Okay. There we go. Perfect. All right. And then you actually have a little window in the top right from Skype. You can close that. Yes, that's fine. Thank you. There's some ugly guy up there. I don't know what that is. Yeah. All right, there we go. Yeah. So first thing, what is it in .NET Core that might interest me as a desktop developer in migrating my existing WinForms application to Core, right? And once you start developing on top of Core, you're getting access to all the good things that Core has to offer. And we keep talking about it in many conferences or announcements. I just wanted to highlight the most biggest things. And one of it is deployment flexibility, right? In .NET Core world, you can deploy different .NET Core versions side by side on the same machine. You probably remember that was not an option for framework, right? Oh, my gosh, yes. If you're developing a framework, you're stuck to one version. If you want to upgrade, that would affect all applications that are running on that machine. For sure. Yeah. Usually how it is done, you need to submit a request to your IT department. They would upgrade the framework version on all machines. Something might go wrong. There might be some regression issues, et cetera, et cetera. Oh, my God. Oh, yeah. I can't tell you how many times that I was working at a previous employer and we'd say, you know what? We're going to deploy a new version of our application. And it now uses .NET 4, right? And the machines are all configured with .NET 3.5. We go to deploy and, oh, well, we've got to upgrade everybody. So we start rolling out the upgrade. We do test rollouts. And now they go to use their older applications and they don't work. Only mine works because mine's .NET 4 and theirs are .NET 3. So you end up with this mix and match collision. Yeah. Yeah, yeah, yeah. Crazy times. Luckily, now in .NET Core, we can have as many versions as you want. You can specify in each app which version you want to target. You can change your mind any time. That's basically you can change your shoes while running. That's hard to do. I've never tried it, but I'm guessing it's hard to do. You can do it with .NET Core. OK. There is an option to go even further and have your application be deployed as self-contained. What that means is that the .NET Core version would be distributed with your application. So in this case, you don't need to worry what environment is on your user's machines. You just distribute your app and it's going to work, no matter what. So I already know a little bit about self-contained applications because as a web developer, I know if I want to develop and push that .NET Core application to a Linux machine that doesn't have .NET Core installed, I've got to bring those pieces with me. I can do that with desktop apps too? Yes. That is an option for any .NET Core projects. And another great thing we're working on right now is a single .EXE. So now imagine all that goodness self-contained but as a form of just one .EXE file. OK. Very easy to distribute to your users. Yeah. OK, real-world example here. So we're here on Twitch. I've got a couple of friends here on Twitch. I've been helping them out. I've been writing a little Twitch bot for them to do different things, manage things for them. And I wrote it in ASP.NET Core at .NET Core so that I could just give them, here's the whole thing. I don't need to worry about what .NET framework version it is. They could unzip it on their machine and it's how many files because it's all the DLLs and this and you're telling me now, we're going to get with .NET Core 3, one .EXE. Exactly, yes. Where do I sign up? Yeah. Yeah, OK, let's go, let's do this. You've got my attention. Perfect, OK, I will try to continue getting more and more of your attention. Next amazing thing is, of course we've been, all this time we've been working on .NET Core. It's much younger framework. So we had a chance to redesign it again, fix our mistakes, optimize many things and we introduced many and many runtime and API improvements. And now if you're developing for .NET Core, you have a chance to benefit from all those improvements. And that also resulted in much better performance for .NET Core than for .NET framework, right? So if you would consider to port your desktop application to Core, you can benefit from all those features and many more. That I won't talk right now, but there are blog posts available announcements where you can learn about all that, right? There's plenty of documentation about .NET Core performance. It's huge on ASP.NET side. It's got to be even better with the desktop. Exactly, yes. And that is all that you will get right now, but when I talk to developers, I also encourage them to think about the future. And as we talked in the announcement, the future of framework and future of .NET Core, the framework will be fully supported. We're not going to kill it or drop it on the floor. Of course, it will get all latest network protocols, security standards, Windows features, but that will not be a place for innovations, right? It's a pretty old tech. There are many applications that are running, that were written years and years ago, and we cannot introduce new tech without risking of breaking old clients, right? And of course, technology is changing. You cannot possibly foresee what 15 years ago, what is happening now, what kind of devices, what kind of high DPI monitors are available now. We need to innovate. And .NET Core is a place where we will be introducing all new features, new APIs. So we will move extremely fast because we have an option of side-by-side deployment. So if in your applications you want to benefit from all the new edge-cutting APIs, .NET Core would be an option for you. If your application was written years ago and it's in support only, you're not modifying the code, you're not going to modernize it any time soon, it's okay to leave it in the framework. Sure, like you said, the framework's not going away, it's a part of Windows. Exactly, yes. Yeah, so if you're considering, like if now I hope I got your interest in .NET Core. Oh yeah. Suppose we, like say you have a .NET application, you're interested in porting it, you probably want to know how hard it is, right? Yeah, what's involved, right? So is this just lift and shift and it just works on .NET Core or is there a little bit something more involved? Yeah, that is a great question. It completely depends on your application. Even though we moved a majority of WinForms WPF Core to Code to Core, your app still can have dependencies on other features that are not supported in .NET Core, like for example WCF Server or some remote in APIs, right? In that case, if you move it to .NET Core, your application will break. And it would be great to know what it will take to port your application before starting any refactoring, right? And there is a way. I want to know what I'm going to be getting into here. Yeah, yeah, exactly. So there is a way to do it and it is called Protability Analyzer. That is a tool that will tell point to all APIs in your code that are not supported in .NET Core 3. You can get it on aka.ms slash portability analyzer. We also released a blog post called IO WinForms and WPF applications ready for .NET Core 3. So you can go get it there. In fact, how about I just demo it? So is this the same portability analyzer that I previously used to make sure that my applications I could use with .NET standard? Yes, yes. The underneath, it's the same tool. We wrote a very simple wrapper. Sorry, that's not the one. WinForms app that would compare your application specifically to .NET Core 3. If you want to compare it to any other versions of .NET Framework, then you can use a Visual Studio extension or the Alt tool. Okay. I've just shared the link to that blog post in our chat room. So that our friends that are watching, they can click through if they want to read a little bit further, bookmark it, all that good stuff. Yes, the blog post has very detailed instructions on how to use it, but it's extremely simple application. You can download it on this link. I already have it on my disk, so I'll just going to run it. So once you download it, you will get portability analyzer AXE, and here you specify paths to your binaries or your source code. What this tool is going to do, it will look at your assembly and compare APIs that you're using in your code to APIs that are included in .NET Core 3. If you have something that is not supported, it will notify you about it. Another thing it will do, it will collect the list of .NET Core APIs and send it back to us, so we can see what our users are depending on. That helps us to prioritize our work, to think what are APIs that we want to include in future versions of .NET Core. To understand how we can better serve our users. Okay. So what you're saying is, by scanning my code with this tool, not only am I going to get that report of what works and what doesn't work, but I'm also effectively voting, if you will, for what's the priorities. Yeah, absolutely. You're making sure voice of your application is heard. Of course, we don't collect any source code, any personal data, nothing like that. You can read about the privacy. Right. It's just the APIs that you're using from .NET Framework. Exactly. Yes. So how about we run this API Protability Analyzer, and I have an application, pain.net, that's open source. Okay. Oh, yeah, p.net. Oh my gosh. I use that for building some of the ugly user interface on my Twitch channel. Yeah. Here you go. So would you like to see how compatible it is with .NET Core? Please. Yes. Let's click Analyze. Depending on how big your application is, it might take some time. Here we go. It creates a portability report. It takes some time. You didn't even finish another sentence than we got in response. Yes. It wasn't that bad, right? It creates a portability report, saves it on your disk. We can open it, like probably open in Excel, it'll take much longer time. But as a result, you will see how compatible your app is with .NET Core specifically, and if you care about other platforms like .NET Standard, Silverlight, any network platforms, you can use the Visual Studio Extension or the tool that is underneath this UI version. All right. Let me hide my video there so we can see behind my noggin. There we go. Let's see here. So we're doing pretty good. Most of assemblies are 100 percent compatible with .NET Core. But we have two, pain.NET and pain.NET.Data, that has 99.96, 99.51, right? So it looks like not that much of a work, but let's look into details. So here you can see APIs that are used in your code in pain.NET, and these are assemblies where they're used that are not supported in .NET Core. So that is basically a scope of work that needs to be done before you're able to port. You will need to refactor your code somehow to exclude usage of these APIs. In certain cases, if you're using all the APIs and we already have a new option, it's very easy to just use a new API and move on. So we would see something in that recommended changes column that says, oh, instead of this, use that? Yes. Great question. We are working on it. Obviously, we don't have a content there now, but that is a goal. The goal is to put as much recommendation as we can. Oh my gosh, yes. Yes. So once you run API port, you can evaluate is it doable to move to Core? How much work am I willing to do this work or not? If it's not that much work, you probably want to know how to port your app, correct? Oh my gosh, yes. I mean, what was it? 99.1% in one or two assemblies? Yes, please. Yeah, 99.96 and 99.56, yes. So I pick an app that we will port together and it's a different, we're not gonna port pain.net, we will port a different application. That's not gonna be a trivial case so we can see all issues that we might face and we can learn, but it's also not the most complex because I don't wanna keep you here for days, right? As much as we can do in like about 30 minutes. So what I picked. We're just going to update it in 30 minutes. Nothing to see here. Right, this is a game. I don't know, did you play it when you were a kid? It's a cold memory game or match game? Yeah, right? When you're turning to cards at the same time and trying to find a match, I played a lot of these games. When I was a child, cause my parents believed it's good for my memory and somehow it didn't work. See, I still suck at this game. But, okay, here you go, at least one. All right. Let's take a look at this application. So inside we have a VIN forms user interface and we have a business logic, our library. They both target, let's see, they target .NET Framework 4.5. Oh my gosh. It's a pretty old app, right? Yeah. So what do we wanna do? We want to move them to .NET Core. And my suggestion is to start with the project that does not have dependencies on other projects in your application. In our case, it's gonna be business logic, right? So we will start with this guy. The task is to move it to core or standard. I'll talk to that later. And the way you usually do, you just change a target framework in project file. But here's the tricky part. Since this application is old, let's look at the project file. First, we cannot just edit it. We need to unload the project. And then, okay. Does that look familiar? Oh yeah. Oh, that's, mm-hmm, MS build file. Right, it's an old style project file which has lots of rows. And when we were designing it years ago, we were thinking that the system will take care of all that. Like humans do not need to edit it. But reality is that sometimes we have, and now when we think about .NET Core, we think Crest Platform, maybe you don't have ID at all. Maybe you're writing it in your favorite, I don't know, text editor, right? We don't want our users to make right all that. That's insane. So we came up with the new SDK style project files which is much smaller, nicer to work with. Another thing, here, let's see the framework here. We see target framework version. This is the old guy he doesn't know about .NET standard or .NET Core. It knows only about framework versions, right? So here, we cannot update it to .NET Core. We need to first migrate this to a new SDK style project and then we'll be able to move it to standard or core. So the way I'm going to do it, I'm going to delete it all and just insert, I have a code snippet because I'm horrible at typing. Sorry, not this one. Okay. Those are five lines. That's it. That's all that we need. Yes. So it's basically project SDK, Microsoft.NET.SDK, and target framework.NET. That's a later version of a framework, but this is the new guy and he knows about .NET standard, .NET Core, .NET framework. This one we can. Right. So first, let's build it and see what happens. Actually, let's first load it back. Good idea. Right. With the previous model of those project files, you had to unload it and you couldn't change it while now with this SDK model. Yes. So now, good thing we can open it immediately, but we have a bunch of errors. Let's take a closer look. It says duplicate system reflection, assembly, company attribute, and so on. So the reason we are getting it, because if we go, if we look in properties, we have assembly for .cs, and in new SDK project file, we are getting this file created automatically. So what we can do, very simple fix, we just disable automate creation. Oh, okay. Yeah. Generate in four, we just set it to false. Right. Let's see. Oh, here you go. No errors. Okay. So in the previous model, we had that assembly info.cs. We want to continue using that so don't automatically generate. Yeah. Another option would be to delete the file. If you want to keep using the file, just add this property. Generate assembly info false. Okay. Now, we have a new SDK project style file, and we can move it to core. My suggestion would be move it not to core, but to standard because this is our library. Even though right now we have only WinForms app maybe in future, we want to develop a mobile app or a cross-platform app. We will be able to reuse the logic if we're targeting standard. Like standard is supported by any other .NET platform. Immolander has a great talk on how to develop libraries, where he talks a lot about standard. I would not repeat his words. I would just give an advice. If you can't target standard, do that. So there's a couple of questions in the chat asking the difference between core and standard. I think you're right there at explaining it. Standard is that contract. You're coding against this contract that works with all the other .NETs. Exactly. Xamarin.NET Framework.NET Core. So if you can write a class library, because only class libraries can target .NET standard, you're in a good place with your class library, right? Yes. That's absolutely right. So don't the standard think of it as a set of rules, and every implementation.NET Core.NET Framework. They should have the APIs that are included in standard. That is a minimum set of APIs that has to be presented every .NET platform. If you're targeting standard, then you're guarantee support for any other .NET platform that your library would be consumed by. Yeah. That makes sense. Like you said, I do want to be able to have a match game at some point that runs on a mobile device. Yeah. So let's move to standard. Let's. For that, we just substitute that with .NET standard 2.0 and let's build it. Okay. So good news and bad news. Hang on. Let me hide my face there so we can see the errors. Okay. So now it says the name registry. Right. So good news we're on standard, bad news we're having some errors. Okay. What does it mean? In our game, in settings like for leaderboard for tracking results, we're using registry to write results. Registry is a Windows thing. It is not included in .NET standard. In our case, we have a WinForms app, so we still want to be able to use registry. There is a workaround for that. It is called Windows Compatibility Pack. That is a NuGet package. Yeah. That was created for exactly cases like that, where you want to stay on the standard, but you want to use some APIs that were not included in it. So to add it to my project, I'm going to go to manage NuGet packages, and I will search for Microsoft Windows Compatibility. Okay. This is the guy Microsoft.Windows.Compatibility. We're going to install it. It will give us around 20,000 APIs. Some of them are Windows only, some of them are cross-platform. Okay. It will give us bigger space to play with. Oh, yeah. Yeah, go ahead. I'm blown away with how easily, how quickly we can say, we're just bringing another 20,000 APIs. It's right here in this NuGet package, and it makes them available to you. This is huge. This is making all of those things work with all the new technology. Exactly. Yeah. So good news are errors are gone. Okay. But let's think for a moment what we just did. We enabled Windows on the API registry on a.NET standard project. You see where I'm heading? Yeah. Go ahead. In future, we will want to use this.NET standard project on Linux or Mac OS. We will face on there. On my Android phone. Exactly. Yeah. It might happen that, for example, I developed this code and some of my coworkers picked it up and bringing it to Linux, Android, et cetera. They might not even know that they used that API. For sure, with my memory skills, I'll definitely forget in a year. So it would be nice to have a way to be notified. Sure. If we're using some APIs that are not cross-platform. There is a way to do so. That is another NuGet package. Another analyzer. This one is in pre-release, so you need to check include pre-release. Okay. And it is called Microsoft.NET analyzers compatibility. Okay. So these are Roslin analyzers. They're not actually enhancing my code, but they're telling me things about my code. Yes. Yes. This one will prompt you every time you're trying to use API that is not cross-platform, or when you're trying to use API that is deprecated. And as you can see now, we have all those warnings about. So now I'm getting build warnings because it doesn't work cross-platform. Okay. Yes. Yes. I'm going to reflect over here to Swiftress in the chatroom is saying it looks like there's some extra steps to build more software that runs only on Windows but conforms to the standard, wherein only some of that can run cross-platform with no cross-platform UI components. I think what she's saying is, by taking these extra steps, something that was very Windows-specific previously, we can make now work cross-platform. And now we've got messages here that we know here's where it will break when you try to use a cross-platform. Yes. Yes. You're absolutely right. And that is only if you want to get those messages. Sure. For example, if I made my piece with registry and I don't want my code to look like a Christmas tree, I don't want all those highlights. Get rid of the red and green. No more red lines, no more green lines because of those errors. Right. I can suppress the warning. I just click on the light bubble and I go suppress in source. That would be suppressed. Or I can do it in a suppression file. In that case, it would be suppressed for all occurrences of this API. There's a follow-up question about those analyzers that I think you can help us with. ME Too Fast in the chat room is asking, is it possible the analyzers come with a future version of Visual Studio as an extension so that when I am building a WPF on .NET Core application, I'll be able to see some of that information. That is a great question. And that's actually why we're showing those analyzers and collecting feedback. I would personally be very happy to see it in Visual Studio. And if we have enough feedback that that's something useful, I think in future we might enable it there. So thank you for your feedback. It's very good. Another just a tiny thing to show about the analyzer, what else you can do? You can customize how you want to be prompted. Right now we have warnings, but you can make it error, you can make it in for whatever you like. For that, you go to dependencies analyzers compatibility and here all your warnings. So for example, for this one, you can go set rule, set severity, you can pick, right? Nice. So for example, something I think is very critical. I don't want my build to be successful without it. I set it to error. And that's a Visual Studio feature that's been there for a while. That's available in 2017 and 2015 as well. Yes, yes. So good news, we're fully migrated our business logic to .NET standard, right? And now what is left is to port our user interface, WinForms to .NET Core. And here we can do the same thing, but I want to show one trick. And for that, I'd like to remind that our .NET Core 3 is in the preview version. So there are features that are not yet available. We're working on them. And one of those features is a WinForms designer, right? It does not exist right now for .NET Core projects only for .NET framework. But if you want to migrate your WinForms application, you probably want to use designer, correct? Oh my gosh, yes. Yeah, there is a way to do that. And I'm going to show how. And one option is I will leave this framework all the application as is. Okay. And I will create another WinForms application. I will link all files from my old framework application to my new application. So every time I want to. You're going to trick Visual Studio. Exactly. Every time I want to use a designer, I just open my old project and use designer the way I always have. And but I will have those changes immediately done in my new project because they're sharing the same files. So we already know how to share files between projects. You're just going to share it from an existing working project into the new model project. Yes. All right, chat room, get ready to clip this because I think this is a hint that we're going to want to make sure folks see. So let's make sure we can create a clip of this. Go ahead, Elia. OK. So I'm going to create a new WinForms application. To do that, that's another thing that is not yet available in Visual Studio, templates. So we will create it from a console, but templates are coming. So what are we going to do? Do .NET new WinForms. And we will specify the name matching game.core. Let's see. OK. .NET restore. We're great. Perfect. Seems like we successfully created a new project. Let's add it in our solution. Existing project. OK. So here you go. How about we run it and see what is there right now? We're going to set it as a startup project. So right now, that is a simple hello world application. Yeah. Cool. Yeah. All right. That comes with the template. Sure. That is awesome. But think about it. This is a WinForms running on .NET Core. Pretty awesome, right? Oh, yeah. It's a big step in the right direction. Absolutely. Now we're going to delete all those files, the dummy one, and we will link them from our old framework. Because we can use item groups and reference. So we do compile include. We specify the application where we want to get files from, our matching game, our old framework application. And we just do OCS files. If you have Resx files, you need to do the same for Resx files. OK. Resx files are the resources if you're doing translations, text replacement. So let's see. Now we have in our .NET Core, we have those files. OK. One thing we need to not forget to do is also disable generation of assembly info. Oh, because we also brought in the assembly info. Yeah. OK. Now let's see. So now we have error. The type or name, space name, logic does not exist. Obviously, because this guy has dependency on logic, but this guy doesn't know about it yet. So let's add a dependency. OK. And Adam in the chat room is asking why we disabled generate assembly info. And Adam, that was because there already wasn't assembly info in that project that we're going to bring across that already has all those things defined for us. So no need to generate it. We've already got it on disk. Thanks for the question. Actually, I think I just. Oh, yeah, Mr. B in there. There you go. All the same. See that? Live coding friends. Live. Yeah. OK. Perfect. Back to our warnings from. From the registrar. A giant analyzer. Right. OK. So how about we run it and see what happens? Come on. Here we go. Fingers crossed. Oh, it's going to work. It's going to work. Oh, my God. Oh, yeah. Oh, yeah. Listen to that thunderous applause. Thank you. Thank you, chat room. Thank you. Yeah. So yeah. I mean, OK, this is a this is a simple application. But really for a series of clear steps, this feels like something that a lot of folks could follow and make happen quickly. Absolutely. Yeah. And again, I picked the old application that didn't have SDK style project that had a dependency on API that is not included in dotnet standards. So maybe your porting experience would be just update framework version to core. And that's it. Sure. Maybe you don't need to use the designers anymore. Yeah. Or of course, there are more complicated options. Or another way I wanted to talk, instead of having two projects to link projects, another option would be to have two project files and load your project with the older or the newer one. OK. And in certain cases, when your application is very complex, that might be a better way to do it. So you have to try. OK. So OK, go ahead. You're good. Some moderators are helping with some of the questions in chat. This is great. Perfect. Perfect. So yeah, as I said, to update the designer, you can open the old app, the old framework project. You can do your changes here. We can just test it, update. Let's do that. And let's run our dotnet core, the new project again. Let's make sure. Oh, OK, update. I cannot type, but you can see that. But that's fine. Yeah. So you changed the title, and it still works from the designer from the other project. It's perfect. Everything works. Oh, look. And you're doing better this time, too, at the game. Yes, I think I learned. So the question I'm seeing here from Swiftress in chat is, if there are no cross-platform UI components to use the legacy frameworks, and we have to take these extra steps, it doesn't buy the cross-platform deployment. They don't see advantage. Well, some of those advantages that we do have are, like you were saying, being able to deploy the framework with the application so that we don't have that dotnet framework criss-crossing deployment issue that we have current. Exactly. Yeah, so dotnet core has many perks that may not be obvious when we think about core, we think all cross-platform. But it's not only that, right? You mentioned side-by-side deployments. We have a flexibility in deploying options. But we also have all new APIs, like C-Sharp A, right? Span of T, that would be available only in dotnet core. And we've been fighting that high DPI issue as well. Yes, high DPI improvements would be available in dotnet core. Yeah, so if you want to benefit from all that, dotnet core is a pretty good option, even though you have to be with windforms only. Right, right. So there was a question earlier. I want to make sure that I call back to it. When you were speaking about the self-contained apps, when something's packaged down to one file to that, one EXE that's going to be deployed, if there's a security vulnerability that's found in something that's been compiled into that EXE, what happens? How's that handled? Good question. I don't have an answer on the top of my head, but I'm not the person to speak about it. But my guess would be we probably would need to incorporate that update and rebuild and redistribute the new EXE. Sure. Yeah, the developer's going to have to handle that. And I suspect that Windows Defender would block the ability to run that EXE, but we're still working on that story. Yes, yeah. OK. I'm just looking. OK. Moderators and VIPs are handling questions. Good. All right. We've got about eight minutes left. Plenty of time. Yes. Yeah. Just to summarize what we just did, we talked about why .NET Core might be a very good option for your desktop development. And Portability Analyzer can help you to understand how easy your heart would be to port your existing application. And then we just ported an application. We also have a .NET blog post with the very detailed steps and options for WPF. For WPF, it would be very similar. And the minor differences pointed out in that blog post. I can pull it up. OK. Right now, it is called how to port desktop applications to .NET Core 3. Right? And it has the same sample. It has a video recorded earlier and has more detailed steps. I was trying to describe not only this particular matching game, but also other issues that our users might face while porting. OK. I would encourage you to give it a shot, to let us know, give us your feedback. We're eager to learn and to try to make your experience important better. Yeah, I just shared the link to that blog post in the chat room. And to be clear, this isn't a required update. Folks aren't required to port their applications. But like you're saying, if you want to take advantage of those new APIs and you're going to continue to evolve your application, you're going to want to get into core. Yes, absolutely. Very cool. All right. Just keeping an eye on here for any questions in chat. Adam says, I prefer this segment clipped highlighted somehow than to necessarily read the doc. You know what, Adam? That's why we decided to have, oh, you join us for an hour here and talk through this. Yeah. Perfect. I want to create a simple hello world app, put in a fresh Windows 7 VM this weekend and try again. Yeah, that's windfish. That makes perfect sense to give a try to. So a lot of very positive feedback coming through. That is great. So all right. Terrific. Well, thank you very much, Olya. Oh, of course. And I think we'll, yeah, gosh, there's no other questions in chat. I think we can get ready for our next session. Sounds great. All righty. Well, thank you so much. Thank you very much for hosting it. I'm sure we will have many more interesting sessions today. I'll definitely be watching. Oh, yeah. We're going to talk about XAML Islands next. Perfect. Perfect. That's a very interesting topic as well. All right. OK. Thanks so much. We'll catch you later. Thank you. All right. I'm just going to put you on mute. And we're going to, come on. There we go. Back over to me. Yeah, oh my gosh. There's so much happening there, right? .NET Core is really where things are going. This is going to be the future of .NET. All the innovation that's happening right now from Microsoft, it's open source. It's .NET Core. You're seeing the new versions of C-Sharp and VB are going into .NET Core first. And that's what's going to help drive and set up and set the tone for the next set of technologies. And I think you're also seeing that there's great things happening with .NET standard so that you can get these technologies running in Xamarin. Port things from .NET framework to .NET Core a little bit easier. Take your business logic that you already have out in those class libraries. Make them .NET standard. Check out that portability analyzer. And you'll be able to determine how easy it is to upgrade. There is no push. There is no requirement to do these upgrades. But if it's something that you're going to be maintaining long term, sure, you're going to have .NET framework available to you for a very long time. It's something that is not being removed. It's part of Windows. You're going to get it as you install all the versions of Windows 10 as they come out. And you're going to be able to continue to use those applications. And we're getting our next speaker ready here. Make sure that things are set up. So we're going to start talking about something called XAML Islands in this next segment. I'm looking forward to this because if I have everything set up correctly here, and this is a piece where we're going to start to learn how to cross the streams, how to use things from one type of XAML in another to get our interface working together, regardless of which UI technology, which client technology it is that we're using. Don't cross the streams, says Codebase Alpha. Well, maybe. I like this comment from Windfish, 1981. At least .NET Core is like beer. It tastes good if you do it right. Oh, man. That's not too bad. Diver Dan agrees there. That's a cool emote from a hearthstone. Very nice. Very nice. All right. I think we're ready. How we doing there? Can you hear me in the studio? All right. I think we're ready to go. I'm going to bring on our next guest. This is Ricardo, if I have it right. Here we go. And the transition. Hello, hello. Welcome. Hello. Hey, you can hear me. There we go. Why don't you introduce yourself real quick? Hey, I'm Miguel Ramos. I'm a program manager in the Windows Developers brilliant platform 10. My team is the one who work in the UWLIP platform, MSIX, all these UI stuff. So that's basically me. Yeah, all right. And here, I better put the name up. There we go. There we are. Now folks know who we are. And we're going to talk a little bit about Windows 10 API story for Windows Developers. Do I have that right? Yes, we are going to talk about that. Windows 10 API for .NET developers as well. We are going to talk about some of the items. Cool. Now, let's get your machine connected in here. Can you join the call with channel nine? Go ahead and yeah, call. Well, I think actually you just added me recently. So you can add me on Skype. Call me. There we go. And then mute the microphone on your side. That should have added you. It didn't add you. One more time. We've got this. Let's try again. So join call. My microphone is mute. Hang on. We'll do this. Move this up here. All right. And what we can do is you can share screen from over there so that we can get that out. And we can take a look at your slides and your code that we're going to talk about here today. Great. I'm churning the screen right now. Yeah, there we go. Oh, yeah. Yep, you can min my Skype. All right. Very cool. Wonderful. And there we go. All right. Modernizing existing Windows desktop UIs. All right. So this is something that I know folks have had a challenge with. My gosh. They've got existing Windows Forms applications. They've got existing WPF applications. And they want to bring the web browser in. They want to have that browser control because they've got a help page or they've got something out on their internal network. Oh, just show what's on that HTML page over there. It's a problem, isn't it, when we get into Windows 10? Yeah, it's a problem. Yeah, it is a problem. This is something that we try to resolve with all this kind of hosting technology that is helping Google Valper to put all together and use the best part of every platform. This is something that we are going to talk today. OK. Do me a favor, last thing. In the top right corner, there's a little Skype window that's hanging around. You can close that one. All right. Yep, you're good. All right. So go ahead. What are XAML islands? Can we start there and take a look at your agenda? Sure. So let's start with very quickly about what is XAML islands? XAML islands is something that is going to help to the developers win from WPF and also win 32 developers, native with C++ application, use the latest innovation that we have done in the Windows UI platform. So they can use all this kind of through and design stuff inside of their app. Oh my gosh. And then those other, I called out the web browser. That's the one that I've run into the pain point with is the web browser on 10 is Edge. I want to get Edge into my application, but Edge is a UWP app. Yes. So right now we also can do that with all XAML islands. Oh, very cool. I will review all these things that you can do it. So yeah. So the agenda that I have today is something like that. I don't know, it's not clicking. No, it's working. So I always like to put in context to everyone. So I'm going to review very quickly about all the Windows desktop UI that we have in the platform. So Win32, the WPF, WinFronts, and UWP, just to have a sense about what are the advantages of each one. And then I'm going to introduce XAML islands. Then I'm going to share with everyone the roadmap that we have today for XAML islands. And also I would like to just share several feedback channels so people can give feedback to us digitally to the product group. So this is the agenda for today. Sounds good? Yeah. And I like that we want to make sure that there are feedback channels that, especially you folks out there that are watching, not just ask questions here in this channel, but when you come back and you try out some of these features, let us know. This is more of us becoming part of the community. We want to hear from you so that we can work with you to make this experience better. Exactly. We're really eager just talking to you. Oh, yeah. All right. Go for it. What do we got here? History. Oh, no. I hate history as well. Ha, ha, ha. But sometimes it's necessary to put the thing on context. OK. So let's start with something called Win32. So Win32 is something that is, wow, it's right now 25 years old. I can't believe that. Yeah. It's something that was released with Windows NT 3.11 in the digital cell of Windows 95. I was still in high school. Oh, my gosh. OK. All right. I hadn't gone to university yet. OK. Thanks. So 25 years ago, we have the Win32 and we ship something called the Commando's Library, which is still live. So if you go to the operating system, go to the tax manager. For example, you will see all this menu bar on the top. You will see all these radio buttons, checkboxes. This kind of application are Win32. And they are following the common controls library. This API was C. Actually, there is a wrapper in C plus plus called the NFC, the Microsoft Foundation classes. So what happened with that is actually it requires that you really know what are you doing. Oh, my gosh. Gosh, somebody in the chatroom is saying, I wasn't even born yet. Oh, come on now. Come on. Same story. Now I feel even older. Thank you. The thing is, this is a very stable platform. Of course, 25 years old. They have an understander performance for this density of data. This performance, because it's really native, it's very close to the hardware. So yeah, what you said, it's nothing between you that is helping to you to create application. It's actually had to write code, a lot of code for do something. So the thing is, this is still live. The last update that we did in the platform was in 2008 when we introduced the ribbon, the docking, and the document tabs. If you go today to Visual Studio 2019, you can also create still Win32 application. If you go to the new filter of app to create new application to desktop and choose MFC, you will get a Windsor. And this Windsor is going to help you to create your first Win32 application, something that I always love to show. And while you're bringing that up, it really says something. It's a real testimonial to the work that was done with that original UI library that it's lasted so long. And it's really set the tone for Windows user interface experience. And it's something that folks recognize and are able to immediately grasp. Exactly, exactly. So this is the template application that it's creating. As you see, it's a little bit of an update. It's not very fashion, it's not very modern, but it's functional. It's still working. Sure. So let's go a little ahead of the time. This was in the 93. In the 93, so in 2002, with the first version of WinFront or the framework, we introduced Windows Firm or WinFront. So this is 70 years ago. It can drive now legally in the States. So the thing what this technology was doing is grabbing the common controls that you see in Win32, but also adding a lot of new controls that make it easy for developers to create a lot of data business applications. So somehow they rationalized the investment of developers in order to create applications for language listening very quickly. So actually, you had to write code and manage code in C-share or Visual Basics. So the performance is a little worse than Win32 because it's a rubber on the top of Win32. But the trade-off is about how can we create an application faster in this time than Win32. So the only thing is there is no new controls in the platform since 2006. But luckily, we have seen in 2018, we poured the WinFront's platform to the network 3 and we make it open source. So everyone can contribute to the platform and we are happy to receive help. Good. So this is WinFront. Let's go a little more. WPF, this is only 13 years old. It is in 2006. And with the version of the Donner framework 3, so we ship WPF. The feedback that we get from WinFront's developer was about, hey, this is great, but I want to create custom controls. I want to create more different kind for UI and it's really complicated to do that with WinFront. Actually, it's almost impossible. They have to invest a lot of time just to do some simple things like changing the layout of a button. So all this feedback that we have from the customer, what do you think, is just come out with a different platform on WPF, which is going to separate the presentation from the behaviors. This presentation is going to come out in a somewhat market language, something that we have seen early this morning. So developers can specify the layout of the UI very quickly. So the good thing about WPF is no longer using the GDI plus underneath graphics engine that you're using in Win32 and WinFront. They are using a more powerful graphics engine like Dataset 9 for rendering. So that means that these platform can use all the hardware accelerations in the graphic card. Since I really like about WPF, oh, wow. There is a lot of API just to do whatever you want. So you imagine some UI, you have this API. And you can literally create. And also, I really like the data binding, the separation. How easy is to separate the data from the control so you can just create this binding as true to as saving to you a lot of time when you have to create an event and try to fill the information in the event. That having to do with fixing all the things and how. Another. But it feels like we went from where we had MFC and when we built our user interface that way. And then we did Windows Forms. Everything was very much like it was the square box. You got the Battleship Gray application. And for an enterprise application that just needed to give you some data entry, good enough. But yeah, but it felt like I was getting into a sports car. It felt like I was getting into a Corvette, a muscle car where it's like, you know what? I can change the way this looks. I can use the graphics accelerator to build with WPF. And having XAML available to me as a design language meant that we could be innovative without having to get all kinds of crazy. You're right, in the Windows Forms designer. And I think that really says something about taking that feedback from the customers and saying, all right, let's give you this control over your user interface. Yeah. That's what you prefer to describe exactly all the steps that we have done until I arrived here. So the last control that we had to the platform was in 2012. It was the ribbon. So but in 2019, so we put this to the core three and we make a common source so everyone can contribute to the platform. So this WPF is great, it's wonderful. But you know what happens? It happens that there is new hardware, new requirements, new users that expecting something completely different from the thing that we have today. Yeah, just thinking about how the users are right now engaging with the application in the mobile or even in some specific desktop apps. They are expecting some kind of a powerful animation that may make feel happy with the design. But they also have new 4K monitor with a lot of space and we tend to put a lot of content in the screen and we are expecting that the performance of all this engine is still wonderful when it's something was created like 25 years ago or 13 years ago with a completely different kind of requirement and a completely different kind of mindset. So with all the things in mind, so with all this new core and new experiences, new hardware, even new user interaction is not only mouse and keyboard, but also we have the input with the touch, with the trapper we are expecting to have some kind of gesture, the pen. So yeah, so even gaze, you see now with the HoloLens are also there is specific devices that are following you with the gaze, right? So we need something more than WTF. Oh my gosh, just the gaze interface alone, right? Let me just touch on that for a second. Folks are used to using a pen or their finger with their phone, but the gaze interface where it knows where I'm looking because the camera is that good on my device, that's impressive, that's valuable and the accessibility that that provides to our applications users cannot be underestimated. Exactly, exactly, completely agree with you, 100% with that. So, and this is the reason why like four years ago, we came out with UDP. It's a platform that we create from scratch, taking all these things that we learned from the Win32, from WPF, even for WinFront and put all together in a new platform that is going to support all these future things. So for example, with UDP, you can create application in C++ because it's native, so you have the best performance ever, but if you want to create an application faster, you are going to use Managed Co in C++, right? So we have the two words, the native and also the manage. The performance outstanding is always outstanding that the operating system, Windows 10, is using this platform in the shell, in several applications, all the new stuff that we are doing is UDP. Another interesting thing is, all right, security becoming something really important for the people. Sometimes we rely in the applications and the application developer for taking care about all the security and maybe it's too much work for all these people. So we came out with a model where we are going to run the UDP application in a container where it's going to take care that your application, that you are running there, is not going to damage your operating system. And also- That sandboxing effect that came with it, yeah. Exactly. Okay, okay. So another interesting thing is we were talking about the new users and the new user are expecting having laptops with a battery that lasts like 24 hours. So- How do we extend battery life? Yes. Exactly. So it means that we need to kind of with a platform that consume less battery than WPS or wind from right. And also the platform that we are targeting is PC or writes wonderful. We have a lot of custom in PC, but we've seen that there is a lot of new kind of devices and developer want to target these devices as well. So Xbox, for example, the new Surface Hubs or IoT, even the new tablets and mobile. People want to target different things and why they have to use different technologies to target each kind of things. Why not to use exactly the same technology for everything? So this is the reason why UWB was created. Was created to have something new, modern. Talking about modern, so we are learning with our experiences that we can just scan up with a design and say to everyone, hey, use this design, which is with approach from the metro. We learn that we need to create a design, a new design style, the design pattern that evolves with the user. Something that is changing and is every year changing that is learning from the feedback of the users. And this is the Fluent Design System. The UWB is the platform who were really implementing the Fluent Design System by default. So developer doesn't have to worry about, hey, I need to create a beautiful application. No, this isn't that we are going for free. So we all do things, right? Is that what's the goal of UWB is wonderful. We want to chip more and do more stuff on that. So last year in 2018 with the announcement of the NECORF 3 with WPF and WINGFOR, we also announced that we are going to make open source all the controls that we have in our platform. Yeah, that's a big thing. Exactly, but there is more. It's not making open source. We made the commitment and say, hey, we are no longer going to work in the dark side doing this by ourself. We are going to work in the open source space or the specification, all the roadmap, all the plans are going to be public there. If you want to know exactly what we are doing right now, go to this WINGFOR library, take a look to the documentation, take a look to the pull request, and you will see exactly how our developer are really creating code. So you, developer, can also influence in our design. And we are here, listen to you, yeah. So this is the new Windows UI library. So another interesting thing about the Windows UI library is that all the controls that we are chipping there are some downloading support until it is true, which is the anniversary update. So happens that when we are chipping something, for example, in the October 2018 update of Windows, this new control can't be used if you are running in the April 2018 update. So because it means that there is some kind of limitation. You need to be up to the date to the latest update of Windows, right? Which is great, but you need to be there. So with Windows UI, we are making possible that the control that we are going to ship there has this download support. So there, for example, the navigation view is no longer something sticky to the version of something some update in 2017. It's something that you can use in the anniversary update as well. And also this allows us to chipping faster. We want to do more and more stuff. The way to do that is making something simple for us, the coupling for the platform, and chipping across the Nuke packages. So Windows UI library is, or when UI, how we call that is, they are, it actually is right now, just a Nuke package that you can install using your application and you get all this control for free, right? This is wonderful. I really like it. Oh my gosh, yes. So if you want to learn about UWP, I always recommend to the people, go to this app, the Samuel Contours Gallery. Go to the store, download this app, take a look. Explore all the controls, all the things that we have in the platform, and we have a lot. Right, so I mean, it's a good place for you to experiment and figure out how's my, what are the things in the box that I can get without having to figure out and build my own stuff, because there's a lot there that you can use beyond just buttons, check boxes, radio buttons, drop downs, there's charts, there's gosh, animations, grids, all kinds of great stuff, right? Yeah, there is a lot of wonderful things. You have a lot of possibilities with the UWP platform, the Samuel Contours Gallery is the best friend for you. You want to learn something new. However, if you are a very advanced developer, you can from this WPF world, you really know a lot of concepts, right? Because we are reusing a lot of concepts from WPF. You want to start to create something and you really need some help. So I also recommend to the people to go to the GitHub and find for the inventory sample and download completely into a language business application where we implement the fluent patterns in our enterprise app. So this app is using more of the model patterns or the dependency engines, all these things that we are really recommending to the developers to use when they have to create a very mind-involved application that needs to be managed by the time, right? Sure. Right, so, huh. We have win32, 25 years old, winfarm, 17 years old, WPF, 13 years old, UWP, something that is four years where we put all the innovation of the last years. Today, you can have a winfarm application and you can consume WPF controls, right? So it means that you can start to mix these two technology. Actually, you can have a WPF application and reuse some controls of winfarms. Something that just a few people does, but is possible today, you can also winfarm a WPF application host to each win that can render win32 content. Ah, okay. You can do that, but it requires a lot of knowledge about what the platform is doing. Right. So, okay. So, how can we use all the things of UWP inside the win32, winfarm, and WPF? This is where Xamai Islands comes. So, Xamai Islands is a way where you can able to use all the things I told you about UWP in your win32, winfarm, and WPF. So, thinking about the all Microsoft Foundation classes application with this outdated, outdated look and feel, what if this C++ developer can use the fluent design, can use all the UWP controls in the platform? Yeah, they can do it. All right. Now, this is where it's getting interesting for me. The modern, look at everything that we've learned over 25 years, all of those features now, we can go back and add into those legacy applications when you're on a compatible version of Windows. Yep. All right. So, how do we do it? How we do it? Just one caveat. Uh-oh. Yeah. Everything I'm going to show you today is a work in progress, right? Okay. We shipped a preview of Xamai Island, something that I really like to call an alpha version in the Windows 10 October update, October 2018 update. We did that just because it was there for testing proposals, how they are thinking about, hey, there is a specific customer who really, really, really need this right now for this specific scenario. And we did that, we shipped that. But it was also an alpha version. The first release of Xamai Island comes with the next release of Windows 10. Okay. Something that we internally call native H1. So, the next release of Windows is going to have a very good support for Xamai Island. So, you are expecting to have all these kind of controls, all these kind of effects animation working inside of an island and with it to do in front of the application. So, we are shipping Windows 10 soon. It's unknown. But, when we ship Windows 10, the tooling is not going to be still ready because we need to do a lot of more work. So, it means that Visual Studio 2019, I think that is released on time in April. The Xamai Island support is not going to be there, but it's going to be available in some update around September, October. This is the time of friend that right now we are playing with. Okay. So, it means that, yep. You can at least get in and get started, right? You can start and with the understanding, it's a preview. Yeah. All right. So, you need, yeah. We have a lot of samples for people kind of low starting to play with that. So, they don't have to set up the developer and by long environment for that, set up the don't record the application for making working with some of that. We have a lot of sample where people can download something to just write code, just to simplify the thing. But, we are pursuing a stringing developer speeding from Visual Studio as well. There is another component that is going to be shipped in a different frame. I will explain all these in more detail in the roadmap. Just some caveats before continuing with that. So, some islands, how? How this works? Well, so, some islands is a set of components. And the first component is a low level component at the level of the operating system. We are going to have a sample hosting API, a WinRT API. The WinRT API are the API that are using UWP applications. The WinRT is exactly the same as Win32. This is the similar concept, but UWP is the high level concept. So, we have a WinRT API, which is going to have all these hosting things. Developer can also use all the inbox sample controls. And if they want, they can also use all these out-of-band controls that are cheap in the Windows UI library. So, they can use all together. So, if you are a Win32 developer, you need to communicate directly with this low level API. This low level API is something called Desktop Windows Sample Source. This is the Windows 10 API. And what this API is expecting is, hey, give me an H-Win. Give me the Windows handle or your application. Give me the Windows handle or your application to the Desktop Windows Sample Source object and the Windows Sample Source object who returns to you a child window. And in this child window, you can put all the sample content that you want because this API is going to take care about rendering everything, interacting with everything inside that. So, looks like it's simple in concept, but it requires a lot of tricky things. Oh my gosh, yeah, it looks very tricky. My gosh. Yeah, let me show you something that maybe is going to feed you a little awe. So, this actually, there's a question here in the chat room. I want to make sure that we reflect out to. It looks like Racha08 asks a question here about the airspace issue. Is there still an airspace issue with XAML Islands? There is, yeah, for sure. There are airspace issues. Some of them is because you require research on the space or your host to set up that. So, in Win32.2, yes, it's going to be that. We make some work in I think H1 in the next release to resolve some of this airspace issue. Like, for example, pop-ups. When you have a pop-up, you want your pop-up upside of the hosting, right? So, we resolve all these pop-up issues. This is something that, yeah, it's going to be, you develop a handle to have for free. However, all the airspace issue in Win32, for example, is known to be for free. You need to be allowed about the relight out of the fence. In WPF and WinFront, there's another story. We can talk about that a little later. Okay, and gosh, I'm reminded here. Can you explain what the airspace issue is for folks who might not be actively working in this space? So, the airspace issue is you have your application. This is your, for example, your Win32 application. You say, hey, this rectangle inside is going to be my SAML ILM. And I'm going to put all this SAML content inside of this Win32. What happens if the content that you put there is bigger than the space that you reserve? So, it happens that the content is going to be clip and you don't want this, right? You want that the content is 10. Actually, it depends on what the scenario is. I found different scenarios where people really want to clip the fence, but in the majority of the cases, people really want to extend the fence, right? This is the airspace issues. They mean something that is really painful, for example, is in my engine, you have your area. You put a combo box in the bottom and you click in the combo box and the combo box is clipped. So, it doesn't make it disgusting in user experience. This is something that we really fix because a combo box, when you click, is a pop-up and the pop-up is going to be upside of the hosting area. So, we can resolve several things, but other things is really complicated. We can make magic. Sure, okay. Well, let me show you a demo about all these things working with C++ because I know that there is a lot of C++ developers that are eager to use modern features. So, all right, here, chat room. Help me out here, let's let us know. If you're a C++ developer out there and you're building interfaces, type one in the chat room right now so we can see how many folks are C++ developers watching right now. We've got about 250 people watching in the Twitch chat room. There we go, I'm seeing a couple of them pop in. Oh, yeah. I know, I know. So, we know they're there and we want to make sure that you get support. Yeah, for sure. That's wonderful. Yeah, really excited about how many C++ developers we have. Great. Cool, okay. I'm going just to load this C++ project. I try to create the most simple Win32 project ever which is create a window. Let me down a little. So, this is a Win32 application. I'm using a C++ WinRT extension so I can to consume a WinRT library from this C++ applications. This is the reason why you can see and hear these headers. So, the thing I need to do to consume some islands is first of all, this is the window I'm creating is just, all right, Windows 10 APIs are based in COM, they're all COM technology. So, the first thing that we need to do is to set up a specific apartment required for running all the SAML environment inside that. And this is the thing I'm doing first is initializing this apartment, this single, as a single threat apartment. The second thing is, okay, I have my apartment. I need to set up all the SAML environment and then I need to just create this Windows SAML manager in here. Let me zoom a little the font because it's much better for me. I'm not gonna get that for you as well. No, that's fine. This is the Windows SAML manager. Okay. Yeah, we have the apartment, we have the single, the Windows SAML manager over there. The next thing that we need to do is just to create the desktop Windows SAML source object. And the desktop Windows SAML's object requires the H-Wing. And this is the thing I'm doing here. Creating the object and passing it to the H-Wing of the application. So, when I have the H-Wing of the window, the thing I need to do is just grab my child H-Wing as set up the position on the side of the H-Wing. And this is something that I am doing in here with the setWindowPost API. Well, I have my child window. The next step is just put a lot of content inside there. Well, let's do that. So, right now I'm creating my step panel in here in the code behind, when code behind in code. With a brush, I'm creating a text block and up into the step panel. And then the only thing I need to do is this desktop Windows SAML source object have a property called content. I am setting up the root of the SAML content in there. And that's it. This is all the thing I need to do just to show a SAML island inside my Win32 app. Let me run this, very quickly. And you will see how this is Win32. This is the default thing. That is the Win32 text block. And this is a text block from UWP SAML. Yeah, okay. So, you know what, the code you used to set that up seemed very straightforward, right? I mean, I'm literally reaching into the exact same APIs that I know already with UWP. And it's just setting that the content there. Okay. And the wonderful thing is everything is running in the same UI thread. It's fantastic. It's typically for developers. Oh my gosh. So, if you are wondering, all right, you are writing their code. So, but I really want to use the SAML market. Can I do that? Yes, you can do that. It's something that I am going to show you today because we are still working in the tooling, but you are going to, if you have a UWP control, that is UWP control. And with all your SAML content over there and your reference to your C++ project, you can use that. Means that you can write all your SAML market in the UWP control. Okay. Yeah, I got to see it. Yeah. Yeah. Now you got me. You're going to go the other way. That's going to be interesting. Yeah. So, the other way, what is the other way? It's time to call Win32 from... From UWP. From UWP. All right, we can have a very interesting conversation for about that for another day. Okay. All right. Good. So, let's continue a little more. All right. So, this is something that you as a C++ developer, you have to do it, right? So, you have to invoke your any desktop Windows SAML sort of object. You have to take care about the layout of things. You have to take care about the focus management. Oops, there is an infancy animation there. About the focus management, but what happen if you are a WPF and WinForm developers and you don't know any clue about what is an HWIN because you really don't need it, right? And you don't have also need to know anything about low level APIs. You just, you are in your happy world where you drag and drop control, write some code and everything is important. Everything's managed. Do the thing. So, why you need to just call desktop Windows SAML sort of API? We know that it's painful for you developers. So, we create a set of, this is the second set of component that is a set of wrappers that is going to help WinForms and WPF developers to consume the SAML islands. So, we are going to achieve in the Windows community a toolkit, a wrapper for the desktop Windows SAML source, a wrapper for WPF and other wrapper for WinForm. But also, we are going to wrap the more interesting controls that we have in UWP, like the map control, that in Canvas, something about the web view, something that is really complicated to, oh, it's not really complicated, but it's top of the request for our developers and we wrap into a WPF and WinForm controls. So, means that you are going to use these wrapper control as WPF control and WinForm control and you don't have to think about UWP at all. Sounds good? Yeah. Gosh, you're making it sound like there's a nice shim there that I don't have to even think about. It's going to cross the boundary for me. Yep. So, you're thinking about the Windows SAML, this WPF, this wrapper control for WPF and when we are talking about the airspace issues before, right? So, when we did implementing inside of this wrapper control, we are aware about when the host WPF application layout is changing. So, we need to communicate to the host and change the thing as well. We are doing all this kind of work for you so that you don't have to worry about that. And it's in the Windows Community Toolkit. Everything is open source. If something is not working for you in a way that we are thinking about, you can change it, right? Mm-hmm. Okay, all right. Actually, it's really complicated to get this wrapper control. So, it's enough. A lot of qualified developers can do it. It's not for the faint of heart. So, great. Let's continue a little more. So, what are you expecting to have in this Windows Community Toolkit thing? So, a bunch of new packages. So, one new package for the Windows Hamel Host. With the Windows Hamel Host, it's the wrapper for the desktop Windows Hamel source. This Windows Hamel Host is going to allow to you to put all the content, all the random WPF content that you want. Another package is about the, for the WebView. So, you can use the WebView control that we have in UWP, in WinFront and UWPF. So, it means that it's enabled to you that you can render, later on, finally, you can render HTML5 content in your application. And another NuGet package is a set of controls that is going to make simple for you to consume all these UWP controls, like the MapControl, MediaPrior, LMA and Canvas. We are still working in the SwapChain panel. Actually, you can see this wrapper control in the GitHub. And we are working as well in the text box for just to support this cooling fence about that you can ink with your pen in a text box in UWP, and you see this and very inking experiences, which is awesome. So, you are going to have all the things. We are really cheap, several things for support the 2018 October update of the operating system. And we are planning, working together with the Windows Community Toolkit guys, to chip in an S release of the Community Toolkit, the support for the new update of the Windows 10. All right, time for a demo. Oh yeah, always show me, don't just tell me. Here we go. Oh yeah. There's a question in the chat just asking, does the Zamo Islands work with F-Sharp? F-Char is a language for... I was thinking in theory yet, but I never created an application in F-Char. I never believe that this is an idea. So before to say something in theory, let me take note, I create a F-Char sample and validate and verify that this is working. Right? To make the mistake. And there we go. We actually have one of our moderators jumped in and provided a link to a project. Oh, that's great. Thank you. Thank you so much. I owe you a beer or whatever. All right. This is a, let me just clean up this a little. This is a WPF application. This is a Donut Core 3 WPF application. As you can see in my WPF application, double click is all doing almost nothing. Just have a label and a text box, but I have something called Windows sample host. Can you do me a favor and increase the font size to 16, please? Two, whoa, one 50. Yep, that'll work for you. Yep. Great. All right, so say that I was saying that we have this Windows sample host. This Windows Summit host is the wrapper that I was talking about. Actually, this is the namespace that I'm referencing. So if I go to the WPF application in the dependencies and right-click, manage new packages, you will see that in here I have a version of the Microsoft Toolkit WPF UI Summit host. This is a preview. Actually, I don't know the source code that I have in the Windows Community Toolkit and I created my own build because everything is there and just I'm testing the things from this build. Okay. Right? So adding this new good package, I have access to this Windows Summit host component. This Windows Summit host component have a property called initialize type name. This is the type of the user control that is going to host all the content. In this case, I say, hey, my user control is a UWP WinRT component green UI user control. And this user control is defined in a WinRT class library, which is this guy over there. This is a WinRT library. This is a UWP class library. Okay. So I can reuse this UWP library I consume in my application. In this UWI library, this, sorry, in this WinRT library, I'm using Windows UWI library. So this UWI library also has a reference to these auto box controls. Let me show you. In here I'm using the Microsoft UWI Summit, which is the new good package for the Windows UWI library. So this user control is not only using the inbox control, but also I'm using the Windows UWI library, which is a new good package with more controls. All right. So what is control is doing? Let me run the application. I'm running. Oh, I'm not in the same boat. I always forgot to deactivate for my demo proposal. Sorry, guys. It's live. Hey, this is kind of, you know, this is what happens along the way we find things. Oh, you know what here? Let me go show you. I got to fix this. Yeah. I'm expecting in some moment the window. I don't know. I still have more symbols. Sorry, I was debugging something before making this presentation. All right. Here we are. So we have this WPS application. This is the, all this app is a WPF in the top. You can find WPF content in here in gray. You can see all the UWP content, everything running in the same UI thread. So you can see some difference between the two platforms. So you can see the difference, for example, in this emoji. So WPS doesn't support color emoji, but UWP support color emoji. So which, all right, it's not something that is going to make to you to jump to the UWP platform, but it's cool. Are you kidding? I need my colored emoji. That's game changer. My kids won't talk to me unless there's at least a couple of emojis in those text messages. It's just some detail that I wasn't aware. Honestly, I wasn't aware about all this detail until I was starting to play with both then only at the same time. So another thing is about textbox as well. Textbox is something that is very frequent that you can use in your application. So when I write something, some random text, yeah, so you have this and you can write click and then right click, you can paste, copy, but look at what happens when you are running. You are writing something random. So happens that they say, hey, why are you writing? I don't have any idea. So you have the proofing, everything integrate. You have these beautiful experiences. You have, you can clear the thing. And also your textbox is working really well from accessibility from the default, right? This side of the textbox doesn't mix the accessibility requirements very well. So you need to make more space. And more stuff is about the contrast for the thing, how the focus is set up. There are small details that UWB platform are doing that we are not aware about that. And they are really important for today engaging user experience. I'm doing the performance of the user using the applications. So this is just two small details. In the top, in here, I have my navigation view that for demonstrate that you can use the Windows UI in SAME Island as well. And all of this is .NET Core 3. Nice. Nice, right? Wonderful. All right, let me stop that. Let's continue a little more because I want to be very, very, very clear about the roadmap, the things that are going to work, the things that are not going to be supported yet and we are still working because I believe that this is an important message for all the people. Roadmap. All right, so in the past, last year, we released a preview of the SAME Island, an alpha version just for anything that you can play with. In the next release of Windows, in 1981, actually you can right now play with the SAME Island with the insider builds. So we did a lot of work. We fixed space issues with pop-ups. We are making sure that we respect the DPI of the user. The user had different DPI. The island is already adapted to that. It's working with accessibility. If user are using narrator, for example, they can greet all the things in the visual free of the SAME content. We support the localization. We make sure that Qlient really is working. The keyboard accelerator APIs are working in SPETTE. We did a lot of work to make sure that this is really working. Things that are spent in order to work in this first release, well, connect the condemnation, something that we are not going to have enabled yet. The media player for the element when you click in full screen is not going to work. So the inking text boxes is not going to work. It's going to work just in some insider. So there is several things, several other things that are not really critical that is going to be out for this first version. But we are listening to the customers and our customers say, hey, SAME island is wonderful, but it is only going to work if I have my Windows 10 update to the version of connecting each one. So I won't really, really want to use that, but I need to just support for Iris 2 or all the version of Windows 10 at least. So yeah, we are listening. We are listening to you. And right now we are planning, we are thinking about, hey, this is something that we should do and we are investigating how we can do that. Okay. Yeah, thank you guys because the feedback we received for different channels, in this case it was a survey in Twitter, they give a very sense about what people were asking. So yeah, we are listening to you and we aren't reading your message. It's right. So this is the roadmap for the platform, but we have more pieces. Okay. This is the roadmap for the groupers, for this groupers in the Windows Community Toolkit. So the Windows Community Toolkit is going to be update in some point with the release of the Windows 10. There are going to be something about that. It's something that the day is still clear, but there is going to be some update. We are going to have a specific part of the groupers working in this update of the Windows Community Toolkit. The specific part of the groupers is the groupers that are working with the Donut framework. For example, this is going to be shipped in the next release of the Windows Community Toolkit. In October, no, October, November, no, I don't know the date yet. Something aligned with the ship, the final release of Donut Core 3, we, the Windows Community Toolkit guys are going to update the Windows Community Toolkit version 6.1, 6.2, whatever, with all the final support for some island for Donut Core 3, because it doesn't make sense to ship something that is in preview, ship something as a final release. So we need to go to the Donut Core 3 guys just shipping that platform. So we ship also the Windows Community Toolkit with that. Made sense, right? Yeah. In the future, yeah, we have more things to think about in the future, but we are eager just to listen to your feedback. We can change the backlog, depending on the feedback that we can see from the users. And the final piece for the roadmap is about the Visual Studio. So Visual Studio is going to be updated, it's going to be released in something April, I believe, right? So this is not going, some island support is not going to be there. It's going to be a little move to some update in the end of the year, 10th of October or more or less is the day that we are now thinking about. But yes, we are going to have support for a lot of the scenario. And this is the reason why I want to talk about some scenario that are going to be smoothly supported. I mean, they are going to have this streamlined developer experience, other scenario that is not going to have that, that are not going to have that. For example, if you package everything, you are creating a Win32 application and you package in MSAIX, package means that you have to create this unbox of security. You can package without creating this unbox of security. But you package your project, so the Visual Studio tooling is doing for you a lot of the stuff. It is resolving, it basically is creating an identity for the package. It is resolving the dependency with the third party controls. They are resolving the resources thing. Visual Studio is doing a lot of stuff and this is something that is going to be really smooth for developers in this first release. So, and package is something that, yes, this is possible. You can do a package application, but maybe it's going to require a little extra work for you. Just to have clear about the experience that you are expecting. The, another important point I want to talk about is about this kind of crazy combination that you can do between the host technology and the WinRT component, because it's a very complicated world. So, in the host part, you can have Win32, you can have a .NET. In .NET, you can have .NET Framework and .NET Core 3. So, let me classify the thing for Win32, .NET Framework and .NET Core 3. In, in the, this is the host, the component that you are going to put inside of Summit Islands, this third party WinRT component can be native C++ or can be managed, C-Shar or whatever language you choose. So, thinking about all this combination that you can do. So, there are some scenarios that are not going to be fully support. Just for example, if you have a .NET Framework application and manage WinRT component and you want to use this inside of Summit Island, the only way to do that is doing some kind of compilation work around. There is a lot of documentation, there is a lot of, there is some documentation there that is, is, is explained to you how to do that, but this is something that we are not going to support in this release. Things that are going to work really well. You have your .NET Core 3 application, you can reference a managed package, you can reference a native package, everything is going to work really well. And Win32 as well, you can create all these kinds of combination. The aesthetics in the, that you can find in the, in the cell is because it's going to work really well. Maybe there is going to be some caveats and the caveats is something that depending of how well we don't with the tool. So just to have a quick issue and be completely transparent about the thing that we are going to support and the things that are going to be supported. That's my sense. Yeah, oh yeah. Really, I mean, let's, let's break this down. We're talking about supporting brand new UWP technology on very, very old frameworks, not trivial, yeah, not everything's going to work. Sorry, that application you wrote in 1995 doesn't get all the UWP functionality. Yeah. That's okay. Yeah, but we try. Yes. I need to be honest, we try, we try. Oh yeah. Sometimes it's almost impossible, but we try. So that's it, this is all my story about Summit Islands. Oh my gosh, it hit the post right on there. Look at that time. Yeah, I'm ready to pay. Oh my gosh. There were a lot of questions that went by in the chat room. We called out a couple of them and the moderators have been handling them throughout the hour here together. I really like what we're doing here because the concept, the premise of the Summit Islands being able to take that modern technology, that modern look and feel and get it into my historical applications and take advantage of new user interfaces. New user experiences is tremendous. It really speaks towards not just a commitment to modernizing older applications, but getting accessibility baked in because you're able to use those new, right, and I, gosh, when you brought up Gaze, that really landed with me. That Gaze interface is something that it can't do with an MFC button control. You can't just look at it and have it click, but you can with UWP. Yeah. So, very cool stuff. Well, thank you so much. This is really good. Thanks to you. And yeah, I think we'll sign off. Thanks so much for joining us, Miguel. This is great. And we're gonna get ready for our next guest, James Montemagno. Thank you, guys. Bye-bye. Alrighty, take care. There we go. That should be just me. Hey, there we are. All right. My gosh. There's definitely something to be said there about Microsoft's commitment to having backwards compatibility, to being able to continue to use your tools, your features, your applications as you move forward, as you're continuing to use new versions of Windows. That backwards compatibility is such a commitment. So, and now I think we're gonna take another commitment step forward here. This isn't like, no. We're gonna show another side of this, how we can reach forward into other places with Xamarin. And we're gonna bring on up my friend, James Montemagno here. Let's see if I can call him up and get him into the mix here for this. And it's ringing. There's a thing happening. There we go. I'm gonna change things over to Mr. Montemagno. There we go. We're gonna... All right, can you hear me now? Oh yeah, I had you on mute on my side. Perfect. No, I have 18 different audio interfaces over here. ProStreamer Life, you know, I just gotta swap things around. ProStreamer Life, there he is. James Montemagno there to my right. So good to see you, friend. How's it going? It's amazing to see you as always. It's absolutely delight when I can spend some time with the .NET community. And of course, you, Mr. C Sharp, for it's himself. And I got the chat up here. Oh my goodness, a lot of some subs over there are too in the chat. It's been really fun to just have all this on in the background and watch and learning some new things as well. Oh my gosh, the number of things that I've learned, reactive extensions, a little bit with Prism. And then, right, knowing that those work on .NET standard interfaces means that I can take them, take them over to your favorite framework, Xamarin. Yeah. So I'm, as always, really excited to talk about mobile development and what we offer here, Microsoft, you know, coming from my long lineage of doing mobile, well, I've been a .NET developer for over a decade and doing mobile development with Xamarin for over seven years. So it was a, it was a framework and platform that I fell in love with. So I went to go work at the company and after the acquisition, I'm here at Microsoft and my entire focus is on Xamarin and building the community and great developer tools. So it was really easy, right? The story is simple. I knew C-Sharp, I knew .NET. I was writing WPF and WinForms apps and within a month, I was building iOS and Android apps and sharing code across everything. That's my story and that's why I love it. And you're sticking to it. Yeah, not going anywhere. I'm not going anywhere. Well, that's my story and I'm sticking to it, right? We still do it today and we have a, I mean, definitely a better story than what we had so long ago in the ecosystem around everything that we're building, the amazing libraries that you showed off. So you showed off earlier, you know, Prism, Jeff was talking about Refit and reactive extensions, reactive UI. We're talking about, you know, your different DI containers. All that stuff works with Xamarin because it's just .NET. And that's kind of the story I wanna tell and show off and also do some porting of some code. I see some porting has been a fun experience. So I wanna take some WPF stuff that I've done and port it over to a mobile app and kind of talk about what is different when it comes to mobile compared to a desktop application. Cool. All right, do you wanna share your screen and we'll get that up and running? I do, but I gotta do one thing first, Fritz. You know what I gotta do? What? Gotta pour some coffee. Oh, gotta pour some coffee. I stream, of course, on Fridays and I always brew some fresh coffee. So for you good, sir, I made some fresh coffee. We're just gonna pour it in. It's still steaming out of the Zojirushi. You do that, have some coffee. Absolutely, that's a Seattle thing. I'll enjoy my energy beverage of choice. I like that. Well, don't forget, gotta get that hydrate bot, drink some water. The hydrate bot? Sure. All right, so let me share my screen and you should be able to see it any time. It's a beautiful Windows 10 default. There we go. All right, I wanna set kind of a base level for everyone, though. Let me minimize you out of here. I was gonna say, get rid of me over there. I'm already down here. I don't need you, get out of here, Fritz. That's right. Let me go ahead and I only prepared a few slides and then we're gonna go into code and stay in code till the very end. All right, sounds like fun. Is that okay with you? For this time only, all right? And I'm gonna make sure, I've made sure I'm recording and we're gonna have this video afterwards, James, okay? Yes, I'm actually uploading our other workshop video except for it's like eight billion gigs. So I have five makeup internet and it's taking forever. I'm not doing it now or else this would just cripple, so. Yeah, that'd be terrible. Let the folks at the office take care of that. Yeah. So yeah, so what we're gonna do is we're gonna do mobile development with Xamarin for desktop developers, how you can bring your existing XAML, .NET skills, everything that you learned today and what it means, like what is Xamarin? How is it defined? How does it fit into .NET? That's my email. People can email me there. It's a special alias that I have that skips all of my rules and goes into my inbox. So like even if Fritz emails me, even to this, it like skips but everybody else you have special access to my inbox which is pretty sacred. So if you have any issues, any questions, anything tweet at me, email me, that's my email, Mots at Microsoft. Because folks like that Hanselman guy when they send it to you, it goes into the trash, goes into spam immediately. Auto archive. Auto archive, there you go. Keep it around, archive though, not don't delete, that's the key. That's the key, that's the key. All right, so we wanna build for everything. It's sort of what we've seen a little bit today talking about desktop. So whether you wanna build desktop apps, web apps, cloud apps, mobile apps, gaming apps, IoT apps, AI apps, all the apps, there's .NET. It's there, it's there for you. It's, yeah, .NET, it does a little bit of everything. Does a little bit of everything. We like to call it your platform to build anything. And traditionally, I think I always thought of myself as coming to .NET and building Windows applications. And then as things grew, I was building web applications. I was deploying into Azure. I was running .NET code on a Raspberry Pi. I was building, you know, TV applications and putting stuff on the Xbox, it was crazy. Building applications for a refrigerator. And a toaster. And a toaster. Well, the refrigerator is a thing, all right? It's a thing, all the things, all the things I say. So, you know, Xamarin fits in, we always think of it traditionally as mobile, but I kind of wanted to find exactly what Xamarin is. So, if people are like, what is this Xamarin thing? I'm gonna tell you what it is and all of the frameworks that live on top of Xamarin. So, I define Xamarin. This is my new definition that I agonized for weeks. Let me hide us there so folks can read it. There you go. So, it is an open source, a mobile platform from Microsoft for building modern and performant iOS, Android, macOS, watchOS, and TVOS applications with .NET. That's like butter. That's like, it'll do a little bit of everything. Yeah, I kept adding on all the platforms. And the beautiful part here is that at the same time since it's built with .NET, you can also share your core source code with any other .NET application. So, whether you're building a desktop application, a web application, an IoT application, anything else, since we fall into .NET, and we adhere to the .NET standard for all of these applications, you can share code everywhere. So, that's what's really, really important is this is what the Xamarin platform does, but we're part of .NET, which means that we do everything. Oh yeah, a little bit of everything, which means that just being a C-sharp developer means you're now able to go everywhere. Yeah, absolutely. And this is just a core Xamarin platform that lives on top of a lot of open source lineage that goes beyond that. Like, Brave is asking in the chat about Linux. Like, we do have a story for Linux, too, with the Mono project and building things, and there's a lot of great community efforts there, too. So, not to be that there's other things that we do, but this is my initial definition that I'm sure will transform over time. Oh yeah. And, you know, it's used by tons of developers and tons of enterprises all over the place, including Microsoft. I was really pleased to put the Microsoft logo in here. And this is all sorts of different companies using it for all different sorts of ranges. And they're not only building with Xamarin, but with .NET, with ASP.NET, with Azure, and all different sorts of services. So, there might be one company that may, you know, think of like UPS, it's got a package earlier, which is awesome. They use it whenever you scan a package or Cincinnati Children's Hospital, where they're making it easy for parents and children to connect and get in and out of the hospital easier and building these really awesome mobile apps. So, really all different verticals. So, we've grown, we've been around for a long time, in general. So, you know, like I said, I've been building for over seven and a half years, so really stable platform. So, we're gonna be building some apps, we're gonna be porting some code, but Fritz, I need to tell you how things are architected. How are we gonna build these things? What does it mean? I need a little bit of help with that. I mean, we already did this once, but the hundreds and thousands of people watching, they need to know how to solve them. Millions of .NET developers out there that are watching right now. Here it is. Super simple. Okay. You wanna build some projects. I'm gonna focus in on iOS and Android, just for most of the time, and then I'll put like .NET everywhere and it's all the .NET platform. So, everything we talked about. Well, you're gonna focus in on iOS and Android as the target, but macOS, the watchOS, those are other ones that could be in there as well. Exactly. Those are all target head projects, if you will. There, here, let me put this back up. There we go. Now, we're part of the architecture. Yeah, there we go. Yeah, so we're part of the architecture. You got a little Fritz, a little Mots in there. And we think of it like you have iOS, Android, and then any other .NET application, whether it's a WPF application, you have a WPF application, ASP.NET, you're building things in C-Sharp, maybe F-Sharp, maybe BB, all the languages. I picked C-Sharp, that's my favorite language. And these are head projects where you have access to all of the platform code. So, you wanna access something in the file browser or do camera control or something like that. That's that core code. But the unique part about Xamarin is that every single bit of it is in C-Sharp and .NET. So, I'll tell you a little bit more. And then the backend part of it here is all about creating a shared C-Sharp code base. So, inside of there, you can have as much or as little as you want, is business logic, platform APIs, and user interface controls. And again, you can have shared user interface or not shared user interface. And we're gonna show you how you can lift and kind of shift your WPF apps over to iOS and Android, which is pretty cool. And everything compiles on into native apps at the end of the day. So, in general, everything in that shared C-Sharp part right there is just a .NET standard library where you're sharing just a bulk of your business logic and additionally, platform APIs, user interface codes. But that's other stuff too. I'm talking about like unit testing, UI testing. Like those are all just shared common chunks of functionality because an app is more than just what the user sees. It's all of these services, all this stuff living in Docker, all this stuff, right? So, what we often see for like a Windows desktop type of experience or anything Windows, that's because we have like .NET. Like these are .NET, namespaces like system IO, link, XML, core, numerics that we know and love. And when you wanna develop for maybe it's WPF or UWP, you get the SDK and you access the specific APIs for that platform. And like as you would expect and hope when you wanna go to some other .NET platform, such as iOS and Android now, you get those APIs too. So, here when we go over Xamarin iOS is the host framework that gives you all of .NET basically at the core of it that can be run on our .NET runtime running on iOS that we developed to give you all of that stuff in gray. So, all of those different namespaces, but then up top you have all of your iOS specific APIs. This is literally five of about 10 billion, but you kinda get the point that you have access like SiriKit, ARKit, Core ML, MapKit, UIKit, all of the different things that Apple does. So, we have all those and the same thing for Android. You get all that .NET goodness on the bottom and then whenever you want to, you can go and tap into the picture and picture APIs or geo location or NFC or fingerprint APIs available on those platforms. So, I think that's like something really unique is that here we're accessing all of that. Notice on the bottom there, everything is accessed in C sharp. You're not writing Java code. You're not writing Objective C or Swift code. You can bring those libraries into Xamarin, but at the core developers don't really need to worry about that when they come to Xamarin and seven and a half years, I maybe thought about that code like once or twice ever and it builds 80 applications at this point. So, very little. Yeah, gotta crush that code. Yeah, it looks like we're getting a little bit of a bandwidth issue on your side. Yeah, are you seeing stutter or what are you seeing? Stutter and a little bit of down quality on your video. There, it's coming back. Your camera, yeah, your camera started getting a little fuzzy there on me. We're good. Okay, much better. Okay. Okay, so the architecture is here, right? This is the same slide that I did and here's a bunch of pretty photos, bingo-bango. But I wanted to talk about what is inside of the shared C sharp logic and how we're enabling you to access more of those platform-specific APIs. So, the business logic part, so the first bullet point there, Fritz, those are all your models, view models, Rethyl service calls, things that are just .NET code. And then you have platform APIs and user interface. So, for platform APIs, those are all those top-level things, those fingerprints and SiriKit and Core ML. And if you wanted to, you could go write that in C sharp. But what we did instead is we abstracted tons of those APIs into a single library for developers. It's about 30 to 40 APIs that we call Xamarin Essentials. It works across iOS, Android and UWP. And what this does is it gives you things like Flashlight, Clipboard, Battery, Geolocation, Gyroscope, all these APIs into a single library. So, when you click File New, you got all .NET for your mobile apps and now you have all these great libraries. So, you don't need to go learn how do I do a compass on iOS and how do I do it on Android? Learn those APIs, you have one API. Yeah, that just makes sense. That's right. Give me just that thing and then you .NET, you common language runtime. Go figure out how to do that on that appropriate device. Yeah, and just like we do that kind of automatically for you for some of the .NET APIs, like SystemIO, right? Think of SystemIO, where that's writing and reading from disk and those APIs on iOS and Android and Windows are completely different, but SystemIO abstracts that for you, even when you're developing with Xamarin. And that's what Xamarin Essentials does for things that are not in .NET, basically, because there is no gyroscope or battery for device information in .NET, in general. They're in the platform APIs. So, that's what we do for you. And then, on the UI front side of things, if we look at this infrastructure now, this expands out. So, instead of having your shared C sharp, now you have Xamarin Essentials and in the bottom we have the business logic in UI. And the UI part is unique. So, at this point, you can go write iOS storyboards and Android XML and tap into the native APIs, but we've also abstracted common user interface controls into something that we call Xamarin Forms, which works across iOS, Android, UWP, Mac OS. And there's a lot of community supported front ends, if you will, for this, such as Tizen and there's some Linux support and WPF support and I think there's WinForm support at this point. And it's just a common API for user interface. So, it gives you all sorts of things, like images and buttons and labels and list views and all that jazz. So, that means now we take your entirety and we lift it up once more and say, listen, you still have access to everything in iOS and Android and .NET for all the different platforms, but here now we layer on your shared business logic, Xamarin Essentials and Xamarin Forms and you can pick and choose as much or as little to share across each platform. On average, our developers share about 80% of code, sometimes higher, sometimes lower. It depends what you're building. Makes sense. Look at all those boxes. I spent a lot of time on these animations and boxes. Dude, who doesn't love boxes? I was up till 2 a.m. with Galloway working on the slide deck. Working on boxes. Working on boxes. And that's it, that's my presentation. Now we have kind of a base level of sort of where Xamarin fits, hopefully. Do you have any questions at all? I know I'm reading the chat. I have the chat right here, so. Yeah, we're keeping an eye on things over there. You have a slightly different display than some of the other folks that we've had on, so I'm trying to get that squared up a little bit better here inside the window. A beautiful 1080p display? Now it's come through at a slightly different shape from other folks. Interesting. You're gonna change my resolution? No, no, you're good. I prefer what you've got. But I'm making sure that I cut out your task bar at the bottom, which gives me a little bit of black there at the bottom, but that's okay. Got it. I can deal with that. So let's go ahead and we'll shut down PowerPoint. We're gonna save as much RAM as humanly possible here. So I'm just gonna open up VS 2019. Hey, Liz, welcome to the chat. I just like to welcome people when they come in. Hey, Liz, good to see you. So I'm just gonna walk through a file on you. I'm gonna be using 2019. We're going rogue like Ryan did earlier. We're just gonna go for it. It's been working great for me, so I'm pretty excited. So this is the preview, because we're gonna be using some .NET Core 3 with WPF. Which seems to be a trend on here. Oh yeah, that's a thing. It's a thing. I'm really excited about it. I think I've been excited about a lot of things in my time here at Microsoft, but I'm really excited for that, so. Oh yeah. So here's all my new projects and what I'm gonna do is just kind of, you have all the different workloads and when you tap down on mobile, that's where you're gonna find all the Xamarin stuff. So notice that when I'm here, that we have things like Android applications, iOS, Android Wear, WatchOS, specific libraries for iOS and Android TVOS. We have all these extensions for iOS applications. So if you need to build an audio application or broadcast to other applications, you can do that. If you need a document picker, we support all of the native capabilities, just like if you are writing it inside of Xcode with Swift or Objective-C, but you can do it in C-Sharp. So there's like a photo editing extension or share extension. So we have all of those things. So when you think of an iOS application, it's actually more than the core app. If you're inside of your iPhone, you pull down from the top, that is an extension and that's what you would build right here. And I think it's a really important part to talk about Xamarin is that we support like the entire stack for cross-platform and for these different things. So, all right, let's just do File New here and walk you through this little app 24, perfect name for an app and- Because the first 23 weren't anywhere near good enough to ship. No, they were not. No, 24, I'm feeling pretty good. Although lucky number 25 is my lucky number, so it's close, off by one. Did it start at zero or one? That's the question. Hmm. It is the 24th app. It started at one. Because all good. It's the 24th app. Yeah. So what's really nice here is that we give you a bunch of great templates. So master detail will give you like a flyout navigation, tabs, give you tabs. Xamarin is a new template that we released which gives you a new navigation hierarchy. So instead of trying to navigate from page to page, you define your entire application in a single XAML file and that's coming in Xamarin Forms 4.0 which is pre-released right now and then there's blank app. But I wanna make sure that we see something here which is you can include an ASP.NET Core web API project with a single click on these things. And yeah, what's nice about that is a lot of applications that need some data and ASP.NET Core is great, especially if you're developing on Mac or Windows. Everything I'm showing you here you can do on Mac OS with Visual Studio for Mac. And what's cool is that you can run your ASP.NET Core web API on Kestrel, which is like a different flavor of running your backend like IIS. But what's cool about it is that you can just debug locally against your Android emulator which is super cool. But let me spin up a file new project and just kinda walk through a high level. So when we do the porting, then you'll kinda see how things are gonna look and feel. So this is gonna give me iOS project, Android project, a.NET standard library and my core app that I have backend so I can share some user interface and install some libraries. And my surface book too is chugging along. Okay, great. And perfect. So what I like is when you do file new is that you get an Android application head, an iOS application head and then a.NET standard library like I was talking about. So what's really cool here is that this gives you sort of everything that you need to get started building an application. So let me go ahead and it's going to be restoring some NuGet packages. Give it a second here. There we go. So what I'll show you what you actually got installed to zoom back in here is you have dependencies. So here's SDK and when I drop that down we get.NET standard library. We get NuGet packages. I have Xamarin Essentials and Xamarin Forms which are there. But I still have Android and iOS projects in here. So if I need to add Android libraries, I care of the support libraries or I need to go in and write specific code for Android, for instance, I can come over here and double tap on my main activity. And as you can see, I'm using Android namespaces here. So there's Android runtime views, like this is the Android code that's here. But since this is a Xamarin Forms based application, my app actually starts over in this shared.NET standard over here, which is this application class that has a main page. So I'm just gonna go and open up a main page. This structure is gonna look pretty similar to any WPF UWP developer where I have an app XAML with an app class behind it. And I put my application resources in it, cool. And then over here, I have a main page where I have a content page, which is a Xamarin Forms content page. I have different stack layouts and labels that are inside of here. And I have a property grid, I have a toolbox. So if I wanted to over here, I can go ahead and put an entry over here and put that in there. It goes on a new line. Now I have an entry, if I want a progress bar, now I got a progress bar, and I can start to add these controls in there. And what's nice is that I have my Android project set as the startup. And what I'm gonna do just to save because Skype is gonna kill it, we're gonna run this on my physical device because the emulators do take a lot of RAM. So we're gonna shut that down just for now. I'm keeping an eye on chat. We have a couple of our friends have popped in chat here. There's Ramblin' Geeky's another member of the LiveCoders team, right? We write code live on Twitch when we're not here on the Visual Studio channel. And Dot Morton is here and says, I'm curious if the size of someone's microphone says something about that person. I don't know what you're talking about. I believe the size of the microphone stand tells you audio quality of that person. Oh my gosh. I hope you've heard that throughout the day today. I was on some Teams calls earlier and everyone was like, this is the best, like the best audio I've ever heard in my life. I'm like, oh, just my podcast setup. So, exactly. What I did over here is I simply went in and up top, you can see I have my Samsung device plugged in. So inside of the toolbar here, it actually says, hey, I'm debugging this application and do you wanna just debug it on your Android device? So this is going to compile. What's that doing up there? This is gonna compile my Android application here locally on Windows and then start a debug process on to my Android device that I have plugged in. So here I'm just doing a screen mirror here of my Android device, which is running right here. And all we're really gonna see is like some entries, this progress bar and this label over here. That's my goal at the end of the day. So this is gonna compile. Now, I will say my compile will take longer because Skype is probably crushing my machine right now. And I should probably also close Chrome. Let's get rid of that. Let's just close all the things. If I was really smart, Fritz, what I would have done is I would have just used my Elgato capture card and we would have captured over there. And then I have my main machine. I didn't think about it. And I was like, yeah, Skype, it'll be fine. We tested it yesterday. So what are you gonna do? But yeah. Yeah, the number of machines that you end up plugging together in order to make a really good stream. Yeah, it ends up being this board, this spider web of cables. It does, yeah. And even here, I have like multiple, multiple, multiple keyboards, multiple mice, everything, which is funny because that's how I actually stream is with that. But we'll see. I was watching Brian. He was running into some issues earlier. And I was like, you know, I should probably actually set up multiple. I should do this, but then I didn't. So there we go, it's deploying. Perfect. So, okay, it's deploying, it's waiting. So what we'll see is the output here. So a few things happened on your first deploy. So I might have deployed to this device in a while. So it will check to make sure you have like Android dependencies installed. It will make sure that you have our runtime installed. So we're not doing like a full compilate. We are doing a full compilation of your app, but we're not doing a full package. So here it's going to go and sign our application, zip align it and then start this debug process. So you can see Visual Studio on the bottom left. Like it's like starting debug, it's doing stuff. It's about to change modes and boom. Now we're into a debug window. And we're going to get a beautiful screen with a progress bar that says welcome to Xamarin Forms. Boom, that's about it. That we would expect. So it's very impressive. Anyone could have done this at home. But what I think I like over here is that now I can come over into iOS. And I know I don't have a navigation bar over here. So what I'm going to do is I'm going to, on the stack layout, which is going to stack things like a stack panel, I'm going to give this some padding. I'm going to say on platform and show off something unique. I'm going to say on iOS, let's give this a padding of 40 on on Android. We'll give it zero. So inside the XAML here, I'm going to say on iOS on Android do something different. And what we're going to do now is we're going to go ahead and pair to my Mac, which is sitting off to the side. So to deploy and debug iOS applications, you need to be connected to a Mac because Xcode and the simulators and the build tool chain all live there. So I have two MacBooks here. One is set up for preview and one is set up for normal versions. Now, if you have Visual Studio for Mac installed, it'll just connect and be good to go, but this screen did a bunch of things right there. It just did a bunch of things. It checked the version of iOS you have, our build extensions, our SSH client. And if those weren't installed, it would install it for you automatically, which is pretty cool. And I want to show you something up here, Fritz. Please. So now I've set iOS as my startup target. Oh, wait a sec. Look at that. You're just used to any CPU, but no, no, no, not with Xamarin. You have iPhone and iPhone simulator. So here are every single one of my iOS simulators that I have on my Mac. Oh, okay, okay. And does it have my iPhone 7 Plus there? Yes, right here. It has every single thing. iPhone 7 Plus, 8, SE, XR, everything. All right, all right. And now what's really cool though, is that these are different versions. So this is my old machine that I've been developing on since iOS 8, when I got this MacBook, adorable. So I even have older simulators here. So I have 9, 3, 8, 4, 12, 1, right? And these are, Adam asked like, what are these simulators? These are the actual simulator images that live over on my Mac, but we are communicating over SSH to talk to the Mac to say, hey, what simulators do you have that I can deploy on? So now when I actually go and set to deploy this application, it's gonna communicate to my Mac on my network. It's gonna compile as much as it can locally. And then it's going to attempt to figure out how to automatically deploy this application and package it up and deploy it to an iOS simulator. Now, what I like though, and what you're seeing literally in front of your eyes is that we have built a remote iOS simulator for Windows. And what this does is it takes that simulator that's sitting over on your Mac and basically over the network, sends all of the images and touch events really fast to your Windows machine and back and forth to your Mac. So it's like constant communication, which I'm sure is great for the Skype chat. Yeah. No, actually it's not, it's going well here. So boom. Yeah, your video is very stable right now. You know, when you have five megs up and you're paying ridiculous amounts of money, which is pretty good. There's a lot of people that have worse internet and pay way more, so I can't complain too much. So yeah, boom, here's my beautiful user interface. Look at that, I did it, boom. What more could you ask for? A beautiful, stunning iOS application, yes. Now, notice here though that when I bring up the Android app, like we get different look and feel because they are the native controls at the end of the day. So that's really cool. But I'm in a full debug session, I can stop debugging, my iPhone simulator's still here, it's nice and snappy, I have my other apps that I have. And let's do something interesting, right? So let's do like X colon name, we're not gonna do any MVVM yet, I'm just gonna say like entry tweet and then let's do a button here and we'll say X colon name, we'll say button tweet. And then I'm gonna say text equals tweet, okay? And what we can do here in the placeholder, we'll go ahead and minimize this output, we will say tweet stuff, right? So there's like we're building out a beautiful application. So, so far I have an entry, I have a button and what we'll do here is we'll add a clicked event. And what I wanna show is that a lot of these things are gonna look very, very, very familiar for anyone that's developed, you know, WPF or any other XAML based application. There's entry, which has this as a button. Of course here, I have other things like a command, a command parameter, all of those things, right? So now what's cool is I can go into my code behind and I have this button tweet that I just selected. And now what I can do is let's say I want to share something out, I wanna tweet something out. So now what we can do is we can come in and say using Xamarin.Essentials because there's a share API in Xamarin.Essentials. And what I can do here is I can say var tweet and I'll say entry tweet.text. So just access that control. I'll say if you know string.is null or white space which is my tweet, let's return. Else, let's go ahead and mark this as async because I know that this is something I have to await on. And what I wanna show you first is what would happen if I just typed in Xamarin.Essentials is I would get all of these APIs that are built into Xamarin.Essentials like battery, clipboard, connectivity, device information, email, flashlight, geocoding, all of those things, but I'm inside of shared code which is really cool. Oh yeah. So I'm gonna use this share API and say request to share. I'm gonna give it a new share text request because right now we support text but we're adding files to share documents to other applications too. That's the next on our radar. So here I'm just gonna set text. I could also set a URI inside of here and I'm just gonna give it the tweet. Cool. So now what I'm gonna do is simply redeploy this. Now the iOS simulator doesn't have Twitter on it. I could copy it to clipboard or do some other stuff. So I'm just gonna redeploy it to Android because I've installed Twitter on here already come using my actual physical device. So this is gonna compile up my application just my changes and start to deploy onto my device. And I wanna show you that I just hit F5 and before we had to wait for that first compilation file new and look how much faster it's already deployed. Like we worked and spent a lot of time where now I'm back into my application in seconds and not minutes, right? And I can write awesome he is eating stuff. Hey. Perfect. They can't hear me. I muted going out. It's only coming across Skype to you, all right? So I just read some stuff in here. I didn't have lunch today, man. I've been hosting this all day. Yep. Okay, so we're gonna tweet this out. And now we get these different dialogues on here and you can see that I can tweet and I can send it to Skype, to Gmail, to anything. We're gonna tweet this out. There we go. And I'll just go ahead and tweet that out. There we go. I just literally tweet it right now. You're killing me. There you go. But literally. There it is. One line of code. Boom. And if I ran that on iOS, I would get the native shared dialogue and I can do everything. So super duper cool. All right. That's the basis. All right. So what I did, let's recap. Built an iOS Android application with C-Sharpen.net. Have access to all the APIs. I'm using shared user interface, shared business logic, and accessing platform APIs without ever having to leave Visual Studio 2019 for both iOS and Android, onto my device, onto an emulator or to an iOS simulator. Boom. People can go to twitter.com slash James Montemagno. That's what bizcat asks in there. So that's my Twitter handle. I just tweeted it and you can retweet that. And I've, yes. I've retweeted your trolling here. I tell you here. Just for that, I'm gonna link my tweet. Not yours. Oh, I see how it is. Oh, and Visual Studio is promoting it too. Oh, I see how it is. Boom. Oh, you know what you get for that. I'm gonna give you some. Mucha is gonna come after you and she's gonna tell you what's up. Okay. Ridiculous. See, for instance, we have a lot of fun here. I like what's happening here. Okay. So let's close it. There's my app. Now, the other day I was building on my stream a brand new application that I wanted to use with .NET Core 3 for WPF. So inside of here, what we're gonna notice is that I have the .NET Core, it's called My Stream Timer. In fact, before I go into it, let me just run it. Because as a streamer, we always have this countdown at the beginning of our stream to say, hey, we're finishing our coffee, like give us five minutes to do stuff. But we don't want it to be longer than just a few minutes. When you go into somebody's stream and it says, all right, we're gonna start in 35 minutes. I'm like, what am I doing here? What am I doing? And there are some really cool applications, but there's not a cross platform one that I know of. And the one that I use snaz, which is awesome, does like everything under the sun. So I wanted a simple count up, count down. Uh-oh, your network's going on here, buddy. Uh-oh, James? Oh, I'm losing you. You're coming back. You're new. We're coming back in time. I'm gonna, we're waiting. Come on back network, come on. Now I just pulled his video just so that it wasn't all scrambled and he was sitting there making an ugly face. Oh, do you want me to try to call you back? Am I back? I think you're back. You sound perfect, by the way. So. Thank you. Do you want me, I can turn off my video if you want me to. Maybe that'll help the bandwidth. Oh, there it comes. I think we're good. I got your camera. Turn off the camera. Yeah, you shouldn't have camera coming from me. No, I don't have you. Oh, there you go. You're back crisp again. Comcast, I will say I was a little nervous. Last night I tweeted out a photo, literally Comcast at 1.30 in the morning. They're like, just schedule maintenance, shutting down your internet for an unspecified amount of time. Thanks. Thanks. What? So, yeah, so who knows? You know, that's what $75 a month gets you. All right, so here's my timer app, right? So my entire goal was to create a Donut Core application so this could run on every single version of Windows. And I wanted to port this over to Mac with Xamarin, but I figured, why not start the process early and do this? So this is my WPF app. I'm using some cool stuff like Maw apps, the Metro theming, I'm using some icon packs, and I'm using some MVVM stuff. So when I come in here, I hit start and it starts a countdown timer. And this actually outputs it to disk. So I'll show you what this looks like on my GitHub. Let's go over to my GitHub account because I had it open earlier. Do, do, do, do my stream timer. There it is, there it is. So what it does is it will output it to a file and then an OBS or Streamlabs OBS or any other tool. You can read that in. So it has a nice little account down timer. That was my entire goal of this application. Or you can stop it and you can count up and you can say, I've been streaming for five minutes, six minutes, whatever, and you can copy this out and you can click this little button. And then this is when it's done, it will say whatever this finished text is. And this is my V1, I'm gonna get a lot better on it. So this app though, I structured it in a way that I feel many developers structure it, which is here I have a WPF app. So this is a .NET Core 3 app. So here we can see it's a .NET Core WinXC uses WPF. I'm actually reusing my own MVVM helpers that I created like for Xamarin application and has some base view models, commands, things like that in it. I just reused it. And then I have a single project reference to this .NET standard library. So here I'm not using anything Windows dependent. I'm using my MVVM library, which I've used in every Xamarin app I've ever built, but now I'm using a WPF because it's .NET standard and just works. And I'm using .NET standard. Inside of here, I have my own little service container. So I'm not using Unity or dry IOC, I have my own little IOC container so I can access the clipboard. But most of the work comes from this timer view model. So what I want to kind of show is that this looks very similar to probably a lot of normal types of WPF for anything XAML based before is inside of here I have this like base view model. If I peek in, this is this like observable object which I'll peek in. I notify property changed and I can raise events back and forth. So Xamarin Forms has a full MVVM framework built into it just like WPF does. So I have a few things like a start stop command and I have a copy file command and I'm using a system timers timer to count down. I just have some simple settings that I data bound to. I have a is down, is up, how many minutes you want, the current output that you want, what you want to say when it's finished, what you want the file name to be, so just properties, nothing fancy over here. Where I want to output the file to, so what I want that to be. And then I have a little command or a little string that I do start or stop and I toggle those. And then over here, what I'm using to like copy a file is I'm using environment variables for a special folder for my local application. I use system IO path to combine those files and then I use a little clipboard through my interface to copy to clipboard if it exists. So here on WPF, I have clipboard.setText for instance, which is coming from system windows. So inside of here, that's super nice. And then I have a start stop little command that simply comes in, save some information, starts to write to disk. And then whenever the time elapses, it simply does some quick math, says end time minus state time now, does some string formatting, bingo bango, we write some stuff to disk and we're good to go. So let's say we wanted to port this over to Xamarin. Well, we got 10 minutes left, so let's see how much work we can get done. Hang on, hang on, hang on. You're gonna take this from one.net flavor, .net core three, the latest, the greatest, the preview, it's not fully released yet, and WPF. And you're gonna get this working in Xamarin so that I could run it on macOS or I could run it on a tablet. Yeah, correct, yeah, that's correct. In 10 minutes or less. Well, I haven't done it yet, so we're gonna find out. Okay. Yeah, I think we can do it. I'm fairly confident in- If anybody knows how to do this, he's right over there. I think it's gonna happen. All right. So I'm gonna create a new folder here. Here, I'm gonna get out of your way here. Let me, there we go, now I'm out of your way. Get out of here. All right, so I'm gonna create a new folder called mobile and we're gonna add a new project. And just like we did before, we're gonna add a new mobile app and we're gonna create a blank app again. So this is gonna be called my streamer, stream timer, .mobile. Is the project name. Boop. And there we go. We're gonna create a blank app for iOS and Android. Hit okay. Now the best part here is that I'm not rewriting my WPF app. My WPF app stays exactly the same. It doesn't change at all. It's exactly what the UI is using my apps, using everything. I'm not like rewriting the WPF app. I'm gonna leverage everything that we wrote earlier and bring it into here. So let's organize these a little bit here. So it's gonna restore some new gets over there. There we go. And then let me go ahead and throw some mooches in the chat so people wanna find me. There we go. It's gonna restore some new gets just like we did before. And I'm gonna go ahead and make sure that these move into the right folder. So now what we have is a mobile app, mobileapp.net standard library, just like we had before with Xamarin Forms, M-I-S-D-K. Boom. Now we wanna bring the shared library, which we had earlier. All this code that I'm running over there into it. So we're gonna come in and we're just gonna add some references. So I'm gonna say my shared code, hit okay, boop. Now I'm gonna come into my Android and iOS project and do exactly the same thing. The machine is gonna let me right click, add reference, shared, boop. All right. Then I'm gonna come into iOS, add my reference, shared, done. All right. So now at this point, what we need to do is we need to migrate some of our user interface over. So this application was pretty custom. So if I go into my main app, my icon packs. Uh-oh, uh-oh. There went the network. Oh my gosh. It finally took him down. I'm just like, I hear you perfect. Oh my gosh, and you're back. I'm waiting for the video. I have to turn off the camera. Yeah, it's the camera. I'm gonna, let's turn off the camera. Hey, there, it's just me now. Now I'm running things. Do you want me to start and stop sharing my screen? Oh, no, you're good. I can hear you great now. Oh, okay. Fantastic, and yeah, let's try without the video for a little bit. Yeah, let's do that. It's really odd that the video, whether you're using Skype or Teams or Slack or OBI, like it just, it takes a lot of horsepower for some reason. It does. All right, so here's what I'm gonna do. A lot of these things are similar, but a little bit different. So we're gonna port some of the code over and what I'm gonna do is, I'm just gonna copy and paste code and we're gonna fix it up and see if I can do it. I hopefully, I did not, I didn't build this user interface with this intended by the way. So this is like a new experiment for me. Like I'm literally doing this for the first time. So we're gonna come in and we're gonna first do a scroll view because maybe we have a very small phone. You know, I can't really control the window size. So I can't do that. Now I'm going to go ahead and paste this in and things are gonna get very upset at me all of a sudden. And it's gonna say, look at all these squids. These things don't exist because these are WPF controls, but some things do exist. Some things do exist. It's okay. Grids, okay. Sure. Grids exist, okay. We're gonna delete this little border that I had before. And we're gonna reuse everything here. Now we do have a label, but it's not content. It's text and it is horizontal options. And it is start. There we go. IntelliSense helps us so. Now we don't have a border, okay? But so for border, I was just adding some margin, like some spacing around it. I could get rid of this, but I don't have enough time. So I'm just gonna slap in some grids inside of here. As one does. As one does and put some padding of five, okay? Okay. Don't judge, don't judge. No judgment. This isn't HTML. Tables in HTML, as we know, have been banned. No, I can't. There we go. So we're just gonna put in some grids in here. There we go. I'm gonna put some grids in here. Yeah, we're just kind of bopping along. There we go. There we go. This looks good. We have another grid in here. There we go. Right, this is gonna get compiled out and nobody's gonna know that it's a grid. They won't feel that it's a grid. Now we super optimize it. Yeah. I do this. Where those HTML tables will be the bane of our existence. Forever. Okay, so what else do we have going on here? We have stack panel. Well, that is a stack layout, very close. Now we don't have radio buttons and that's okay. What we're gonna do in here is we're gonna put a switch. And here we're just gonna say is toggled and we're gonna say binding is down. So if the switch is on or not basically is what we're gonna do. So we're just gonna kind of clean that up a little bit. Get rid of our radio buttons. Make it a little bit more mobile friendly because switches are a little bit more common. We have a label in here. Again, we're just gonna say tax. There we go. We'll say horizontal options and we'll say start. I guess it's actually end. There we go. There. Now numeric up down that is coming from mall. That's a custom control that doesn't even exist in WPF. But over here, we actually have something called a stepper. So that should work for us. Stepper is the Xamarin control. That is the Xamarin control. It should allow us to step up and step down. So we'll say horizontal options and we'll put it at the start. All right, label again. Text and horizontal options. End. So we're just kind of replacing right with end basically text box. We saw earlier that that is called an entry. Text, binding, boom, it works. Again, we'll put text in here and we're gonna go ahead and just copy and paste this over here, boom. Awesome. Text box again, this is gonna be an entry. There we go. And label, we're just cleaning up some code here. Text, there we go. And an entry, boom. But this is a simple one page, right? And you're clearly going through and renaming things, moving things around. If you had a couple dozen pages inside of an application, you're gonna be up the creek. You're gonna have a problem. Yeah, I mean, you know, ideally you're not gonna do what I'm doing here. Ideally what you're gonna be doing is, like here I just have a button in here. Ideally what you're gonna be doing is coming into your mobile app and saying what pages from my WPF app make sense to port over, right? Does it make sense for me to do a one to one mapping here to have the same row? Is there better controls that I can be using, something more mobile friendly in general? So if you have a big app, your individual pages might come over relatively smoothly, but I often don't recommend what I'm doing, but this app I think it's okay, because it's a single page, but kind of like bringing over the controls in general. So usually what I say is, let's say a horizontal options, there we go, center. So usually what I say is that these controls here for my application usually come up and they enable me to check my application out, see my things inside of it. Our friend Rickety, hang on, our friend Rickety Rocket in the chat room is saying, just a quick friendly reminder, there is find and replace in Visual Studio. What? No way. Impossible. Oh, man. And it'll even work with regular expressions too. There you go. I need to, that's what I, again, I didn't rehearse this at all. This literally just happened. So here's what I have so far. So I brought up our Xamarinform XAML previewer, so I can actually get a little preview here on different devices, see what it looks like before running it. And now I get little steppers inside of here and I get output. Again, it's not 100% fixed just yet, but it's looking a little bit okay. And I can see that these controls, again, it's not a super complex user interface, but it's like, you know, it's something, it's my application in mobile form. But I need to come in and I need to say, I give it a binding context because we need to use that view model over there. So that thing was called, let me pull up my solution explorer and get rid of the previewer here. That thing was called, from my shared code, the timer view model. There we go. Now, let's see a visual studio. We'll pick that up. That automatically does. It's gonna bring in my namespace for me. Now what I've done is I've replaced and created a mobile-ish in five minutes version-ish version of my app. I'm reusing my timer view model here. There you go. And I spy, so all that code, right? The UI's different, yes. And the timer view model was writing a file to disk. You don't completely have that experience on a tablet or something like that and that's not gonna work too well with OBS. That is correct. It's not gonna work with OBS. So maybe we wanna do something there, Fritz, now that you spiced that up for me. Maybe we don't wanna write it to disk, right? So maybe I wanna come in here and I wanna say, what I could do here is inside this.NET standard library, maybe I want to bring in Xamarin.Essentials. Now, what's cool here is that there is a.NET standard version of it. So even though I'm gonna install it into the.NET standard version and not into my WPF application, it'll still work okay. It just won't return implementations for anything because it won't exist yet. Sure. So what I could do over in my code here, I could say, let me see if this thing's gonna catch up. I could say, if Xamarin.Essentials.DeviceInfo .platform equals equals and we'll go ahead and kind of bring in these namespaces here, let Visual Studio work for us. And we will say deviceplatform.android or deviceinfo.platform equals equals deviceplatform.iOS, right? We'll just go ahead and return. So maybe we won't do this. So maybe now we're just creating a countdown timer because everyone needs five minutes to count down stuff. That'd be pretty okay. Oh yeah. I'm just gonna check that. And since I have Xamarin.Essentials installed into iOS and Android, I'm now just gonna say, hey, don't worry about writing that thing to disk. Like it'll be fine. Like we'll just go do this thing. So now what we're gonna see is we already saw our user interface running over on inside of the previewer. But ideally, if my app is gonna go ahead and compile up here, we should now run this entire application with a little bit new user interface with my windows that I can't figure out a pin inside of it. Come on, Visual Studio. There we go. On my Android device. So let's give it a second here. I know that I'm one minute over, but if this works, this'll be amazing because I literally did not have time to test this last night. So. Live coding. That would be really cool. That's part of the fun here on Twitch. Yeah. Yeah. And if you wanna see more, make sure you click through and follow James. He's another great streamer here. And he does a stream every Friday. Mostly Xamarin stuff. I've been rebuilding my Hanselman application. So that's what I've been doing recently. There you go. Cool, things are happening. So what I think is really astonishing so far is that inside of that main page, right? It's just this time review model over here, which is now all of that code, all of my command, my event manager, my service container, clipboard stuff like that, everything is there. So it's gonna finish the jar signing and it's gonna start deploying. Oh my goodness. I'm gonna be so excited if this works. Crossing my fingers. Oh yeah. I'm crossing fingers, toes, anything else I can cross, cross, cross these. I'm so nervous. Come on, work. All right, so it's not beautiful. Okay. I didn't optimize it. Wait, wait, wait, wait. Can you turn? Yeah, I was gonna say turn at landscape. Woohoo. Look at that, right? And now it's inside of a scroll view because I optimized it. Look at that. That's a good start. It worked. It's a thing. Now it's counting down. It totally worked. Look at that. There it is. So you can see the little starting up. Now we're starting it. So it's gonna count down and that's actually pretty nifty. Maybe I wanna start it in both places and do stuff but or maybe I just wanna create a timer, any piece of functionality inside of here. And this is customized. I'm using string formatting. I could actually write this to disk if I really wanted to. Like that would work. Like all of that code would work by the way but it wouldn't really work with Streamlabs but it's like, but you could do that, right? So if you bring this now over to macOS though I could bring this entire application that I just built for iOS and Android go to my Mac, spin up a new Xamarin Mac application reuse all of the user interface all of the shared code now have a macOS application over there too which is pretty cool. And then use it with OBS on the Mac. Exactly. Fantastic. So there you go. Oh man. Wow, I can't believe it worked. Totally happened. It totally happened. Now, we do have beautiful applications though too. We have some great samples like this Tailwind Traders application which is super cool which is kind of like a store so it can log in. You can use Azure AD. You kind of get some really beautiful apps I can scroll through recommendations I can come in and see like, you know home appliances so we can now build we can buy the things that we're gonna build apps for, right? And there's some AR and smart stuff inside of here. So while I built a lot of really easy simple applications like just so you know, like there's you know, more full fledged applications that you can sort of build and take advantage of. So when you go to xamarin.com that'll redirect you to the Visual Studio page but you can learn on our docs docs.microsoft.com, there's samples there's everything that you could possibly imagine over there which is super duper, duper, duper cool. Oh yeah. I think that's it. I took out my time. I can't believe that worked. I'm mind blown overall. Yeah, yeah. And I brought my video back up. Hey, the video is back. Let's try it. Let's see if we can get that back to the thing. Hey, there it is. And I can go back over to here. Fantastic. Oh my gosh. All right. So WPF with .NET Core 3. It's all .NET standard friendly. So you should be able to take those things and get them running again over in xamarin. XAML isn't, you're gonna need to do some finding and replace but the shared stuff works. Yeah. And it makes sense, right? It's a one to one from desktop to the different mobile platforms. Cause this app even though I ran it on phone could be on tablet. You could bring that to TV. You could bring it to different platforms. You're gonna wanna spice it up like you saw I ran it and it wasn't portrait mode, right? It's very different than my landscape mode. So that's what I think is the things that I showed you we have great tutorials to step you through and walk you through the interesting parts of the difference in XAML. And I came from a WPF silver light background and making the transition is super duper simple just to kind of string replace in your head a little bit but we do have the toolbox, the property grid. So we help you out there. Fantastic. Very cool, James. Thanks so much for joining us. Learned a lot. Now we know how we can reuse what we've done on Windows over on mobile. Fantastic. And thank you for having me. No, thank you for joining us. And I'm gonna go get our next guest on the line. I'm gonna start putting together Abel is gonna join us to talk about actually deploying. So cool. Alrighty, I'll catch you later. Make sure you follow James Montemagno there on the Twitch. Take care. And we're out. All right. And here we go. So the Xamarin technologies, the Xamarin tools are something that I really do need to, I personally need to spend more time with. I think there's a lot there that's happening that we can make those mobile applications easier and it's not something that is gonna take a lot of time. You know, okay, you're gonna have some challenges with getting the XAML converted. But if you're at a minimal, if you're at a small application, making that conversion, getting it up and running with the Xamarin toolkits, gonna be real easy to do. All right, I think I see our friends here. Let's see if I can get all the things converted and running. All right, I think we're almost ready. Looks like it. Can I unmute you over there on channel nine? You ready to go? Give me a thumbs up. All right, look at this. Fantastic. So over here at channel nine, I have coming back to join us. It's Abel and I'm sorry, I don't have one on my markdown list here. Who's our other guest? No, no, no. Hey, well, thanks so much for joining us. So we've spent a lot of time today learning about building and developing Windows applications, but you guys work in DevOps. Why don't you introduce yourselves and we'll talk a little bit about deployment. All right, cool. So I'll go ahead and do a quick intro. My name is Abel. I'm a cloud advocate that specializes in DevOps, right? So I've been living and breathing DevOps for the past couple of years. But really, my claim to fame, fame is I got code and I've been writing code for over 20 years now and I pretty much just eat, drink and live writing code. I think the only thing I love more than code would be music, but I don't get paid for music, so I have to write more code. But so I've been writing code for a really long time and we're here to talk about DevOps for desktop, which is really exciting for me. But the problem is 90% of the code that I've written has been web apps. And I haven't done a whole lot of desktop applications. I think maybe like 15 years ago, I wrote a Win32 desktop application. But luckily with us is an expert on desktop. Yes, so I'm Ricardo, but everyone calls me Norito. All right. I've also been coding for over 20 years and a lot of different kind of projects from web to desktop. But in the last two years or so, I've been focused on how to improve the tools that we have in Visual Studio to create Windows applications from UWGP, WGPF, the designers, deployment. And I also was kind of on the days of ALM, the early days of DevOps. So I met Abel where he was at that point. And I think that now we are in a very exciting moment because the technology that we have in the deployment space and DevOps and get together to do some real things is what we want to share today. I also have some other passions like music. I play in a band, I like and skiing. And to say that I'm from Spain and I also love Spanish food. But to pay the food, we need to work and do some code. So this is where we are here. That's right. Oh, fantastic. All right. So let's start. Yeah, deployment, right? And DevOps around, Abel, I'm like you, I came from web. So this feels a little bit different for me thinking about building a client app. Right, right. And building a client app or even deploying it, right? I mean, it's different than a web server because for a web app, you get your bits, you create them and then you push them out onto the server some fashion, right? It might be serverless or whatever, but it doesn't matter. And that servers in one place, you know its name, that's where you're putting it, but a client app, well, that's going all over the place. Yeah, so how do you even do that, right? But before we dive into and talking about that, maybe we should address the elephant in the room. I see what you did there. What exactly is DevOps, right? So the big thing is we all know that DevOps is super important because people like me have been shouting about it for like the past 10 years. But you ask 10 different people about DevOps is you're going to get 10 different answers, right? So just so we can frame the conversation we're about to have. At Microsoft, DevOps is something very, very specific to us. So at Microsoft, DevOps is the union of people, process, and products to enable the continuous delivery of value to our end users. So notice I said that super, super carefully, right? I did that for two reasons. Number one is because the person who came up with that quote is my manager. So if I said it wrong, I would get in trouble. But the other more important thing is every word of that makes sense, right? So the key that I want people to realize is that we need to be able to continuously deliver value to our end users. That's what's absolutely vital in today's world, right? So some of you might be thinking, why do I care? Why do I need to continuously deliver value, right? Well, DevOps is important. The speed of business is moving so quickly today that we have to be able to innovate at DevOps speed. We have to be able to continuously deliver value. And the thing is, if you don't, your competitors right now, they are using DevOps best practices, which means they will out-innovate you, which means they will render you obsolete, right? And nobody wants that to happen. And we know this, right? This used to be theory, back when we first started talking about DevOps, back in the LLM days, but this is no longer theory. We have hard empirical facts now. Companies and groups that implement DevOps best practices, guess what? They absolutely do out-innovate the companies that don't use DevOps best practices. So whether this is for web apps, or whether it's for desktop, guess what? We absolutely need to use DevOps best practices, even for DevOps applications, or desktop applications. So it's not necessarily easy to do DevOps correctly, right? We need to be able to align a couple of things. We need to make sure that people, the process, and the products are all aligned together, so that we can enable this continuously delivering value. So what that means is, well, the people portion, that's probably the hardest, right? That's culture. You need to have a culture where everyone from top all the way to the bottom, you're totally aligned with this idea of, we need to continuously deliver value no matter what. So if our old processes are hindering this, get rid of it, let's find processes that make sense, right? For the process part, that's a little bit trickier, because the process, well, in some ways it's not, right? Your process needs to let you iterate fast enough, yet still deliver code that's high enough quality. So in order to do that, things like Agile or Scrum, or things that, processes that let you iterate like that, those work really, really well. But we need to be able to plan our work from iteration to iteration. And we need to be able to do things like, well, once we check in our code, we need to be able to track our check-ins to the work that we did, and also we need to have automation built in. So we need to have automation that will take that check-in and automatically kick off the build, compile our bits for us, get us our binaries, run all of our unit tests for us, right? And if all of those look good, we need even more automation that will pick those bits up, and then start deploying them into our different environments. When I'm talking about web, I'm always like, oh, the dev environment, the QA, UAT, all the way out into production, right? Yeah, I've got a machine name that I can point to, right? There's the dev machine, it's called dev, right? Exactly, exactly. But for the desktop world, it's a little bit different. So we'll kind of dive into that and show what I mean by that. And then finally, once our application gets deployed all the way out into our client's desktop, or production websites or wherever, it doesn't end there, right? We still need to be able to monitor our apps, get telemetry, figure out what people are doing, right? What are people doing? Is my app even up or down? Is my app performing well? And if I can answer those types of questions, then that can help me kind of figure out, am I delivering value from sprint to sprint? And based on that, for my next sprint, I can retool or reprioritize and figure out what we're doing, and then this whole process rints and repeats itself. So if we think in these four axes, the first one is, I think it's no difference for web or desktop because it's the planning or how to find the right user stories to build. For development tests, they don't see much difference because at the end we have search control, we have builds, we have unit tests, the same thing. However, in the release part, is where I see a lot of differences because we need to understand that client applications are deployed to client machines. And that's a unique challenge that we are going to show you how you can do it easily with our tools. And finally, for monitor and learn, also the fact that the application is distributed across hundreds or thousands of machines, another challenge, how can we get the right insights from telemetry where we are not only monitoring one box or one machine or five or 10 or hundreds. And it's all these different client machines, right? And even something like, remember back in the day, if something happens, you get that little message box on your phone that says, email the logs to the developer. Right, nobody wants to email. So there's gotta be some way we can automate that, right? So we'll go ahead and dive into that. And there are all sorts of tools out there that will address all these different parts. That can help you take your code, play on your work, source control, build and release systems, telemetry gathering. And you can use all these tools, they work great. But at Microsoft, we also have something called Azure DevOps, the product, which is everything you need to take an idea and turn that idea into a working piece of software in the hands of your end users for any language, not just .NET, not just the Microsoft stack, any language, any platform. And this tool, that's kind of what we're gonna show today. So, what we're gonna do is we're gonna look at desktop application, desktop DevOps. But I do wanna point out that the desktop world is different than the web world, right? So because of that, because of that, desktop has some very, very unique challenges. And hopefully you can help us out. Yeah. So, let's review which are the different parts that we were talking today, which is unique for desktop applications. So, as we said before, let's start on the builds and how do you configure your branching, versioning. So, first of all, I'm going to make all the demos with one of the applications that was shown this morning. It's an application WPF app. It's kind of target .NET Core or .NET Framework. So, everything that we talked before will be used here with new models. And, well, it's all the code that you have been written during the day. So, what we have is a repo. Let me switch to this repo. It's open on GitHub. So, my account, Redomin, MSIX catalogs is one. Yeah. So, this is the WPF application that you can build for framework or for core from the same sources. So, I use this application to evaluate different migration strategies and differences between one and the other. And also we have like different channels. So, ultimately, we want to deploy our app to the store. So, I have two store deployments, one for framework and one from core. So, the app is like here in the store. And also, two different side load locations. One is from a web app service running on Azure where we can push or copy all the installers. I said installers because we will talk about that in a second. So, users can get the application from there. But also we can use App Center as another distribution method and another platform that we integrate with this dev of practices. So, going back here. So, what we have in this repo are basically two main branches. One is master. That will be the branch that will be deployed to the store. And the other one is dev. That this is like our nightly build and that will be deployed to side loading. So, that's one of the first parts. And we will be diving the different configurations to our build pipelines. Then we have packaging. This is the installers that I referred before. And we call packaging because we are creating packages and the MSIX technology is a great, great, great addition to have a smooth DevOps workflow to from build to deploy to release to update. So, are you going to later dive in and tell us a little bit more about the MSI access? Yeah, yeah, yeah, yeah, yeah, yeah, yeah. Cool, cool. As the agenda, the different topics that we will cover. And guys, I actually have a question from the chat room asking, does DevOps support other custom installers like Nullsoft? Couldn't hear anything. Dude, cut out for a second. Dude, does DevOps support other packaging mechanisms like using Nullsoft? Yeah, I, the question. So, I think that that depends on the toolset that you use to build your installer. For MSIX, where we are using a new project type in Visual Studio, this is a packaging project that allows you to produce MSIX or Apex packages. And yes, there are other tools that you can use to build the different installers. One popular tool is Wix. I'm not sure in Nullsoft what's the support that they have. Basically, it will depend on the different agents or options that you have to run your builds. But as long as you can build in your machine, probably you can integrate with DevOps. Yeah, so, so after DevOps, the product can, you can do literally anything you want to it. So it's basically a task runner. But that means if there are tasks already built for Nullsoft, guess what? You can just go ahead and use it. I would check the marketplace and see if those exist. I don't know if they exist or not. Worst case you can automate from a command line and conduct yourself. That's what I was going to say next, which is if the task don't exist, then can I use Nullsoft from the command line? Because if you can, it's simple enough for me to create PowerShell scripts or Node.js scripts that does whatever it is I need to. So the short answer is yes. The long answer is yes. Check the marketplace. If not, you might need to build your own custom task or write some scripts that will actually call Nullsoft to do whatever type of packaging you need. Another important point here is that to have a really modern DevOps workflow, it's not only installing for first time, it's only how to deliver updates. That's a really good value for the MSIX deployment stack that you can automate the deployment all the way out to the end users, not only to the server. There are some issues with other installed techniques like MSIs that automatic updates are not there by default. So you need to do something to define your update strategy. But yes, sure, this is something that we will go over. I already talked about distribution, different places where you can host your packages and your updates. And one important part of the distribution and the client story, and this is different from the web, is how to protect your packages. And this is why we believe that code signing is an important, really, really important asset these days where the digital signature will protect your packets, the content integrity from the author to the end user to make sure that anyone modifies or added malware or anything to your packets. And here from the DevOps perspective, how to deal with the private key, it's super important. And the other two topics are testings. How can we do testing, code UI testing, functional tests in our DevOps? And finally, how to get the limitless. Abel said, we want to make sure that we understand and get all the feedback and all the events that we got from our users without asking them to send an email with log files. Right, right, right, yeah. So let's start. The first thing are builds and packages. So you need to understand the, well, maybe you can explain what are the different options to build in DevOps from the hosted building and what's the thing, and why this is important. All right, so in Azure DevOps, there's this concept of you can create builds. You can link your builds to any type of refos, any type of Git refos, whether it's in Azure refos or whether it's in GitHub or Bitbucket or other Git type of refos. And you can link them together so then anytime somebody makes a change, you will go ahead and kick off this build. And the build, there are in Azure DevOps, there's this concept of you have build agents that you can use. And there are two types of agents. There are hosted agents and these are agents that we at Microsoft provide for you for free that you can just use. And each one of these agents, and we have these hosted agents for Windows, of course, we also have it for Linux machines and also for Mac OSs. So really what that means is you can build just about anything, right. And then also for all three of these platforms, there's a known set of software that is pre-installed on these agents for you to use, right. The Windows agent, I'd like to say that we have the agent with Visual Studio 2017, but we also have another agent with Visual Studio 2019 that is needed to build .NET Core 3 desktop applications. Yes. To see that we have support for those. So for most of the stuff that you do, you don't even need to have your own build machine. You can just use these hosted agents, depending on which flavor you wanna use, just pick it. And it will automatically build your code for you, right. But sometimes you need to have custom software installed. Maybe you need to flip some registry bits or do something, right. There are sometimes when your build machines has to be super configured just your way. And for those types, you can use what is called a private agent, which is your own agent. Basically you have your own VM or your own machine and you install our agent on it. And then now you can just use that from Azure DevOps as well. So in this table, I'd like to highlight some of the big differences that we will see doing DevOps for desktop applications. The first thing is the .NET targeting pack. If you are building .NET Framework applications, your app will be targeting .NET Framework 461 or 47 or whatever. To be able to have that capability, Visual Studio needs to install and target impact that will enable Visual Studio to build targeting that specific version. So the latest version of .NET Framework is 48 and it's not available on Visual Studio 2017. So based on which version of .NET Framework you are targeting, you probably will need one option or the other or your custom build agent. However, for .NET Core, things are much easier because you can get the SDK out of band. What it means that we already have a task in DevOps where you can customize which version of the .NET Core SDK that you want to install. So you can build your code with our nightly versions of our code or you can use the most standard previews right now we are in preview three, but it's something that you can do so you don't need a custom build agent for that. And the last part is the Windows SDKs. We are releasing one version of the Windows SDK with each major version of Visual Studio with each update. But there are some times where the SDKs in preview like the insiders builds for Windows and those versions of the SDK are not deployed to the hosted build agent. So if you want to build something or targeting an SDK that has not been released yet, probably the private build agent will be the best fit for you. And then there are other two parts. They're running UWP test or test that requires some kind of interaction with the shell and like UI test, they are not so easy to configure in the hosted build agent and sometimes it makes sense to use your custom agent. Probably because you're super easy to use. Oh, you're super easy, don't understand me wrong. The only thing is you need to maintain that machine. Right, correct. So let me ask you about the custom build agent here. So we have a question in the chat that I'm not sure if you would use a custom build agent or what. Bravecobra asks about, and it was a rambling geek chimes in as well, about code signing. When you have to sign that application that's gonna be shipped, that's a little bit tricky to do because you have to get the certificate and you need to sign appropriately. Is that something that's handled well with the hosted agent? Or do I need a custom agent that I install and maintain that certificate on? Short answer, you can use the hosted agent for that. You totally can. And we will show you that in just a little bit. Spoiler alert, sorry about that, okay. Bad, we understand in some cases if you want to protect your certificate, having the certificate only on your private agent also makes a lot of sense. So you can do it, but you are both options and you can choose what you want. But that's one specific topic of this session that we will cover in a second. All right. So packaging, as I said before, packaging is a really important piece because this is how you bundle all your files and deliver those files to the customer. Yeah, I'm glad you're telling us this because I don't know anything about packaging, right? For my web app, I just zip everything up and hurry for that. Yeah, well, it's a package. Right, right. So here in, for Windows applications, we have one packaging format that was called Apex, but we renamed it to MSIX. When I said MSIX or Apex, basically it's the same thing, just the rename of the extension to be clear when Visual Studio will generate MSIX packages is based on the configuration of your project. So every time you create a Windows application packaging project, I'm going to show you right now, or a UWP project. The very first question that we ask is, which is the version of Windows that you target and which is the minimum version that you support? So we call this target platform version and target platform inversion. Only when the target platform inversion is greater than 1809 in the latest major release of Windows, we will produce MSIX. Otherwise, we will produce an Apex. So you will see in my demos that sometimes the files are Apex or MSIX, but it's the same. And let me show you what is that packaging project. So here I have Visual Studio and I have my solution with my application, my download standard library, and the third project we see here, this is the packaging project. This is a project that doesn't have code or anything like that. What it has is just the reference to the application that you want to deploy. And also it includes something else that is this manifest. The manifest is an important piece of the package because it defines a lot of things. From the icons that will be shown when your application starts in the star menu and interacts with the shell, which capabilities do you want to declare to your application and which packaging characteristic, like which is the package name, which is the display name, the version, the publisher. And all of this information is used by a tool called Make Apex to produce the final tool. So this is a project type that is really easy to use. Yes, application, they find your requirements, the characteristics of your package and that's it. Then you can create the package using this option Store, Create a Packages. And we have options to create packages for the store or you can create packages for our side load. We will cover that later in the next section. This packaging project, the Windows Application Packaging Project, that extension is web approach, supports any kind of Windows desktop projects in Visual Studio. So you can use WinForce, WPF, .NET Framework, .NET Core, but also C++ applications. And the gestures and how do you build and deploy the apps is exactly the same, no matter the technology that you use to build your application. So packaging is the universal packaging for any kind of exit that you can think to deploy to Windows. Cool. So here you will see a manifest. Some important parts here is the identity. One important characteristic of MSIX is that in your machine there could be one and only one application with the same identity. So if you want to have side-by-side from different channels, let's say that you want to have the version from the store and the version from your side load installed on the same machine, you should change your identity. Another important piece is the publisher. This string needs to be exactly the same as the subject name of the certificate used to sign the package. Okay. And there are other characteristics, like dependencies. So MSIX can detect which are the dependencies of your application and handle the runtime dependencies for you. So you need to worry about installing prerequisites or anything like that. So with MSIX, you just double-click and you get your application installed. Okay. So here are the basics of MSIX. But MSIX is just a package that when you install, you've got the application in your machine and that's it. Okay. How can we customize MSIX from your DevOps? So we fully support command line builds, but there are some new parameters that you can use to customize the output of your builds. So you can use these parameters, for example, to say if you want one build pipeline to produce a store package, you can specify that you only want a store only or if you want only the side load, only side load. You don't say anything, we will produce both for you. Which platforms? This is something that is unique about MSIX is that you can bundle in the same package, the binaries for multiple platforms. And here's where you configure which platforms that you want. Which is the output there. If you want to sign your packages, and this is a best practice, and I recommend that in your build pipeline should not sign your packages. The sign-in should happen at the release time and we'll talk about releases in a second. And the reason is to avoid dealing with certificates at build time. And also because if you're deploying to the store, you don't need to sign anything. So don't think that you need to sign everything at build time and sign your packages when it makes sense. All right, so let me just restate that to make sure I understood correctly, right? Because I always figured if I build my app, I'm gonna sign it at the same time. But what you're saying for best practices, it makes more sense, the build is just gonna do the compilation to get those compilation bits, maybe run all of our unit testings like that. And then when it's time to do our deployment, that's when you go ahead and actually sign it. Fascinating, all right. Okay. But what about, I mean, so we're talking about applications here and building that packaging for an application. What about if I have a Windows service to deploy? Can I use the same technology to package a Windows service that I want running and get those same incremental updates happening? So the short answer is yes. There are some features to enable services, but they're not exactly the same services as you know today with .NET where you run your install util to configure your service. So there are some limitations here. We added that support for the next version of Windows. So if you're interested in deploying MSIX or services with MSIX, please contact me and I will guide you and how to do it. But the foundations of how to do it is exactly the same. There are some differences on how the service is deployed and that, yes, we will support services with MSIX. And the last property here is the App Installer URI. So this is a URL that you define to identify your installation point. I don't know if that means something. So let's talk about that in a sec. That's the distribution. Before getting to distribution, the App Installer, let's finish the packaging and build with .NET Core 3. So .NET Core 3 has two different deployment models and this happens for console applications and desktop applications. The first one is what we call framework-dependent deployment. What it means, this is the same deployment model as the .NET framework. So you need to install the runtime before you install the app. So you don't have the runtime, the app don't install. And in your package, you will have only the DLS or XS of your code. So the base class library and the runtime will be in a different folder. What is new with .NET Core 3 is that you can have different applications targeting different versions of the runtime on the same machine. With .NET Framework, there's only one version of .NET Framework and all the apps are based on the same runtime. The second option is self-contained deployments. This is a new deployment option and this will generate a folder with all your dependencies, the runtime and the base class library. I can give you my USB and you have my app. That's it. Magic, you don't need to install anything. However, the downside is that the size is bigger. It's around 100 necks, so it's not too bad. Not too bad. What is really interesting here is that if you go with self-contained and there is a service in event or any security issue that you need to deploy, you need to deploy your application. In framework-dependent, you update the runtime and all the apps will get that date, here you need to update all the apps. There are pros and cons on each option, but for MSIX and the packaging project, we will start with self-contained deployments and in future releases, we will enable framework-dependent deployments. So for now, the packaging project will produce self-contained deployments. One implication of self-contained deployments is that the code is no longer portable, so you are not targeting any CPU. You are targeting one specific architecture because each folder will be targeted for one architecture. What it means is that you need to specify the runtime identifiers to your own network project. So at restore time, we will download the runtime for the platform that you are going to be. This is an important detail. So these are the runtime identifiers that you have here to specify and you want the self-contained or framework-dependent. Okay. So the summary here is that the packaging project allows you to package anything that will produce a desktop application. Cool. So now let's talk about distribution and this is very similar to the web. The thing that here is where both different ways of doing the box will get together that in the end you need to specify a URL where everything will start. So MSIX was started as Apex as I said before targeting for restore to submit application to the store. And it's already supported to the store, so you can submit your MSIX packages to the store today. But we want to enable all their deployment options using the same packaging format and we call this side loading. What it means that you can get the packets from different locations. Okay. So not from the store. So side loading is basically I install it but it's not from the store. Exactly. And there are different ways to install so you can install from a USB double click and you install the application but then you don't get updates. If you install from a web location or a shared folder the system will track where did you get your application from and knows where to ask for updates. Oh, so if I let's say I push my code to like for side loading onto a website or something like that and I install it from there, new updates come even if it's side loaded it will update on my desktop. Exactly. Wow. So that's the demo that I want to show you when we finish explaining all that they have here. Very cool. So the store of course will update your application for free so that's, but this is the new thing with side loading. Think about it like the click once deployment experience that we used to have where you again define your installation point and all the updates will get from there. So that's exactly the same. And the trick here is to deploy your packages from your release pipelines to that web location. So end customers, clients will get the application from there. Got it. Okay. Yeah. And as I said before, if you want to support the same map deployed twice, I mean, from the store and side load you need to change the identity of your application. Got it. To make sure that you enable side by side. If you use the same identity you need to uninstall one to install the other. Got it. So these automatic updates with the app installer file this is very basic XML file where we specify the URL of this file itself that it's here. And then you specify the version, the publisher, the name, this is the identity. So you'll see that this is really important. And then the URI where you will get the Apex or MSIX bundle. These are the Apex, MSIX is the same. And then there are some update policies. So you can customize how do you want to update your applications. Maybe you want to update every 24 hours or you want to check for updates only every other week or maybe you want to update every time that they have launches. So we call these update settings and there are some different options to customize your deployment experience. The same experience, the same option that you used to have with ClickOnce. So how can, which different options that they have to store my packages. So you can use a share folder. If the share folder is in your private network probably it's another good reason to use a private custom build agent that have access to that private network. With Azure and all the investments that we have in the cloud, it's also easy to create a VM that can connect to your virtual, to your private network and deploy your files there. So that's also that it's super easy and that's it. If you prefer something that is more web based so you need a web server, you can use any web server from BlobStorage to Azure App Service or any other web application. The only thing that you need to understand is that the client will need the magnet types. So you need to configure the extension to make sure that the browser or the HTTP agent will understand the kind of packages that are doing all the files that will be served. So here we have a couple of magnet types that you need to understand. So I need to configure my mime types so that it will recognize, okay, got it. You can do it in BlobStorage, you can do it in App Service. And finally, if you don't want to configure anything you can use App Center and App Center will enable to host these files as well. So App Center already support Apex and MSIX for UWGP but also for any other Windows application that is packaged with MSIX. Cool, so let's see how can we do the same thing from the pipelines. Maybe you want to introduce which are the build pipelines and release pipelines before we get into there. So let me go back here. My pipelines. Yeah, so for those of you that are familiar with Azure DevOps, you know that there's build pipelines and also there's release pipelines. And the thing to remember, let's go ahead and just jump in one just so people can see what it looks like. I guess I'll just take a look at this. If you look at a build pipeline, both the build and the release pipelines they behave very similarly inside of Azure DevOps. And they're basically, it's just a task runner and it does one task after another task after another task. So usually when people say, well, how do I create a build? The first thing I ask them is, how would you do this manually? What are the things that you would do? And then let's, okay, those are the good tasks. Let's see if we can find tasks that can actually do that or maybe we need to write our own custom tasks or write a shell script or something that can do that. And so it's just a task runner. Out of the box, we give you hundreds of tasks that you can just start using, right? And it's not just for .NET, it's not just for the Windows stack, it's for any language targeting any platform, right? And the idea is if you wanna do something that doesn't exist out of the box, jump into the marketplace. I think we have like close to like 900, is it? Something like that. We have a lot of custom tasks created by our partners that you can just download and start using. And once again, you start scrolling through this list and you realize, wow, these are tasks for all sorts of different kinds of stuff, right? And then again, if you wanna do something that's not out of the box and not in the marketplace, you can write your own custom tasks as well. So custom tasks is nothing more than PowerShell or Node.js, which literally means if you can do something from the command line, you can get Azure DevOps to do that really easily as well. For example, I'm using this version in tasks. This version in tasks will take the version of that is generated from my build process and we'll update the assembly version for Donut Framework and Donut Core and we'll also version my Apex based on my manifest. Got it. So that is the version that will be used all over the place. My Apex starter file, my assemblies, and that also on my packages. Yeah. If you look at this, it's super easy to read, right? But it's the first thing we're gonna do is version of these different assemblies, then we're gonna use NuGet. We gotta restore our NuGet packages before we do anything. We have a little PowerShell script here that's gonna update the Manicast. Yep, all right. To update the identity. So I'm adding a suffix here tonight, which you will see that we can have different publisher or different identity of my packets. So this version will be used lately because it's the CI from the Dev branch. That's the question that I will use for Cybel. And then once I finish with the manifest and updating the version, then I'm ready to build. So that's the next step. So we'll go ahead and use a Visual Studio build task because everything's in Visual Studio, right? So for the Visual Studio build task, I thought this was kind of interesting because if we go ahead and look at the MS build arguments that you see, you put a lot of different MS build arguments in here. But that kind of makes sense because you want this build to do something very specific. Exactly, so and those are the same arguments that I described before. You were talking about earlier. So exactly this. So here you can see that the sign in is disabled. You can see whether it's the MyAvistare URI or which platforms I want to use because this is defined on a variable here. And from this, this will output my MSIX and the package for the store, the package for siloed, but also the Appistare file. And something else that we also create is the HTML page. So you will see a nice kind of installer experience out of the box. So I'm also publishing the symbols, copy the files and publish the artifact as a draw. And the next thing is the release pipeline. So I have different release pipelines for different builds. So these release pipelines for the ones. Sure, so the release pipeline is very, very similar to the build because basically it's the exact same task engine, right? So, but the idea is you can create these different stages. And for this demo here, we only have one stage, but you could have multiple stages like maybe these are alpha testers in your beta testers. And maybe this will be to like a dev environment that you can test it out to, like a QA environment all the way out even to the store if we want to do, right? Yeah, so it's the same type of stuff. You define your environments. After you define your environments, you can jump into the environments and here's the same task runner, right? So how you want to do your deploy, it's a task runner. So the same thinking is, okay, how would I do this manually and then let me find the tasks that can actually do that. And if I can't find it, then I'll just write my own. Yep, bye. So here we have the code sign task that someone were asking before. So let's see how this task works. So the first thing is that we have this secure file and what's this? What's that? So the secure file is, well, you have a certificate, right? Oh yeah, I have my PFX with my private key. Yeah. So you have a certificate, you don't really want to store that certificate on GitHub with your repo, right? Exactly, we don't want that. But the point I think that all PFX files are Git ignored. So if you submit your PFX file to GitHub it's because you made some change that you need to be aware of that you are disclosing your private keys. So your private keys are private. Yeah, so we've got to keep our private keys private somehow but Azure DevOps needs to have access to it to be able to sign all the code. So there's something called a secure file where basically you can take your certificate or any file you want, upload it to VST, I'm sorry, to Azure DevOps and nobody else can see it, right? So you do give Azure DevOps your certificate but now no one else can access it except for this pipeline. Even myself, I can't download that certificate anymore? No, you can't download it anymore. You can delete it and that's all you can do. Okay, that works for me. So it's a safe place to store your certificates. Yeah, but this certificate is protected with a password. So my password is also here defined as a variable of type secret. So also my password is secure. So let me just explain variables. Inside a build and your release pipelines you have the ability to create variables that will be used. These variables can be just strings that you can see or you can secure them as well. So no matter how hard I try I will never be able to get your password. Cool, yeah. So this is the task that I'm using to build and the reason that I'm doing the code sign in the release pipeline instead of the build pipeline is because probably you want to sign with different certificates based on your environment. So maybe for your beta testers you are using one certificate and also maybe for your developers for testing you are using different certificate or you are using side loading for your production you are using the different certificate. So yeah, that makes perfect sense. So if we had lots of different stages we can sign them with different certificates from one stage to the next stage. That's another good question. And then the next two tasks the only thing that they are doing is just grab the drop folder the artifacts that were generated in the build and push them to your app service your web application and that's it. See, that's that. Cool. Okay, now we need to go faster because there are a lot of things to cover and I want to make sure that the demo we will have enough time for the demo. Okay. So we already talked about signing just a quick note here that there are two maybe three major kinds of certificates. CA usage certificates, issued certificates these are certificates generated by public CA's like the user or CMAN tech or this kind of guys those usually cost money and but for enterprises or individuals that's a good thing to do. For dotnet developers we have the dotnet foundation that also offers pretty certificates for dotnet foundation members. And we also have another certificates more oriented for development or testing that are self-signed certificates those are certificates that I can generate by myself but if you want to install something signed with one of those certificates you need to explicitly trust that certificate. So it's something that you need to understand and remember that the certificate subject name should match what is in the manifest. Yeah. So with this approach there are two roles here the developer and the user the developer must have the certificate with the private key in current user personal that's where Visual Studio will look for to get the private key and produce the signature. For users who want to trust your certificate they need to copy that certificate without the private key only the public key to local machine trusted people. So there are two different workflows for users or developers. And we already covered this how to sign the release pipeline and now it's time for the demo. So. Good one. Here. You can see everything in action. Let's see if everything works. So first thing I'm going to install this application and for first time so I don't have the application installed this is the HTML page that we generate. Okay. From there. So the build will actually generate this HTML page for you and now it's stored on app service or a website. So you can just point your customers or point your people if you need this app go here and just click this button. Exactly. Now when I click this button what will happen is that the app installer app will open and will ask me to install these applications. I'm going to install the application I can see who is the publisher and what's the version number of this application. This is about 100 megs. CPID is 47 megs I think so you will notice that the first time it took some time. One interesting feature of MSIX is that it enables differential updates. So the next time that it will take the update only the visa change from the previous version will be downloaded. Nice. So you will see that super fast, crazy fast. Nice. So here's my application. Make sure that we understand where it is. So this is the version 1943. It's running its package from the app installer and it's running the .NET Core version of self-contained deployment. Okay. So now let's make a quick change. Okay. Instead of doing the change with Visual Studio I'm going to do something that looks crazy that it's what if I edit directly from GitHub. Nice. So I'm going to edit my SAML from GitHub. Okay. With the GitHub editor. Let me open the app SAML page. So I'm going to change the color of my app from base dark from base light. Don't do this yourself. You probably will prefer to test the change Yes, locally, but for the demo use light. Then I'm going to commit the changes. And now once the change is open, I did the wrong thing. I think I'm going to commit to the dev branch. Oh, well, let's do the change here as well. And to take more time than expected but anyway you can see. So maybe what I'm going to do is to to cancel the bills that are running because I only have some agents and they will process the bills one after the other. So let me cancel some bills and let's focus on the CI bills. So the CD bills that are here let me cancel this one. Because that's got kicked off because that build is actually looking at the master branch. So your CI build is looking at the dev branch which is where you really wanted to make the change. Exactly. All right. So this is it, right? Oh, that's the CD. I have two bills for one for core, one for framework and another bills. So the one that we should be looking at is this one. So this will be the version 53. To like two minutes or so. So once the build is done, we'll have the artifacts stored in our drop folder and then the release will start because the release is also configured with continuous deployment. So everything that the build finishes, then the release will start. So we have like a mapping between build definitions. Very cool. So it looks like there's another bill that kicked off before this one which I think it's the .NET bill. So let's see if we can kill that bill too. Yeah, this one, right? And let's see if we can get this bill started soon. All right. What should be, oh, this is the, okay, this is the bill notifications. So let's stop all the bits that are happening here and just focus on the bill that will trigger the .NET Core 3 deployment is this one. Okay, so already started. Now we are running Nougat Restore and let's see what's happened. So this is kind of cool. Like even though the build is happening on our hosted agents, you're able to see in a console view live exactly what's happening from step to step to step, task to task, we'll be able to see in live view exactly what's happening on that build server, right? So this is really kind of neat. So like this is the same bill that we looked at earlier, right? So the first thing we're going to do, we're going to check out all the source code from GitHub, from the dev branch. We're going to version the assemblies, version the .NET Core, version the APPX, restore our packages from Nougat. So now it's going to go ahead and it looks like it just built our solution using Visual Studio with all of those command line parameters that you passed in. So now it's going to build the correct packaging, that's what all the command lines did, right? Exactly. Okay. So then after we do that, we're going to take the binaries and now we're going to put it into a drop location. The drop location is basically just a blob storage on an Azure DevOps. And when this is complete, after it publishes all the build artifacts, then it will go ahead and kick off our release pipeline. Exactly. So let's see how can we see the release pipeline this is going to end. Now it's uploading the files as we speak. So it's uploading the APPX bundle. Okay. So that has all the different binaries for each architecture. Okay. And now when it's done, we can go to see if the release is ready. Cool. So it's almost done. Just a couple more steps left and you'll go ahead and kick off that release pipeline. Yep. Cool, cool, cool. Let's see. So while this is still going, oh, I guess we're done. Yep. What I wanted to show is you get a really nice summary page of everything that's actually happened during your build, including if you really wanted to look at what is the output, what's going to be put in your drop location. We can actually see, we can download this as a zip file, but then this is all the build artifacts that was created for us. And of course there's that index page. That's the index page that the app installer and this will point to the APPX bundle that it's here. Cool, cool, cool. Okay. So now let's go to the releases and see if the release started or not. Yeah, looks like it kicked off. It started. And we can also see the logs in real time. And let's see when we do this. So now we are signing the package, go into app service, and go into app center. Okay, okay. So that's right, because you're doing the signing during your release, not during your build. Exactly. Got it, got it, got it. So the signing is gonna use that certificate that we uploaded earlier. Yeah, exactly. And then it'll go ahead once it's signed. I guess the first place where you can deploy it to is to the website. Okay. And then you said there was also an app center task, right? So can I go ahead and look at that really quickly? So I wanted to ask about this earlier. You go to the task here, you will see the tasks. Yes. So I get this. What is app center doing? So app center it's a tool that will provide like a next level of abstractions for your DevOps. For, the net core is not yet supported because it's still in preview, but once it's supported, it will do all of this for you with how you don't need to worry about the build pipelines, the release pipelines, the distribution locations, and we'll close the loop also with the telemetry. So basically it's that you're starting in app center and say here's my repo, and app center will take care of everything, configuring everything for you. So the only thing that you need to worry is how to add your test users to your app center project. And they will see every time that the new build happens, every time there's a new version released, every time that someone gets an exception of your application and everything in the same. So using app center that it just, it simplifies this whole build and release process. Okay, cool. Hey, what's that? We got that email saying that now the application is deployed. So now if I go here to the link where we slink, we will have this new version. This is a version 43. Remember that the version 53, the version that we have installed was 43. So now I'm going to close the application, just open again and everything works. We should get this version 53. We can ignite the new theme. So I'm going to find, this is the MSIX catalog called Nightly. This is going to run the same version that you would because it detected that there's a new version available. So the next time that I open the app, if the demo works, we should see the new version. So this one, see that update bar? Oh yeah, that's the update. Now the app is updated because you don't download the difference. Oh, look, there's your changes now, the white background. And here is, yes. So here's the complete demo. So this is so easy that you can deploy desktop applications in the same way that's client applications. Customers, they don't need to do anything. So this is ridiculously cool, right? So just in case people don't realize what just happened, you just checked in code into GitHub. In fact, you edited on GitHub and then checked it in directly. Because of that, it kicked off the build inside of Azure DevOps. It compiled everything, ran our tests for us, did all that good stuff, packaged everything up. And then it went into a release pipeline where it pushed it, it pushed this change not only to the website, but to your desktop that has this app. So then... Well, to be fair, we didn't push yet that will be coming next, we are not pushing. So we need to wait until the customer queries to see if there's an update. So this is why I opened the application twice. Got it, got it. So the first time that you opened the application, it will check if there's an update. And then the update is scheduled for the next time that you opened the application. That's still amazing because you now have pushed, you've got your change onto your end users desktop. This could be hundreds, thousands of users and the workflow that you follow is the same as any other web application. So I think that there's, we don't have the excuse to say, I don't want to write client applications because of the deployment. So the deployment should never be a blocker anymore. Right, right. So this technology is almost the same as any others. This is amazing, this is awesome stuff. So this was the demo and we don't have time to dive on more topics and the next thing will be the testing. You can run UI tests in your custom diligence. Yeah, so testing is simple enough, right? You can have a unit testing, which I'm a big fan of and then of course automated UI tests. So unit testing is just one simple visual studio unit testing task. It can run and unit X unit, MS test, whatever type of unit testing that you want to do. And then for the automated UI testing, it much easier to do it on your own build agent and then you can run automated UI tests with Appian and the Windows driver. Yeah, the Windows app driver is based on Appian is basically the same idea where you write your tests trying to find elements of your UI and making assertions based on those elements and you can also interact with the controls. Cool, cool. And the final idea is the telemetry. So you can instrument your application to deploy, to generate traces, events, exceptions. We also have this concept of crash analytics that is something unique that it means that if your application crashes, even if you don't handle that exception, the system will be able to report the crash and the exception to the developers to understand. So I no longer have to email you the long file. Exactly. You'll get it automatically when it crashes, got it. So that's it. For the roadmap, we are thinking to how to add more and more features to App Center. So it will be super easy for anyone just point to your GitHub repo and you will get all the benefits and everything that we configure manually here but from App Center will be almost automatic. And as we said before with DevOps, I think that we have all the tools and the infrastructure needed to make sure that the deployment of client application is as easy as the deployment of web apps. It really is. This has been awesome. Yeah, this has been terrific guys. Wow, we're doing such a great job chatting back and forth there. I just had to sit back and be like, this is great. So thank you so much for chiming in here and showing us how easy it is to get all those steps that you need to build, to test, deploy, monitor, get the telemetry back. It really is that Swiss Army knife that you need to get from. All right, you're done writing code. Now how do we maintain? How do we decide that next version? Great stuff. Yep. Very cool. Well, thanks so much for joining us. This has been terrific. We're going to have video recorded and available a little bit later on all the stuff that we have done all day today. So that's the end of our day. Yeah, and thank you very much for having us and hope that everyone will apply these concepts to deploy their client applications. Absolutely. So thanks so much everybody for watching. Thank you, Abel. Thank you, Rito. And we'll catch everybody next time. Take care.