Loading XAML at runtime?

As Jakob Christensen noted, you can load any XAML you want using XamlReader.Load. This doesn’t apply only for styles, but UIElements as well. You just load the XAML like:

UIElement rootElement;
FileStream s = new FileStream(fileName, FileMode.Open);
rootElement = (UIElement)XamlReader.Load(s);
s.Close();

Then you can set it as the contents of the suitable element, e.g. for

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Foo Bar">
    <Grid x:Name="layoutGrid">
        <!-- any static elements you might have -->
    </Grid>
</Window>

you could add the rootElement in the grid with:

layoutGrid.Children.Add(rootElement);
layoutGrid.SetColumn(rootElement, COLUMN);
layoutGrid.SetRow(rootElement, ROW);

You’ll naturally also have to connect any events for elements inside the rootElement manually in the code-behind. As an example, assuming your rootElement contains a Canvas with a bunch of Paths, you can assign the Paths’ MouseLeftButtonDown event like this:

Canvas canvas = (Canvas)LogicalTreeHelper.FindLogicalNode(rootElement, "canvas1");
foreach (UIElement ui in LogicalTreeHelper.GetChildren(canvas)) {
    System.Windows.Shapes.Path path = ui as System.Windows.Shapes.Path;
    if (path != null) {
        path.MouseLeftButtonDown += this.LeftButtonDown;
    }
}

I’ve not tried switching XAML files on the fly, so I cannot say if that’ll really work or not.

Leave a Comment