Peter Sivák
Peter Sivák

Reputation: 567

C# - load xaml file at runtime

I have a WPF application in C#.

I have a MainWindow class which inherits from a System.Windows.Window class.

Next I have an xaml file on my disk which I want to load at runtime:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="I want to load this xaml file">
</Window>

How can I load that xaml file at runtime? In other words, I want my MainWindow class to use exactly the mentioned xaml file, so I do not want to use the method AddChild of the MainWindow because it adds a child to the window, but I want to replace also that Window parameter. How can I achieve this?

Upvotes: 2

Views: 6161

Answers (2)

citykid
citykid

Reputation: 11070

A WPF application has by default, in the VS template, a StartupUri parameter:

<Application x:Class="WpfApplication2.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         StartupUri="MainWindow.xaml">
</Application>

The WPF framework will use this uri to instantiate a window class using XamlReader and show it. In your case - remove this StartUpUri from App.xaml and instantiate the class manually, so you can then hide it when you load your other window from xaml.

Now add this code to App.xaml.cs

 public partial class App : Application
 {
    Window mainWindow; // the instance of your main window

    protected override void OnStartup(StartupEventArgs e)
    {
        mainWindow = new MainWindow();
        mainWindow.Show();
    }
 }

To "replace" this Window with another window you:

  • hide this window using mainWindow.Hide();
  • read your personal.xaml with XamlReader which gives you the Window instance for the loaded Xaml.
  • assign it to mainWindow (if you want) and call Show() to display it.

Whether you want the instance of your apps "main window" hold a member of the App instance or not is certainly your choice.

In summary, the whole trick is:

  • hide the main window
  • load your window instance
  • show your window instance

Upvotes: 3

JerKimball
JerKimball

Reputation: 16894

Short answer: - No, you cannot replace the Window from inside the Window. There is nothing you have access to inside a Window-derived object that says "hey, replace everything with this other window"

Longer answer: - You can, however, do something silly like this:

private void ChangeXaml()
{
    var reader = new StringReader(xamlToReplaceStuffWith);
    var xmlReader = XmlReader.Create(reader);
    var newWindow = XamlReader.Load(xmlReader) as Window;    
    newWindow.Show();
    foreach(var prop in typeof(Window).GetProperties())
    {
        if(prop.CanWrite)
        {
            try 
            {
                // A bunch of these will fail. a bunch.
                Console.WriteLine("Setting prop:{0}", prop.Name);
                prop.SetValue(this, prop.GetValue(newWindow, null), null);
            } catch
            {
            }
        }
    }
    newWindow.Close();
    this.InvalidateVisual();
}

Upvotes: 0

Related Questions