2016-05-16 11 views
0

私はMVVMの周りに頭を抱えようとしていますが、現在はナビゲーションの操作方法に固執しています。フレームとCombobox MVVMを使用したナビゲーション

現在、私はページがあり、そのページ内にフレームがあり、そのフレームはさまざまな他のページでフレーミングを担当しています。ナビゲーションは以前はドロップダウンボックスで処理されていましたが、選択を変更するとそのようにナビゲートしました。

mvvmを壊してしまうモデルビューからフレームに触れることなく、どうやってこれを行うことができるのか分かりません。

私が達成しようとしているのは、コンボボックスをクリックし、アイテムを選択して、次にフレームを正しいビューに移動させることです。

私はMVVMでプリズムやその他のフレームワークを使用していません。すべて手動で行うようにしています。

答えて

1

ComboBoxは、メインビューモデルによって公開されたフレームアイテムのObservableCollectionを表示し、ビューモデルは選択したアイテムに対して別のプロパティを持ちます。

メインビューモデルとフレームアイテムビューモデルはすべて、INotifyPropertyChangedを実装するViewModelBaseクラスから継承しています。

ので、C#の:

public ObservableCollection<ViewModelBase> FrameItems { get; protected set; } 

private ViewModelBase _selectedFrameItem; 
public ViewModelBase SelectedFrameItem { 
    get { return _selectedFrameItem; } 
    set { 
     value = _selectedFrameItem; 
     // Defined in ViewModelBase 
     OnPropertyChanged(); 
    } 
} 

あなたのメインのviewmodelは、コンストラクタでFrameItemsを移入します:

public MainViewModel() 
{ 
    FrameItems = new ObservableCollection<ViewModelbase> { 
     new IceCreamMenu(), 
     new SmurfOptions(), 
     new MagicSparklePonyFourierTransformConfiguration() 
    }; 
} 

すべてのフレーム項目はViewModelBaseのサブクラスです。それは、子のもののセットのObservableCollectionsを含む通知でプロパティを公開します。そして、ちょうどそれのためのデータ型を書くことでそれを表示します。

ViewModelBaseクラスにString Title { get; set; }プロパティを指定したとします。あるいは、ViewModelBaseのサブクラスを作成して、Titleを導入することもできます。あなたの電話。ここでは簡潔にするためにViewModelBaseに入れてみましょう。

XAML - これはすべてのレイアウトを省略しますが、ここでは必要ありません。

<ComboBox 
    ItemsSource="{Binding FrameItems}" 
    SelectedItem="{Binding SelectedFrameItem}" 
    DisplayMemberPath="Title" 
    /> 

<Frame Content={Binding SelectedFrameItem}" /> 

でも、SelectedFrameItemとどうすればいいですか?

Easy!たとえばViewModelDataTemplates.xamlというリソースディクショナリを作成し、App.xamlにマージして、その内容がアプリケーションのすべてのXAMLで「可視」になるようにします。

App.xaml

<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <!-- Source is a relative path from project root directory --> 
      <ResourceDictionary Source="ViewModelDataTemplates.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

...プラスどんなテーマのものまたは何でも。

ViewModelDataTemplates.xamlには、フレームアイテムクラスのデータテンプレートを定義します。

あなたはFlavors

public ObservableCollection<IceCreamFlavor> Flavors { get; protected set; } 

のコレクション...とSelectedFlavorで、IceCreamMenuのviewmodelを持っていると言います。リソース辞書のxmlns:vm属性で適切に名前空間vmを定義します。

ViewModelDataTemplates.xaml

<DataTemplate DataType="{x:Type vm:IceCreamMenu}"> 
    <Grid> 
     <ListBox 
      ItemsSource="{Binding Flavors}" 
      SelectedItem="{Binding SelectedFlavor}" 
      /> 
    </Grid> 
</DataTemplate> 

<DataTemplate DataType="{x:Type vm:IceCreamFlavor}"> 
    <StackPanel Orientation="Horizontal"> 
     <Border 
      Height="20" 
      Width="20" 
      Margin="4" 
      Background={Binding Color, Converter={StaticResource ColorToBrushConverter}}" 
      /> 
     <Label Content="Name" /> 
    </StackPanel> 
</DataTemplate> 

あなたがdatatemplates経由で使用したいUserControlsを既存持っていれば、それは簡単です:あなたはNotesTabViewModelためのビューですNotesTabViewUserControlを持っていると言う、あなたが定義することができこのようなDataTemplate:

<DataTemplate DataType="{x:Type vm:NotesTabViewModel}"> 
    <vw:NotesTabView /> 
</DataTemplate> 
+0

これを行うと、コンボボックスから項目を選択し、インスタンス化するビューモデルの名前だけにフレームの内容を変更します。あたかも.tostring()メソッドを実行するかのようになります。 DataTemplate全体で、データの正しい表示方法が定義されていますか? 既に作成されているページごとに別々のビューを作成しているので、正しいビューに移動する必要があります。 – Tbooty

+0

フレームに配置したビューモデルタイプのデータテンプレートが見つからないようです。 App.xamlでdatatemplates.xamlをマージしていますか? –

+0

@Tbooty私の回答 –

0

@EdPlunkett:私がやったように各ビューのDataTemplateをする代わりに、あなたはViewModelToViewConverterを使用して、選択したページのviewmodelにあなたのフレームをバインドすることができますここでは:https://stackoverflow.com/a/31721236/475727

暗黙的なDataTemplatesとDataTemplateSelectorsはWPFとXAMLに固有のものなので、推奨されるソリューションだと思うが、ナビゲーションには適していないと思う。 DRYの原則に違反するとハックして臭いがします。

+0

ありがとう、私はそれを見てみましょう。もちろん、それは何らかの種類のIoC設定を含むことを意味します。 –

+0

しかし、暗黙的なテンプレートがWPFでしか動作しない場合、他の場所ではあまり解決しません。 –

関連する問題