2017-01-28 5 views
0

Я полностью понимаю, как реализовать переключатель представления в WPF с использованием команд и шаблонов данных, когда представление управляется VM верхнего уровня, например MainWindowVM. То, с чем я борюсь, - это то, где у меня есть MainWindow, у которого ContentControl привязан к свойству CurrentView, и я хочу обновить представление из представлений внутри элемента управления содержимым Windows, а пользователь контролирует скрытые представления. При загрузке я установил CurrentView в экземпляр моего MainMenuVm, дав мне две кнопки. Я хочу обновить представление на кнопке команды из этого UserControl, но я не могу понять, как обновить свойство CurrentView, поскольку он находится в MainWindowVm, а контекст данных UserControl - MainMenuVm, как установлено в DataTemplate.Как переключить представления в дочерних элементах управления пользователя в WPF?

Я попытался подключить события и получить контекст данных MainWindow, но я не могу заставить его работать. У меня есть класс relayCommand, который я могу использовать для создания свойств ICommand, мне просто нужна помощь при передаче команд из 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(); 

    } 

} 

MainWindow 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

Извините, но я не понимаю , моя работа - разработчик пользовательского контроля, поэтому приложение dev я иногда борюсь с – user3519506

+0

. Здесь я попытался добавить некоторые детали в свой предыдущий ответ, надеюсь, это поможет. – Seb

+0

Большое спасибо @Seb, высоко оценили – user3519506

Смежные вопросы