2012-04-23 40 views
2

我正在處理桌面應用程序的導航部分,並且有點問題。請求是導航應該是動態的,以便您可以切換視圖的順序而無需重新編譯(理想情況下還可以添加視圖而不重新編譯)。使WPF導航動態 - 使用XML文件?

目前我正在使用XML來定義要顯示哪些窗口,它應該有哪個頭以及頁腳應該是什麼樣子。這裏的XML現在的樣子:

<?xml version="1.0" encoding="utf-8" ?> 
<ArrayOfViewState xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <ViewState ViewName="WelcomeView" Header="Welcome to the Application" FooterButton1="Quit" FooterButton2="Back" FooterButton3="Next" /> 
    <ViewState ViewName="LicenseView" Header="Licence Agreement" FooterButton1="Quit" FooterButton2="Back" FooterButton3="Next" /> 
    <ViewState ViewName="LoginView" Header="Log in" FooterButton1="Quit" FooterButton2="Back" FooterButton3="Next" /> 
    <ViewState ViewName="InstallationView" Header="Installing..." FooterButton1="Cancel" FooterButton2="None" FooterButton3="Next" /> 
    <ViewState ViewName="UpdateView" Header="Updating..." FooterButton1="Cancel" FooterButton2="None" FooterButton3="Next" /> 
    <ViewState ViewName="FinishedView" Header="Finished!" FooterButton1="None" FooterButton2="None" FooterButton3="Finish" /> 
</ArrayOfViewState> 

當我匹配這個代碼它看起來像這樣(viewState.View類型是用戶控件的):

... 
case "WelcomeView": 
    viewState.View = new WelcomeView(); 
... 

正如你可以看到我使用在XML中的ViewName屬性來匹配和創建我的視圖(它們也有一個ViewModel,但通過XAML和MVVM Light ViewModel Locator注意到了這一點)。

該解決方案在技術上允許在不重新編譯的情況下對導航進行一些更改(例如,您可以按照自己喜歡的方式隨便調整順序),但必須有更好的方法來處理此問題,而不是匹配字符串屬性。我試着查看序列化用戶控件,以便我可以將其與其他屬性一起加載,但到目前爲止,我沒有運氣。任何想法如何去改善/改變這個?

謝謝!

回答

2

事實上,有一個更好的辦法。 :-)

看看Microsoft Extensibility Framework (MEF)。它適用於WPF和MVVM。

它可以讓你在runtine的過程中輕鬆地編寫應用程序部分

總之,你標記要一個類被別的地方裝有一個屬性[Export]

[Export(typeof(ViewContainer))] 
public class ViewContainer 
{ 
    public string ViewName = "WelcomeView"; 
    public string Header="Welcome to the Application" 

    // Do more stuff here 
} 

而且在類或組件應使用導出類,你可以用[Import]屬性加載它:

public class ClassInOtherAssembly 
{ 
    [ImportMany] 
    internal ObservableCollection<ViewContainer> m_MyViews { get; set; } 

    // Do other stuff here 
} 

根據您實現它甚至可能是足夠使用1襯墊組裝所有進口類(這比使用以下引用的教程不同的方法架構(!) ):

CompositionInitializer.SatisfyImports(this); 

就是這樣!

(不要拿這些例子,是的,我只是想給點意見,我建議使用 Properties代替stringsinterfaces,而不是類出口。你會發現很多更優雅的在網絡上的片段。:-))

在這裏你可以找到一個教程,讓你開始: Getting started with Managed Extensibility Framework (MEF)

+0

今早曾參與開發本作有點讓它運行,這是一個很好的解決方案!非常感謝!我被困在了我的思維模式中,但是這是一種處理導航的更簡潔的方式。 – 2012-04-24 06:45:07

+0

@AmadeusHein:我很高興能幫上忙。 MEF對於很多目的來說非常棒。儘管過去兩年我已經在一些項目中使用過它,但我現在正在深入研究。我不知道爲什麼我試圖避免MEF這麼久...... – 2012-04-24 07:24:22

0

爲什麼不使用反射?

你可以使用Activator.CreateInstance並傳入您的視圖的字符串:

string asmName = "YourAssembly"; 
string typeName = "YourViewName"; 

object obj = Activator.CreateInstance(asmName, typeName).Unwrap() as UserControl;