2

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?

Peter Sivák
  • 557
  • 7
  • 10
  • 1
    Try Xaml Reader. See also http://stackoverflow.com/questions/910814/loading-xaml-at-runtime – citykid Mar 20 '13 at 19:23
  • Thanks for the tip, but I have already seen that page before - everything there is greatly described, just according to that post, I **cannot replace** the `Window` parameter to one from the xaml file on disk - I can **just add new child** to it. – Peter Sivák Mar 22 '13 at 15:32
  • What do you mean with "Window Parameter"? The top tag *is* a description of the class that becomes an instance of Window after xaml is processed. If you want to replace the instance of MainWindow then the question is who holds this instance, that is where is the variable to change? You can then change this variable with the result from XamlReader. – citykid Mar 22 '13 at 15:57
  • Peter, in your very own interest, if you expect people to make efforts to assist you in the future, you should read, comment and vote for the suggested answers. – citykid Mar 24 '13 at 13:59

2 Answers2

3

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
citykid
  • 9,916
  • 10
  • 55
  • 91
0

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();
}
JerKimball
  • 16,584
  • 3
  • 43
  • 55