First some background: I'm working on an application and I'm trying to follow MVVM conventions writing it. One thing I'd like to do is to be able to give the application different "skins" to my application. The same application, but show one "skin" for one client and a different "skin" for another.
And so my questions are:
1. Is it possible to load a xaml file at run time and "assign" it to my app?
2. Can the xaml file be an external file residing in a different folder?
3. Can the application switch to another xaml file easily, or only at startup time?
So where should I start looking at for information on this? Which WPF methods, if they exist, handle this functionality?
Thanks!
Edit: the type of "skinning" I'm wanting to do is more than just changing the look of my controls. The idea is having a completely different UI. Different buttons, different layouts. Kinda like how one version of the app would be fully featured for experts and another version would be simplified for beginners.
As it's already mentioned in other answers, you can use
XamlReader.Load
.If you are looking for a more straightforward example, here is an example showing how easily you can create a control from a string variable containing the XAML:
And as the usage:
Check out http://www.codeproject.com/Articles/19782/Creating-a-Skinned-User-Interface-in-WPF - Josh Smith wrote a great article on how to do skinning in WPF.
I made simple markup extension, which loads xaml:
Usage:
This find and load MyFirstView.xaml file
And this fill whole UserControl (find and load MySecondView.xaml file)
I think this is fairly simple with the XamlReader, give this a shot, didn't try it myself, but I think it should work.
http://blogs.msdn.com/ashish/archive/2007/08/14/dynamically-loading-xaml.aspx
As Jakob Christensen noted, you can load any XAML you want using
XamlReader.Load
. This doesn't apply only for styles, butUIElement
s as well. You just load the XAML like:Then you can set it as the contents of the suitable element, e.g. for
you could add the
rootElement
in thegrid
with:You'll naturally also have to connect any events for elements inside the
rootElement
manually in the code-behind. As an example, assuming yourrootElement
contains aCanvas
with a bunch ofPath
s, you can assign thePath
s'MouseLeftButtonDown
event like this:I've not tried switching XAML files on the fly, so I cannot say if that'll really work or not.
I have done loading XAML at runtime, here is a short example