2017-01-28 10 views
0

私は、ビューがMainWindowVMのようなトップレベルのVMによって管理されているときに、コマンドとデータテンプレートを使ってWPFでビュースイッチを実装する方法を完全に理解しています。私が苦労しているのは、CurrentControlプロパティにバインドされたContentControlを持つMainWindowを持つ場所で、Windowsのコンテンツコントロール内のビューからビューを更新し、ユーザーコントロール内のビューを更新したいところです。私はCurrentViewを私のMainMenuVmのインスタンスに設定し、2つのボタンを与えました。私が望むのは、このUserControlからのボタンコマンドのビューを更新することですが、MainWindowVmにあるのでCurrentViewプロパティを更新する方法を理解できません。また、UserControlのデータコンテキストはDataTemplateで設定したMainMenuVmです。WPFの子ユーザーコントロールでビューを切り替えるにはどうすればよいですか?

私はイベントを接続し、MainWindowのデータコンテキストを取得しようとしましたが、動作させることができません。 ICommandのプロパティをインスタンス化するために使用できるrelayCommandクラスがあります。私は、userControlからMainWindowにコマンドを渡すだけで助けが必要です。

私は必要に応じてコードを投稿できます。

ViewModelBase

public class ViewModelBase : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

MainWindowVm

public class MainWindowVm : ViewModelBase 
{ 
    private ViewModelBase _currentView; 

    public ViewModelBase CurrentView 
    { 
     get { return _currentView; } 
     set 
     { 
      _currentView = value; 
      NotifyPropertyChanged(); 
     } 
    } 

    public MainWindowVm() 
    { 
     CurrentView = new MainMenuVm(); 

    } 

} 

メインウィンドウのXAML

を:

私は明確にするために私のコードのいくつかの例を提供しようとしています

<Window.DataContext> 
     <vm:MainWindowVm/> 
    </Window.DataContext> 
    <Window.Resources> 
     <DataTemplate DataType="{x:Type vm:MainMenuVm}"> 
      <uc:MainMenuUserControl/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type vm:NewJobVm}"> 
      <uc:NewJobUserControl/> 
     </DataTemplate> 
    </Window.Resources> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="60"/> 
      <RowDefinition/> 
      <RowDefinition Height="60"/> 
     </Grid.RowDefinitions> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="60"/> 
      <ColumnDefinition/> 
      <ColumnDefinition Width="60"/> 
     </Grid.ColumnDefinitions> 
     <ContentControl Style="{DynamicResource PanelInnerStyle}" 
         Grid.Row="1" 
         Grid.Column="1" 
         Content="{Binding CurrentView}" 
         HorizontalContentAlignment="Center"/> 

    </Grid> 
</Window> 

MainMenuuserontrol

<UserControl x:Class="Invoice.UserControls.MainMenuUserControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:Invoice.UserControls" 
      xmlns:vm="clr-namespace:Invoice.ViewModels" 
      mc:Ignorable="d" 
      HorizontalAlignment="Center"> 

    <StackPanel Orientation="Horizontal"> 
     <Button Width="120" 
       Height="120" 
       Margin="5" 
       ToolTip="Add New Job"> 

      <Image Source="/Resources/Add_Green.png" 
        Height="32" 
        Width="32"/> 

     </Button> 

     <Button Width="120" 
       Height="120" 
       Margin="5" 
       ToolTip="Load Jobs"> 
      <Image Source="/Resources/Folder.png" 
        Height="32" 
        Width="32"/> 
     </Button> 
    </StackPanel> 
</UserControl> 

答えて

1

MainWindowVmは、そのネストされたのviewmodelsにデリゲートを与えるために、それは次のようになり行うための簡単な方法:

public enum MenuCommands 
{ 
    NEXT_PAGE = 0, 
    PREVIOUS_PAGE = 1 
} 

public class MainMenuVm : ViewModelBase 
{ 
    public MainMenuVm (Action<MenuCommands> menuCommand) 
    { 
     _menuCommands = menuCommand; 
    } 

    private Action<MenuCommands> _menuCommands; 

    /// <summary> 
    /// Command binded from MainMenuUserControl.xaml 
    /// </summary> 
    public ICommand NextPageCommand 
    { 
     get { return _nextPageCommand ?? (_nextPageCommand = new DelegateCommand (NextPage)); } 
    } 
    private ICommand _nextPageCommand; 

    private void NextPage () 
    { 
     // lets ask our MainWindowVM to switch the view 
     _menuCommands (MenuCommands.NEXT_PAGE); 
    } 
} 

public class MainWindowVm : ViewModelBase 
{ 
    /* ... */ 

    public MainWindowVm () 
    { 
     CurrentView = new MainMenuVm (Navigate); 

    } 

    private void Navigate (MenuCommands command) 
    { 
     // Implement your view switching logic here, like: 

     switch (command) 
     { 
      case MenuCommands.NEXT_PAGE: 

       // CurrentView = new SomeOtherViewModel (); 

       break; 
      case MenuCommands.PREVIOUS_PAGE: 

       // CurrentView = new SomeOtherViewModel (); 

       break; 
      default: 
       break; 
     } 
    } 
} 
+0

申し訳ありませんが、私は理解していません私の仕事はカスタムコントロール開発者なので、アプリケーション開発者は時々 – user3519506

+0

と闘っています。私はこれまでの答えでいくつかの詳細を追加しようとしました。 – Seb

+0

ありがとうございます@Seb、大変感謝しています – user3519506

関連する問題