 On today's toolbox, we're going to dig deeper into XAML Islands and we'll see what treasure we can find. Hi, welcome to Visual Studio Toolbox. I'm your host Robert Green and joining me today is Adam Brayden. Hey, Adam. Hello, Robert. Welcome back on the show. Thank you. Thank you for having me. We did a two-parter on modernizing existing Windows desktop apps. In the second part, which aired last week, we talked about XAML Islands a little bit briefly. Today, we decided that you come back and do a bit more of a deep dive into XAML Islands to get a little bit more into some of the use cases and show how it works. We felt like we skimmed over it a little bit last episode, so let's dive into it a little more. Yeah. In the previous episode, I showed some of the easy drag-and-drop experiences provided by the Windows Community Toolkit, which provides wrapper controls for the media player and WebView and Ink Canvas and things like that. I hinted at using the XAML host control to load any or I did show using the XAML host control to load any control dynamically. Right. What I didn't really get into showing was actually building a UWP user control to get that full dynamic UWP XAML experience and how to load that into your WinForms and WPF applications. The idea is that as you're building a UWP app, there's a bunch of XAML that you have, right, that takes care of the UI. Yes, it's pretty simple to use a control from UWP and UWPF app, but what if you have a bunch of XAML that you basically want to reuse? As well as maybe you want to do some more in-depth XAML fluent design like the transparency, the animations, that sort of thing. So what I wanted to do today was actually show you both how to do the hard way through the XAML host control and all your WPF code, and you'd have to like code all that up yourself, as well as doing it in easier way by building a UWP control. Okay. Cool. Okay. We should mention that you're using the soon to be here Visual Studio 2019 for this demo. Correct. Which at this point is soon? Yes. It's a launch of any April 2nd, I believe it is. Yes. So just a level set. Cool. So what I have here on my desktop right now is the XAML controls gallery. I showed a little bit of this in our previous episode and I just wanted to highlight some things that I'll be showing. One of the examples is the animation interop. With animation oftentimes it draws the user's focus to an activity or something you want them to accomplish. Whether it's a transition from one flow to another on the form, or really drive the importance of something by exploding it in view and then dropping it back down. So the example here in the controls gallery is just a simple blow up of a button. I'll show you how we can do that as well. There's a little bit of code to create this spring animation effect is what it's called. There's another one further down on here, where we've got connected animations between multiple controls, and you can spring all of them together. What I've essentially done is taken the code from this sample and port it into a WPF application using the XAML host. So let's take a look at that. So the first thing with my application here, this is just a simple WPF app. If I go to the designer, you'll see I've got a couple of WPF buttons and text boxes, as well as this wonderful XAML host, Windows XAML host. What I've done here is I've set the- Then just refresh our memory. How do you get that data reference or do something, a NuGet package? Generally, you'll manage your NuGet packages, and if you add a reference to the Microsoft Toolkit here, the Microsoft Toolkit WPF. Got it. That'll give you that XAML host where you can load any content into the form. I also have a reference to WinUI and the SDK contracts. So you can program against the Windows APIs. This example, we're not focusing on those parts as much. But one of the main things, or the primary thing with using the XAML host is you set the initial type name of the control, and you set that to the UWBP type that you want to load. So I'm going to host a stack panel, and then with it in code, I can dynamically load a whole bunch of controls into that stack panel. Once the XAML host is ready for you to start manipulating those controls, it fires the child changed event. So if I go back to my control or my code, you'll see here at the top that I've declared a number of controls, UWP-based controls, that I'll be manipulating in my code. Down here in the child changed event, is where I start initializing those controls. First thing I typically do is get the sender tells me which for the host control, and then I'll get the child which is the stack panel. Okay. Then I'm doing a cool effect here, the acrylic brush. Are you familiar with acrylic in the background? No. Well, let me switch back to the controls gallery real quick and we'll show you a quick example of that. So acrylic is that transparency effect, a little hard to see on the board here. But you can see as I move around it, you can see some transparency of both the background of my desktop and the different things behind it. I've amped up the transparency to be able to show that a little bit better here. So I'm going to apply this background to the everything in the stack panel. So ideally, everything in that Windows XAML host should have a transparent or acrylic feel. The next thing I'm doing here is I'm building up the additional controls. This is the hard or the legwork of initializing all them. I have a couple of text boxes, and then I have a couple of buttons. The buttons I initialize to various sizes and hook up those spring animations to them. Lastly, I just add them to the stack panel and go. So we can take a look at that code, but first let's take a look and run and see what happens. So that the test and the WPF text, and the main window is obviously all WPF, and then inside that are is UWP controls. Correct. You can see it on the big screen here too, but as I move around the transparency effect has applied to the entire XAML host and even the buttons there. Nice. You can see I get the animation effect on these buttons as well, driving my focus and my interaction to those. I also wanted to highlight a couple of things about the UWP intrinsic controls that we've made improvements to compared to the WPF, and you may want to actually pull those into your applications as needed. One example is the infamous typos. I've got caps lock on, but if I do, I have a misspelling here in the word spell check. WPF doesn't help me do anything like that. Another example is emojis. I just saw today that we're on emoji 12. I'm thinking to myself, did I miss one through 11? I'm not sure what that means. I think I missed a few in the way there too, but Windows 10 has a great built-in support for emojis. Some of that does fall through with UTF 8 support for the WPF text box. But one thing you'll notice here, WPF it's only black and white. Right. All right. Now, I created a text box down here in the XAML Island with the UWP control. Look, you get squiggles with words. It has a dictionary. Nice. If I right-click, I get a whole intrinsic- Is it the same dictionary that Word uses, by the way? Is there a single dictionary, do you know? There's a dictionary that's supported by XAML. I'll have to double-check and follow up where it hooks into. Okay. But you can fix that up. Even if it knows some words, it'll actually auto-correct for them. So I misspelled goodbye and it auto-corrected the goodbye. Cool. The last cool little tidbit I'll show you is emojis, and you have color support inside the emoji. Very nice. So. Do you eventually get support for emoji 12? Whatever that comes out. I don't know what number WPF supports, but I'm pretty sure it's not 12. Yeah. So this was an example of just showing you that I can create more complex controls, build them up in my WPF code, and essentially take all that code that's in the XAML's control gallery or out there on the web for UWP, and I can code against it in my WPF app. So. Cool. Let me go ahead and close this or finish that. Yeah. Taking a look at the initialized animations, that's the same exact code that was in the XAML controls gallery. Okay. But this is really not the way we encourage you to do this. So let me ask a question. Is this, are you using a XAML Island? Because I haven't seen any XAML yet necessarily. I've seen you do code. Yeah. Well, in WPF in the designer, you can't mix UWP XAML and WPF XAML. You can't copy and paste. It just won't parse. Okay. Right? You could if you had UWP XAML in a file or some other or even copy, paste it into code, you could use UWP XAML parser. Okay. And then you could load that content into this control. But you are using a XAML Island is the technology that enables you to use the controls from UWP inside a WPF app. Correct. Okay. Because they are both XAML based, even though you can of course create controls and code. Right. So I just wanted to make sure that part was clear. XAML Island is the underlying technology that lets you do that. It's the host. It's the interop layer between an HWIN and the UWP core window hosting technology. Yeah, like those UWP controls I created in code, I could not assign those to the WPF window element. That would fail. Right. I've got to assign them to the XAML host control. Right. Okay. But as you noticed, I had to write a whole bunch of code to initialize just my UI. And that's not a very WPF or XAML-y thing to do. And so what I want to show you next is the approach we're working, the approach that we want you to developers to be able to use going forward and how to mix more complex XAML UI with their existing applications. Right. And so in my second example here, I got the user control that I've built inside of UWP. Mm, OK. Right? Yeah. And I've got, I can view the XAML there as well. And so here I can do all the rich XAML copy and paste and build a user control just like that. Right. And I can build an object model so that people can code against this user control, of course. Oh, yeah. And what I do in my WPF app is now I can go through and in my XAML host control, I can set the initial type name to that user control. Cool. So it's pretty straightforward once you build that. There are a couple of things you need to do in order to hook it up into the project system. Let me show you the project system right now. Ideally, I've got this item group commented out right now. Ideally, we want a project reference to just work. There's a couple of bugs we're still working through with .NET Core 3 in the project system. So you have to directly reference the output of the DLL today. OK. And then to get XAML to work, you also have to out reference the XBF file. But that's some temporary hacks. By the time we get to release .NET Core 3, we'll have worked through these solutions. Yep. OK, cool. So that's some tweaks to do the project. You'll notice I am actually using the .NET Core 3 project here. Yeah. OK. And the reason- Does it have to be? The question- the answer is it depends. OK. So if you remember last time I mentioned that with XAML Islands, there's some challenges mixing different types of .NET Core or .NET. You can't fix .NET Framework to consume a .NET Core application- component. And so a managed .NET Core component. So if I was writing a native control, a C++ UWP control, then yes, I could use it easily in .NET Framework apps or my .NET Core apps. If I'm writing a managed UWP control, those will only work in .NET Core apps. Oh. So you have an existing WPF app written full blown framework. And C-Sharp, yep. C-Sharp. You have a UWP app written to the version of .NET that is part of UWP. UWP. You're saying that you can't create that user control and use it in the WPF app unless the WPF app is migrated to .NET Core 3? Let me clarify. OK. The UWP control, if it is written in C-Sharp, can only work on .NET Core 3 applications. If the UWP control is written in C++ native, it can work in .NET Framework and .NET Core apps. So if you are building a lot of components that you want to reuse in these scenarios, you'll probably want to use C++ if your customers are .NET Framework. Assuming you know C++. Yeah. OK. Well, all of Windows UI is written in C++. Sure. And so we are working to make sure there's some gaps to close in the end-to-end story, but we want Windows UI to be usable through XAML Islands in .NET Framework apps and .NET Core apps. OK. But a lot of efforts being put into .NET Core and carrying things forward. And so for right now, we're focusing UWP to interop with .NET Core. OK. Good to know. So that's what I have here is a .NET Core 3 application, along with the managed WinRT user control. The other thing I have to mention here is the manifest file. Right now, I'm in unpackaged application. And XAML Islands has a check in it that says, I can only work on certain builds of Windows. And the way you tell that in an unpackaged application is set the max version tested in that manifest. OK. If I took this out, I would get an error. I could comment that out, and we could save, and we'll see what kind of error we get at runtime. I have to let it rebuild here for a second. But XAML Islands usually pops up a dialogue that says, yeah. I need version 18.226 or higher. Got it. All right. So let's stop and go back to our manifest. Uncomment out that code, save, and rerun it. Maybe I need to rebuild all. What did you specify? I think there's something cached. But the version I specified is 295. OK. And then of course, if somebody tries to run this app on a version less than that, they'll get an error. Yeah, the app manifest will fail to load or force it to not to load. Probably put a check in your code to check before you get that far, like I'm a startup of the app or something. Well, this isn't the app manifest. So the OS will actually typically fail it to load. OK. Right? All right. And so it's a similar application. You'll can see that I added the acrylic effect with the XAML Islands. Kind of going dark and light, depending on the background there as well. And I've got, in this example, I just had a pop-up menu for a flyout here. And I've got this similar to the text box here. Apparently, we need to put spell checking on button text. Yeah. Oh, very good. Good catch. Cool. And so, yeah. So what I've shown you there is the hard way of adding a whole bunch of contents to your existing WPF applications or a simpler way by building a UWP control. Yeah. I think that adding that to your form. Yeah. That seems the right place, a good place to start. You've built some UI in a UWP app that you want to be able to reuse in your WPF app. It could be login screen. It could be a particular functionality because you have multiple versions of the app. And you just want to be able to have that UI in the WPF app. So you just create a user control out of it and use it. And then you need to be a little bit careful about using some of these animation effects because it's going to be in parts of the app, but not others. You don't want to have a form where the button's on the top. Don't do anything, but the button's on the bottom. Do the bottom half of the form has the visual effect, but the top half doesn't. So there's some design carefulness you need to do to not make the app look kind of schizophrenic. There's obviously some reusable components as you architect your app. And you can pick and choose which ones to replace and get some more depth to your application, more interaction, more focus to the flows of the app. Maybe replace the, for simpler forms, replace the whole UI with the user control. You might ultimately decide that you just want the whole UI to be rewritten as a UWP and then just reuse the code. Get to the point where that's AskW or DemandW. Cool. I did have one more surprise for you. Sweet. I love surprises. Last time, actually in the first Toolbox session, we had ported an app to .NET Core. And then I was showing you the packaging project work with .NET Core. But when I hit F5, it failed to build. And I wasn't able to truly show it actually running as a .NET Core app running as a package. I've built that here in this solution, fixed the problem. It was actually a UX issue. And I misinterpreted the error message. And so we just skipped past it. But I've got it up and running now. Let's see it. What we've done here in the code is Add notes. Should I add a note to that first episode that lets people know to watch this episode? Or is that breaking into jail and highlighting the fact that we messed up? We'll have to think about that. That could be. Let's see if they notice. And then we can point them that it does work here. Users have noticed mistakes. Viewers have noticed mistakes before. So we'll give them credit. But what I've done here is just simply add a packaging project to this solution. And if you remember, there's the application note. It points to my WPF Core 3 application. And so if I set this as my startup, it's going to have to rebuild that application. And then it's going to package that application. And then it's going to deploy that application to the Windows. And it's going to launch and debug that application. So this pipeline takes a second. But cross your fingers, if I have set up everything correctly, we will get an application launched. Oh, there it is. All right, yay. And so you can see from the icon down below that it's packaged this time, because I don't have the right visual assets hooked up. Cool, cool, cool. But we have a .NET Core 3 application with XAML Islands running in a package. Nice. So I could submit this to the store or pass around the MSIX package for side loading in my enterprise or whatnot. Fantastic. All right, cool. OK. Cool, cool stuff. All right, well, I hope you enjoyed this part three of our two-parter on modernizing your existing desktop apps. Any questions, you know where to reach us. And we will see you next time on Visual Studio Toolbox.