2013-03-20 75 views
2

我在C#中有一個WPF應用程序。C# - 運行時加載xaml文件

我有一個MainWindow類,它繼承自System.Windows.Window類。

接下來我有,我想在運行時加載我的磁盤上的XAML文件:

<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> 

我如何可以加載在運行時的XAML文件?換句話說,我想讓我的MainWindow類正好使用提到的xaml文件,所以我做了而不是想用MainWindow的方法AddChild,因爲它向窗口添加了一個子項,但我想替換爲也是這樣Window參數。我怎樣才能做到這一點?

+1

嘗試使用Xaml Reader。 另請參見http://stackoverflow.com/questions/910814/loading-xaml-at-runtime – citykid 2013-03-20 19:23:54

+0

感謝您的提示,但我已經看過那個頁面 - 一切都有很大的描述,只是根據後,我**不能取代** Window參數到磁盤上的xaml文件 - 我可以**只是添加新的孩子**。 – 2013-03-22 15:32:46

+0

「窗口參數」是什麼意思? top * 標記*是對xaml處理後成爲Window實例的類的描述。如果你想替換MainWindow的實例,那麼問題是誰擁有這個實例,那是變化的地方?然後,您可以使用XamlReader的結果更改此變量。 – citykid 2013-03-22 15:57:15

回答

3

WPF應用程序在默認情況下,在VS模板,一個的StartupUri參數:

<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> 

WPF框架將使用XamlReader使用URI來實例化一個窗口類和顯示它。在你的情況下 - 從App.xaml中刪除此StartUpUri並手動實例化類,以便在從xaml加載其他窗口時隱藏它。

現在添加此代碼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(); 
    } 
} 

要使用另一個窗口中 「替換」 此窗口:

  • 隱藏這個窗口中使用mainWindow.Hide();
  • 用XamlReader讀取您的personal.xaml,它爲您提供加載的Xaml的Window實例。
  • 將其分配給mainWindow(如果需要)並調用Show()來顯示它。

無論您希望應用程序「主窗口」的實例是否擁有應用程序實例的成員,當然是您的選擇。

總之,整個訣竅是:

  • 隱藏主窗口
  • 加載窗口實例
  • 顯示你的窗口實例
+0

完美,非常感謝。正如你所提到的,關鍵是要用一個新的Window實例替代Window實例。 – 2013-03-27 01:24:15

0

簡短的回答: - 不,你不能從Window內部替換Window。沒有什麼可以訪問一個Window派生的對象,說

再回應「哎,這個其他窗口更換一切」裏面: - 你可以,但是,做一些愚蠢的是這樣的:

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(); 
}