BrandGhost

Sneak C# Dependencies Into XAML Using MarkupExtension in WPF!

I'm always happy to hear about programming cheat codes. This one is specific to WPF -- but it touches on something that's always been a pain in the butt: Injecting services while still using XAML. In this video, I'll walk you through how you can leverage the MarkupExtension class. This will allow you to provide more context to the XAML processor to leverage dependencies.
View Transcript
when working with WPF I really struggle with trying to get dependency injection to work the same way that I would in other applications but there's an interesting class that allows us to do a little bit more hi my name is Nick centino and I'm a principal software engineering manager at Microsoft in this video I'm going to be talking about WPF and a special class called markup extension markup extension is very interesting because it allows us to do some things in zaml that otherwise we couldn't do and this is one of the areas that I end up fighting WPF and zamel a lot I usually move away completely from this but this class allows us to do some fancy things if that sounds interesting remember to subscribe to the channel and check out that pin comment for my courses on dome train with that said let's jump over to our sample application and see what markup extension is all about okay so on my screen I have some cone you can already see markup extension showing up here but I want to walk through what our application looks like so I'm going to be showing this main window here this is from my splash screen examples as well so when we go to run this we'll see a very bright ugly splash screen but I want to talk about how we normally do Boolean to visibility converters I have videos on this and you can check out at the top here that I have this uh resources section here and this is usually I guess in like a traditional sense how you might say hey look I want to include a converter and we need to have a resource dictionary to be able to do that so we set this up you can see from line 11 to 13 and then to go use it we go to our control that we're interested in so in this case I am dealing with a cont content control and I want the visibility to be bound to is Wizard visible so this is a wizard control that I'm dropping onto a UI and I want to be able to togg whether or not the Wizard's visible so to make that work we can't go from a Boolean flag to visibility we need to be able to use a converter and that's why you can see right here on line 17 I'm referencing that converter right from our resource dictionary and then indicating that it's one way so the UI itself is not changing that on The View model we're only reading the view model State and I would say this is a pretty traditional way that we go do this now that means if you want to go introduce your own converters or a multiple converters you have to keep piling them into this resource dictionary I'm not a huge fan of that but this is like I said a traditional way that we go about it before we continue on this is just a quick reminder that I do have courses available on dome train if you're just getting started in your programming journey and you want to learn C you can head over to dome train I have a getting started in C course it's approximately 5 hours of content taking you from absolutely no experience to being able to program in C and after that I have my deep dive course which will take you to the next level with another 6 hours of content so that you can start building basic applications head over to dome train and check it out let's head back to the video If we go to look at markup extension and we want to go look at seeing how we can do this with our own converters this is a converter that I've written here and you can see that it's a custom Boolean Tois visibility converter just to give it a different name and it's going to inherit from markab extension the convert methods that we see here this is a pretty typical way that you might go make a Boolean divisibility converter it's not really important because you can go apply this concept to your other converters but the unique part is the markup extension and right here so we can see that we have provide value and this is a i service provider being passed in but this is the override that you need to implement for markup extension now when we go to do this you can see that all that it's doing it's not even leveraging the service provider right like if I make this underscore as a discard you can see nothing's complaining it's not being used so we're just returning this we're basically saying that the value that we want to provide back out as a mark of extension is this converter itself in order to make that go as the next step I just wanted to also mention this value conversion attribute at the top that says which way we can do conversions so helpful for Value converters in this context once we have this markup extension if you were to go build your application if we go back to the main window we can now leverage that directly in here without having to use this Boolean divisibility converter resource dictionary so let me comment this part out obviously this part's going to be upset with us but if we do custom bu into visibility converter and build this we get a successful build and you can see that I don't have a resource dictionary at all so that markup extension is allowing us to see this converter so if I go run this like I said we're going to see this very beautiful splash screen and we should be able to get right after this Splash screen's done this wizard control so the blue part is the wizard control just to kind of call it out the background of the main window was Pure White so the fact that we see this cyan color with these buttons in the bottom and the magenta that is the wizard control now to go again just prove this a little bit more if we go to the default value for whether or not this is visible we'll go see if our converter is doing its job if we run it one more time close the splash you can see it's white now right so we've turned off the visibility of that so that means that our converter is working that's super cool if we go back to here you can see we don't need this at all anymore little bit more clean just a different way to go do this so that you don't have to have the resource collection but it's kind of interesting because markup extension is kind of powerful right it allows us to have more functionality available to us in our zaml now the second part and the final part that I want to talk about in this video is how I traditionally use data contacts and I've made other videos about this but when I'm using WPF I like to try and force dependency injection to happen it's how I like to write software so I'm always fighting against all these WPF paradigms to make it work so you can see in here on line 18 to to 21 I'm creating a data context for my main window usually what I would do is have the main window view model passed in here look like this and then we'd go assign it to the data context right so it would look something like this this is how I like to do my dependency injection with WPF for these examples though I just had it simplified and was just doing this kind of thing but I want to talk about a different approach that we can do and that's because when we go to do this pattern that I was passing in the dependency and even the fact that I have these on the Constructor a lot of the time that can break down in some of the preview capabilities that we have in the editor so that kind of sucks but if we go look at markup extension there's something more that we can do I had this data context set up like this I'm going to go ahead and comment this out okay so at this point we don't have a data context what we're able to do is go back and check out a little bit more below this converter I have this provider for a view model okay so what this is able to do again markup extension markup extension means that we have to have this provideed Value method so what we're able to do is create a view model provider instance and we're passing in the type of the view model and just uh we don't need this here actually I've just made it a field when we have it set up this way what we're able to do is basically we're ignoring this provider okay but we need some provider for our application the way that I have dependency injections set up in my application because this provider is really just for the part that's figuring out the zaml and the resources I have my own dependency injection container set up and I need access to that so that I can go tell from the markup extension perspective hey look I have the type you're interested in so what I've done is I've asking for the current applications properties and I've basically put a service provider inside of here just to show you where that is and when my application's starting up I'm setting a service provider in here if I scroll up a little bit more you can see all my dependency injections set up not really going to matter because you can set Yours up the way that you want but I am setting this property inside of here so that I can access it later jumping back over to here I'm getting the provider back out just doing a little sanity check to make sure it's actually set could have a better error message or something when this is not set and then what I'm doing is I'm asking for the required service and that's going to be the view model how do we go leverage this then because we saw that with the converter and we had this markup extension we can start leveraging it in zaml well I'm going to have this code that I left commented out I'm going to go put this back onto the window itself this is going to be able to see the view model provider let's just build this to make sure it works excellent we can see the view model provider we can see that I'm passing in the type this parameter main window view model and if we go run this now what we're able to do is have a data context set up now I want to prove that this works cuz we're combining two things going on now one is that we're injecting the V model and injecting it in this sense where it's defined in zaml not the Constructor and the other thing is that we're able to get this visibility converter The View model has the flag on it that indicates the visibility that means if this is going to work if I set the default visibility to True with all of these pieces wired up we should see the wizard still right let me go ahead and delete this there is no other view model being passed in from anywhere else okay and in fact let me go ahead and put a break point in here so we can see that this code's going to get hit okay so right on Startup you can see already that I have line 97 being hit I'm going to step through here I am able to get a provider back out and that's because like I said I set that up in the startup of my application it's my I service provider instance so we'll do a null check on that and then the next part this is kind of like a service locator pattern so it is a bit of an anti pattern but I think it's kind of buried in some type of helper classes so maybe not so bad and then we pull out The View model you can see that I have is Wizard visible is set to true on The View model and this is the default so if I scroll back up maybe this part needed a little bit more explanation but the way my dependency injection is set up it's going to scan for all of the types okay so it's doing a check to find all of the types and it's going to uh register them as basically Singleton instances so it's finding this registered a Singleton instance of this which has this set to true and that's why if I hover over this if we look inside of it is Wizard visible is set to true now if I leave this okay our splash screen is about to finish I'll close it off with the wizard is visible if this was all broken we wouldn't even see the wizard the fact that the visibility is being converted from a Boolean flag from True to visible means that this is all set up properly and to prove it I'll take the break point off of here and what I'm going to do now is change the default visibility to false if we go run this basically what we should end up seeing is just a white window after the splash screen's gone we'll close it off and there's the white window so the whole conversion process is still working it's just that we have the default set to false so to recap of what we've seen here we did end up having a Boolean to visibility converter that we wrote ourself using the markup extension here and then providing this which is the current instance if I go back to here that meant that we could do this converter just like this without a resource dictionary and then the second thing we looked at was using a markup extension so down here for our view model provider this meant that we can get an instance of our view model if you're using some type of your own dependency injection framework if we have access to the provider so the I service provider we can ask for the service in this case the view model that we're interested in and if we go back to the examl we can see right at the top here on line 10 this is is where we're leveraging that we're setting the data context leveraging this view model provider to be able to get the main Windows view model now personally again for my own way that I like to develop I still will probably be passing things in as a view model through the Constructor that's just the way that I like to do it but I do think there's an opportunity here that if you're unable to for some reason take advantage of this Constructor pattern that you can go ahead and lean into something like this view model provider and you could potentially do this for other services as well I hope you found that interesting and helpful thanks so much for watching and I'll see you next time

Frequently Asked Questions

What is a MarkupExtension in WPF and how does it help with dependency injection?

A MarkupExtension in WPF is a special class that allows you to define custom behaviors in XAML that you can't achieve otherwise. It helps with dependency injection by allowing you to create instances of your converters or view models directly in XAML without needing to define them in a resource dictionary, making your code cleaner and more manageable.

How can I use a custom Boolean to Visibility converter with MarkupExtension?

You can create a custom Boolean to Visibility converter by inheriting from MarkupExtension and implementing the ProvideValue method. This allows you to return an instance of your converter directly in XAML, eliminating the need for a resource dictionary and simplifying your bindings.

What are the advantages of using MarkupExtension over traditional resource dictionaries in WPF?

Using MarkupExtension allows for a cleaner and more streamlined approach to defining converters and view models directly in XAML. It reduces the clutter of resource dictionaries and makes it easier to manage dependencies, especially when working with dependency injection, as you can directly reference your services in the XAML.

These FAQs were generated by AI from the video transcript.
An error has occurred. This application may no longer respond until reloaded. Reload