2017-07-17 20 views
1

ウィンドウ内に2行のグリッドがあります。最初の行にボタン付きスタックパネルがあります。ボタンをクリックすると、グリッドの2行目にユーザーコントロールが表示されます(私はその部分が機能しています)。今すぐユーザーコントロールの中にグリッドの2番目の行の内容を変更する必要がある複数のボタンがあります(現在のユーザーコントロールを別のものに変更)。 Customersのユーザーコントロールのボタンをクリックし、BaseViewModelのNavigationCommandにブレークポイントを設定すると、実際にCurrentViewModelが変更されますが、実際のウィンドウには表示されません。ボタンをクリックするとチャーン・イン・ビューが表示されます。

MainWindow.xaml

<Window x:Class="TestProject.View.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:viewmodel="clr-namespace:TestProject.ViewModel" 
     xmlns:local="clr-namespace:TestProject" 
     xmlns:view="clr-namespace:TestProject.View" 
     mc:Ignorable="d" 
     Title="MainWindow" Width="966" Height="897"> 
    <Window.DataContext> 
     <viewmodel:MainWindowViewModel/> 
    </Window.DataContext> 
<Grid > 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"></RowDefinition> 
     <RowDefinition Height="*"></RowDefinition> 
    </Grid.RowDefinitions> 
    <!--Верхнее меню --> 
    <Grid Grid.Row="0"> 
     <StackPanel HorizontalAlignment="Left" Orientation="Horizontal" > 
      <Button x:Name="Visits" Background="Transparent" Command="{Binding NavigationCommand}" CommandParameter="visits" BorderThickness="0" Width="Auto" Height="Auto" Margin="8,0,0,0">   
        <Image Source="../icon/document-changed.png" Width="16" Height="16"/> 
      </Button> 
      <Button x:Name="Patients" Background="Transparent" Command="{Binding NavigationCommand}" CommandParameter="patients" BorderThickness="0" Width="Auto" Height="Auto" Margin="8,0,0,0"> 
        <Image Source="../icon/document-changed.png" Width="16" Height="16"/> 
      </Button> 
      <Button x:Name="Customers" Background="Transparent" Command="{Binding NavigationCommand}" CommandParameter="customers" BorderThickness="0" Width="Auto" Height="Auto" Margin="8,0,0,0"> 
        <Image Source="../icon/user.png" Width="16" Height="16"/> 
      </Button> 
      <Button x:Name="Goods" Background="Transparent" Command="{Binding NavigationCommand}" CommandParameter="customer" BorderThickness="0" Width="Auto" Height="Auto" Margin="8,0,0,0"> 
        <Image Source="../icon/folder_documents.png" Width="16" Height="16"/> 
      </Button> 
      <Button x:Name="Services" Background="Transparent" Command="{Binding NavigationCommand}" CommandParameter="services" BorderThickness="0" Width="Auto" Height="Auto" Margin="8,0,0,0"> 
        <Image Source="../icon/folder_documents.png" Width="16" Height="16"/> 
      </Button>     
     </StackPanel> 
    </Grid> 
    <ContentControl x:Name="Content" Grid.Row="1" Content="{Binding CurrentViewModel}"></ContentControl> 
    </Grid> 
</Window> 

BaseViewModel

namespace TestProject.ViewModel 
{ 
    public class BaseViewModel : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
     protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 

     public DelegateCommand<string> NavigationCommand { get; set; }   
     public BaseViewModel() 
     {   
      NavigationCommand = new DelegateCommand<string>(OnNavigate);    
     } 

     private void OnNavigate(string navPath) 
     { 
      switch (navPath) 
      { 
       case "customers": 
        CurrentViewModel = new CustomersViewModel();      
        break; 
       case "visits": 
        CurrentViewModel = new VisitsViewModel();      
        break; 
       case "patients": 
        CurrentViewModel = new PatientsViewModel();      
        break; 
       case "customer":      
        CurrentViewModel = new CustomerViewModel(); 
        break; 
       case "visit":      
        CurrentViewModel = new VisitViewModel(); 
        break; 
      } 
     } 

     private object _currentViewModel; 

     public object CurrentViewModel 
     { 
      get { return _currentViewModel; } 
      set 
      { 
       if (_currentViewModel != value) 
       { 
        _currentViewModel = value; 
        OnPropertyChanged(); 
       } 
      } 
     } 
     private object _currentText; 

     public object CurrentText 
     { 
      get { return _currentText; } 
      set 
      { 
       if (_currentText != value) 
       { 
        _currentText = value; 
        OnPropertyChanged(); 
       } 
      } 
     } 
    } 
} 

Customers.xaml

<UserControl x:Class="TestProject.View.Customers" 
      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:TestProject.View" 
      xmlns:viewModel="clr-namespace:TestProject.ViewModel" 
      mc:Ignorable="d"  
      > 
    <UserControl.DataContext> 
     <viewModel:CustomersViewModel/> 
     </UserControl.DataContext> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="25"></RowDefinition> 
      <RowDefinition Height="50"></RowDefinition> 
      <RowDefinition Height="*"></RowDefinition> 
     </Grid.RowDefinitions> 
     <Label Grid.Row="0" Background="#FFF3EB96">Клиенты</Label> 
     <StackPanel Grid.Row="1" Orientation="Horizontal"> 
      <Button Command="{Binding NavigationCommand}" CommandParameter="customer" Background="Transparent" BorderThickness="0" Width="Auto" Height="Auto" Margin="8,0,0,0"> 
       <StackPanel Orientation="Horizontal"> 
        <Image Source="../icon/plus_32.png" Width="32" Height="32"/> 
       </StackPanel> 
      </Button> 

     </StackPanel> 
    </Grid> 
</UserControl> 
+0

CustomersViewModelの参照方法MainWi ndowViewModel?あなたは2つの別々のインスタンスを持っているようです... – mm8

答えて

0

あなたがいるようですすべてのビューモデルの共通基底クラスにCurrentViewModelプロパティを定義する必要があります。これは間違っています。ビュー内のContentControl

は、ビューモデルクラスはとてもMainWindowViewModelCurrentViewModelプロパティにバインドされContentControlには影響しませんCustomersViewModelCurrentViewModelプロパティを設定するの特定のインスタンスに結合します。

MainWindowViewModelを直接参照するか、何らかの種類のメッセンジャー/イベントアグリゲータまたは共有サービス:https://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/を使用してそれらの間を細分化する必要があります。

あなたがそれらを作成するときに、あなたがナビゲートするために、このリファレンスを使用することができMainWindowViewModelを参照して、子ビューモデルを注入した場合:

MainWindowViewModel:

public class MainWindowViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    public DelegateCommand<string> NavigationCommand { get; set; } 
    public BaseViewModel() 
    { 
     NavigationCommand = new DelegateCommand<string>(OnNavigate); 
    } 

    private void OnNavigate(string navPath) 
    { 
     switch (navPath) 
     { 
      case "customers": 
       CurrentViewModel = new CustomersViewModel(this); 
       break; 
      ... 
     } 
    } 

CustomersViewModel:

public class CustomersViewModel 
{ 
    private readonly MainWindowViewModel _vm; 
    public CustomersViewModel(MainWindowViewModel vm) 
    { 
     _vm = vm; 
     NavigationCommand = new DelegateCommand<string>(OnNavigate); 
    } 

    public DelegateCommand<string> NavigationCommand { get; set; } 


    private void OnNavigate(string navPath) 
    { 
     _vm.CurrentViewModel = new SomeOtherViewModel(); 
    } 
} 
関連する問題