Question

I know that it is possible to parse an XAML - file at runtime and create an UIElement which I can insert into my pages grid, no problem there.

But what I really want is to replace the whole XAML of my page or usercontrol, is that possible, too?

Reasoning:

I want to give the users of my application the opportunity to have the application run (startup takes ages - and that can't be shortened because of some legacy issues) and simply update the view by "ctrl + s" in Blend.

Was it helpful?

Solution

It depends on whether you attach event handlers or use the "Name" or "x:Name" attribute to access UI elements from code.

Nice pure MVVM application

First let's assume you have a nice pure MVVM application that uses binding and commands exclusively, so you aren't using named UI elements or code-behind event handlers. Good for you: You have a nice clean application architecture and I like you.

In that case all you need to do is create a temporary copy of your XAML file with the x:Class attribute removed, and call:

 Application.LoadComponent(this, uriToTemporaryCopy);

Ugly impure non-MVVM application

Now let's assume you used an element named with x:Name or Name from your code-behind (naughty, naughty, naughty!), or you attached an event handler using XAML (less naughty but not pure either). You don't have a nice clean architecture, but I still like you anyway.

In this case, Application.LoadComponent won't do the trick by itself because these settings require integration with the code-behind. You also need to find a way to invoke the BAML compiler.

Since the code-behind integration is already compiled into your Page or UserControl subclass, there are some restrictions:

  1. You cannot add, remove, or change the sequence of event handler assignments
  2. You cannot change the names or sequences of named elements or add more named elements

If you abide by these rules, in general the generated code that is incorporated into your class will not change, therefore you can load the new XAML file into a running application without breaking anything.

The procedure is:

  1. Compile the XAML file to BAML either by A) building the containing project, B) creating a temporary project and compiling that, or C) directly calling the markup compiler tasks in PresentationBuildTasks.
  2. Use Application.LoadComponent to load the BAML file just as you did for the edited XAML file in the pure solution.

In a compiled .csproj project, any compiled BAML files will be found under the obj/debug or obj/release directory with an extension of .baml. If you call the markup compiler task directly you can decide on the output location.

What is a BAML file?

For those who don't know, BAML is basically a compressed and optimized binary form of XAML, and is the way your XAML is stored inside your .exe or .dll. It also has capabilities for linking directly to generated code, which XAML does not have.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top