2012-04-23 3 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がタイプのUserControlである)のようになります。あなたは、私が使用して見ることができるように

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

ViewModelを持っていますが、XAMLとMVVM Light ViewModel Locatorで注意が払われています)。

このソリューションでは、技術的には、再コンパイルなしでナビゲーションを多少変更することができます(たとえば、任意の順序でシャッフルできます)が、文字列プロパティを照合するよりも、これを処理する方が良い方法が必要です。私は、他のプロパティと一緒にロードすることができるようにUser Controlをシリアル化することを検討しましたが、これまでは運がありませんでした。どのように移動し、改善するか/これを変更する上の任意のアイデア?

ありがとうございます!

答えて

2

確かに、より良い方法があります。 :-)

Microsoft Extensibility Framework (MEF)をご覧ください。 WPFとMVVMでうまく動作します。

ランタイムの間にオンザフライでアプリケーション部品を簡単に作成することができます。要するに

、あなたは属性[Export]でどこかにロードされるようにしたいクラスマーク:

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

    // Do more stuff here 
} 

、エクスポートクラスを使用する必要がありますクラスまたはアセンブリにあなたが[Import]属性でそれを読み込むことができますが(!):あなたはそれもすべてインポートされたクラスを組み立てるために1-ライナーを使用するのに十分であるかもしれない実装アーキテクチャに応じて

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

    // Do other stuff here 
} 

(これは、以下の参照先のチュートリアルとは異なるアプローチを使用しています):

CompositionInitializer.SatisfyImports(this); 

それだけです!

(あるとしてがないは、これらの例を取るか、私はポイントを取得したい。私の代わりに代わりに、クラスの輸出のstringsinterfacesPropertiesを使用することをお勧めします。あなたは、よりエレガントをたくさん見つけることができますネット上のスニペット。ここで:-))

あなたが始めるためのチュートリアルを見つけることができます。 Getting started with Managed Extensibility Framework (MEF)

+0

はそれを動作させるには、この朝のビットのためにこれに従事し、それは優れたソリューションです!どうもありがとう!私は思考パターンでXMLに悩まされていましたが、これはナビゲーションを処理するもっときれいな方法です。 –

+0

@AmadeusHein:私が手伝ってくれてうれしいです。 MEFは、多くの目的のために本当に素晴らしいです。ここ2年間は私がすでにいくつかのプロジェクトで取り組んでいましたが、今は真っ暗になっています。なぜ私がMEFをあまり長くは避けようとしたのか分かりません... –

0

なぜ反射を使用しませんか?

あなたはActivator.CreateInstanceを使用して、ビューの列に渡すことができます。

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

object obj = Activator.CreateInstance(asmName, typeName).Unwrap() as UserControl; 
関連する問題