web-dev-qa-db-ja.com

MVVM-lightとWPFでビュー/ユーザーコントロールを切り替える最良の方法は何ですか?

私はWPFとMVVMに比較的慣れていないので、アプリケーションでユーザーコントロールまたはビューを簡単に切り替える方法を見つけました。

Winformsでは、コントロールにそれ自体を削除させるには、単純にthis.Parent.Controls.Remove(this);と言います。

WPFには汎用的なParentコントロールはありません。特定のタイプ(つまりグリッド)に型キャストしてから削除する必要があります。

これもMVVMアーキテクチャを壊すようです。 datacontextは常にviewmodellocatorであるため、コードからdatacontextを変更できないという事実を除いて、うまく機能するデータテンプレートとコンテンツプレゼンターも試しました。

ページはWPFでこれを行うための受け入れ可能な方法ですか?カスタムのusecontrolを持つグリッドがあり、viewModelの変数に基づいてそれを切り替えたい場合はどうなりますか?最も単純なタスクはWPFでは簡単に実行できないようです。

24
JReed

親ViewModelでこれを行います。

たとえば、ページ(PageViewModelと呼びます)に2つのビュー(ViewModelAViewModelB)がある場合、PageViewModelCurrentViewというプロパティがあり、これによりどのビューが表示されるかが決まります。いつ PageViewModel.CurrentViewViewModelAのインスタンスに設定し、ViewAのDataTemplateを使用してコンテンツを描画します。 ViewModelBのインスタンスに設定すると、ViewBのDataTemplateが表示されます。

<DataTemplate DataType="{x:Type local:PageViewModel}">
    <ContentControl Content="{Binding CurrentView}" />
</DataTemplate>

<DataTemplate DataType="{x:Type local:ViewModelA}">
    <TextBlock Text="I'm ViewModelA" />
</DataTemplate>

<DataTemplate DataType="{x:Type local:ViewModelB}">
    <TextBlock Text="I'm ViewModelB" />
</DataTemplate>

親ビュー(この場合はPageViewModelのDataTemplate)からビュー切り替えコマンドを呼び出すのが理想的ですが、ViewModelA/B内からビューを切り替えたい場合は、オブジェクトが取得されたときに手動でイベントをフックできます。作成した (CurrentView.ChangeViewCommand = this.ChangeViewCommand)またはメッセージングシステムを調べます。 MVVM Lightには単純なMessengerクラスがあり、これはかなり使いやすいか、またはPrismにはより高度なEventAggregatorがあります

同じViewModelのビューを切り替える場合は、使用するビューを決定するために使用されるModeプロパティをお勧めします。例えば:

<DataTemplate x:Key="ViewA" DataType="{x:Type local:MyViewModel}">
    <TextBlock Text="I'm ViewModelA" />
</DataTemplate>

<DataTemplate x:Key="ViewB" DataType="{x:Type local:MyViewModel}">
    <TextBlock Text="I'm ViewModelB" />
</DataTemplate>

<DataTemplate DataType="{x:Type local:MyViewModel}">
    <ContentControl Content="{Binding }">
        <ContentControl.Style>
            <Style TargetType="{x:Type ContentControl}">
                <Setter Property="ContentTemplate" Value="{StaticResource ViewA}" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Mode}" Value="2">
                        <Setter Property="ContentTemplate" Value="{StaticResource ViewB}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ContentControl.Style>
    </ContentControl>
</DataTemplate>

[〜#〜]編集[〜#〜]

私は実際にこの種の質問がたくさん出てくるのを見ます、それでそれについて何かを投稿しました ここ 誰かが興味があれば

38
Rachel