WPFのMVVMについて質問があり、私を苦しめています。
なぜこのようなことをしますか?
MainWindow.xaml:
<Window x:Class="MVVMProject.MainWindow"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml">
<Grid>
<ContentControl Content="{Binding}"/>
</Grid>
</Window>
ExampleView.xamlを次のようにセットアップします。
<ResourceDictionary xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
xmlns:vms="clr-namespace:MVVMProject.ViewModels">
<DataTemplate DataType="{x:Type vms:ExampleVM}" >
<Grid>
<ActualContent/>
</Grid>
</DataTemplate>
</ResourceDictionary>
そして、次のようなウィンドウを作成します。
public partial class App : Application {
protected override void OnStartup(StartupEventArgs e) {
base.OnStartup(e);
MainWindow app = new MainWindow();
ExampleVM context = new ExampleVM();
app.DataContext = context;
app.Show();
}
}
このようにできるとき:?
App.xaml:(スタートアップウィンドウ/ビューの設定)
<Application x:Class="MVVMProject.App"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
StartupUri="ExampleView.xaml">
</Application>
ExampleView.xaml:(ResourceDictionaryではないウィンドウ)
<Window x:Class="MVVMProject.ExampleView"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
xmlns:vms="clr-namespace:MVVMProject.ViewModels">
>
<Window.DataContext>
<vms:ExampleVM />
</Window.DataContext>
<Grid>
<ActualContent/>
</Grid>
</Window>
基本的には「DataTemplateとして表示」(VaD)vs.「Windowとして表示」(VaW)
比較についての私の理解は次のとおりです(VS 2008を使用しているため、Blendabilityやその他のものが不足していることに注意してください)。
ここで何が起こっているのでしょうか? XAMLでウィンドウを構築し、VMのプロパティを介してデータにクリーンにアクセスし、それで完了することはできませんか?コードビハインドは同じです(実質的にnil)。 Viewのすべての項目をResourceDictionaryにシャッフルする必要がある理由を理解するのに苦労しています。 (しかし、私はやりたくないwrong;-))
それも重要ですか?見逃したことはありますか?読んでくれてありがとう。 :O
MVVMの理解を深めてくれたRachel LimとNick Polyakに感謝します
編集:マイナーフローの変更
ViewModelに応じて動的にビューを切り替える場合、人々はDataTemplates
をそのように使用します。
<Window>
<Window.Resources>
<DataTemplate DataType="{x:Type local:VM1}">
<!-- View 1 Here -->
</DataTemplate>
<DataTemplate DataType="{x:Type local:VM2}">
<!-- View 2 here -->
</DataTemplate>
</Window.Resources>
<ContentPresenter Content="{Binding}"/>
</Window>
そう、
Window.DataContext
がVM1
のインスタンスである場合、View1
が表示されます。
で、もし
Window.DataContext
はVM2
のインスタンスであり、View2
が表示されます。
確かに、1つのビューのみが予想され、変更されない場合はまったく意味がありません。
私はこれが十分に明確であることを願っています:P
VaDでは、ビューモデルはビューについて何も知らないため、ビューモデルのみでビューなしで完全に機能する完全に機能するアプリケーションを構築できます。これにより、完全にコードで駆動できるアプリケーションを作成できるようになります。これにより、GUIなしで統合テストを実行できるようになります。 GUIを介した統合テストは脆弱であることが悪名高い-ビューモデルを介したテストはより堅牢である必要があります。
私の個人的な経験から:両方の作業モデルは、あなたが望むものに依存し、アプリケーションの要件に依存します。 VaD
の背後にある考え方は、コンテンツとコンテナーを切り離すことです。 VaD
を実装すると、このタイプのアイテムを表示するたびに(デフォルトで)このテンプレートを使用できます。 ItemsControls
(リスト、リストビュー、グリッドなど)およびContentControls
でのみバインディングを使用できます。あなたが言ったように、VaD
は、新しいウィンドウを閉じたり開いたりすることなく、ウィンドウのコンテンツを切り替えるために機能します。また、UserControls
を使用してビューを定義し、フォーカスされた要素があれば制御し、コードビハインドを管理することもできます。したがって、データテンプレートは次のようになります。
<ResourceDictionary xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
xmlns:vms="clr-namespace:MVVMProject.ViewModels">
<DataTemplate DataType="{x:Type vms:ExampleVM}" >
<CustomUserControl A="{Binding A}" B="{Binding B}" DataContext="{Binding}" .../>
</DataTemplate>
UserControl
で依存関係プロパティを設定することもできます。これにより、アプリのバインドと分離が許可されるため、作業が簡単になります。
しかし、もちろん、アプリが動的にコンテンツの切り替えを必要としない場合、メインウィンドウまたはその他のウィンドウにVaW
を使用することは問題ありません。実際、VaW
とVaD
の両方を使用できます。この最後のものは、ウィンドウを必要としないアプリの内部アイテムに使用できます。アプリケーションの要件と、アプリの開発にかかる時間に応じて、何が良いかを選択します。この個人的な経験が役立つことを願っています...