2015-10-25 35 views
0

我有兩個對於MainWindow的視圖模型。 我想在視圖模型之間切換。因此,我有一個主視圖模型,讓我給我的第一和第二個視圖模型之間切換:如何將datacontext設置爲不同的視圖模型

class MainViewModel : ViewModelBase 
{ 
    private ViewModelBase _currentViewModel; 

    public ViewModelBase CurrentViewModel 
    { 
     get 
     { 
      return _currentViewModel; 
     } 
     set 
     { 
      if (_currentViewModel == value) 
       return; 
      _currentViewModel = value; 
      OnPropertyChanged("CurrentViewModel"); 
     } 
    } 

    public ICommand FirstViewCommand { get; private set; } 
    public ICommand SecondViewCommand { get; private set; } 
    private bool _canExecuteFirstViewCommand; 
    private bool _canExecuteSecondViewCommand; 

    public MainViewModel(Vokabel model) 
    { 
     VokabelViewModelDeutschLatein _vokabelViewModelDeutschLatein = new VokabelViewModelDeutschLatein(model); 
     VokabelViewModelLateinDeutsch _vokabelViewModelLateinDeutsch = new VokabelViewModelLateinDeutsch(model); 
     _canExecuteFirstViewCommand = true; 
     _canExecuteSecondViewCommand = true; 

     CurrentViewModel = _vokabelViewModelDeutschLatein; 
     FirstViewCommand = new CommandHandler(() => ExecuteFirstViewCommand(_vokabelViewModelDeutschLatein),_canExecuteFirstViewCommand); 
     SecondViewCommand = new CommandHandler(() => ExecuteSecondViewCommand(_vokabelViewModelLateinDeutsch), _canExecuteSecondViewCommand); 
    } 

    private void ExecuteFirstViewCommand(VokabelViewModelDeutschLatein _vokabelViewModelDeutschLatein) 
    { 
     CurrentViewModel = _vokabelViewModelDeutschLatein; 
    } 

    private void ExecuteSecondViewCommand(VokabelViewModelLateinDeutsch _vokabelViewModelLateinDeutsch) 
    { 
     CurrentViewModel = _vokabelViewModelLateinDeutsch; 
    } 
} 

在代碼的主窗口的背後 - 我如何設置的DataContext新視圖模型?

public MainWindow() 
    { 
     Vokabel _Vokabel; 
     MainViewModel _MainViewModel; 

     InitializeComponent(); 
     _Vokabel = new Vokabel(); 
     _MainViewModel = new MainViewModel(_Vokabel.Initialize()); 
     this.DataContext = _MainViewModel; 

    } 

在MainWindow.xaml我有一個按鈕,讓我切換到所述第二視圖模型:

 <Button Grid.Column="1" Content="Deutsch => Latein" Command="{Binding SecondViewCommand}" /> 

如果我運行應用程序,所述第二(或第一)的視圖模型的DataContext不存在。

回答

0

正如我所理解的,當CurrentViewModel屬性發生更改時,您需要即時切換數據上下文。我可以向你建議下一個解決方案。將ContentControl用作主要內容展示器,並根據該屬性的數據更改其提供CurrentViewModel屬性定義的當前內容的數據模板。這裏是基於你的代碼的工作解決方案。 1. XAML代碼:

<Window x:Class="SoContentControlBinding.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:soContentControlBinding="clr-namespace:SoContentControlBinding" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.DataContext> 
    <soContentControlBinding:MainViewModel></soContentControlBinding:MainViewModel> 
</Window.DataContext> 
<Window.Resources> 
    <DataTemplate DataType="{x:Type soContentControlBinding:ViewModelBase}"> 
     <TextBlock Background="Tomato" Text="{Binding Title}"></TextBlock> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type soContentControlBinding:VokabelViewModelDeutschLatein}"> 
     <TextBlock Background="GreenYellow" Text="{Binding Title}"></TextBlock> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type soContentControlBinding:VokabelViewModelLateinDeutsch}"> 
     <TextBlock Background="DeepSkyBlue" Text="{Binding Title}"></TextBlock> 
    </DataTemplate> 
</Window.Resources> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="8*"></RowDefinition> 
     <RowDefinition Height="2*"></RowDefinition> 
    </Grid.RowDefinitions> 
    <ContentControl Content="{Binding CurrentViewModel}"></ContentControl> 
    <Button Grid.Row="1" Content="Deutsch => Latein" Command="{Binding SecondViewCommand}"></Button> 
</Grid> 

2.查看模型碼(chanhges是涉及到我的鹼可觀察到的對象實現):

public class MainViewModel : BaseObservableObject 
{ 
    private ViewModelBase _currentViewModel; 

    public ViewModelBase CurrentViewModel 
    { 
     get 
     { 
      return _currentViewModel; 
     } 
     set 
     { 
      if (_currentViewModel == value) 
       return; 
      _currentViewModel = value; 
      OnPropertyChanged("CurrentViewModel"); 
     } 
    } 
    public ICommand FirstViewCommand { get; private set; } 
    public ICommand SecondViewCommand { get; private set; } 
    private bool _canExecuteFirstViewCommand; 
    private bool _canExecuteSecondViewCommand; 

    public MainViewModel(Vokabel model) 
    { 
     VokabelViewModelDeutschLatein vokabelViewModelDeutschLatein = new VokabelViewModelDeutschLatein(model); 
     VokabelViewModelLateinDeutsch vokabelViewModelLateinDeutsch = new VokabelViewModelLateinDeutsch(model); 
     _canExecuteFirstViewCommand = true; 
     _canExecuteSecondViewCommand = true; 

     CurrentViewModel = vokabelViewModelDeutschLatein; 
     FirstViewCommand = new RelayCommand(() => ExecuteFirstViewCommand(vokabelViewModelDeutschLatein)); 
     SecondViewCommand = new RelayCommand(() => ExecuteSecondViewCommand(vokabelViewModelLateinDeutsch)); 
    } 

    public MainViewModel():this(new Vokabel()) 
    { 

    } 

    private void ExecuteFirstViewCommand(VokabelViewModelDeutschLatein vokabelViewModelDeutschLatein) 
    { 
     CurrentViewModel = vokabelViewModelDeutschLatein; 
    } 

    private void ExecuteSecondViewCommand(VokabelViewModelLateinDeutsch vokabelViewModelLateinDeutsch) 
    { 
     CurrentViewModel = vokabelViewModelLateinDeutsch; 
    } 
} 

3.型號代碼:

public class VokabelViewModelLateinDeutsch:ViewModelBase 
{ 
    public VokabelViewModelLateinDeutsch(Vokabel model) 
    { 
     Title = "VokabelViewModelLateinDeutsch"; 
    } 
} 

public class VokabelViewModelDeutschLatein : ViewModelBase 
{ 
    public VokabelViewModelDeutschLatein(Vokabel model) 
    { 
     Title = "VokabelViewModelDeutschLatein"; 
    } 
} 

public class Vokabel 
{ 
} 

public class ViewModelBase:BaseObservableObject 
{ 
    private string _title; 

    public string Title 
    { 
     get { return _title; } 
     set 
     { 
      _title = value; 
      OnPropertyChanged(); 
     } 
    } 
} 

4. BaseObservableObject實現(以及其他mvvm部分):

public class BaseObservableObject : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser) 
    { 
     var propName = ((MemberExpression)raiser.Body).Member.Name; 
     OnPropertyChanged(propName); 
    } 

    protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null) 
    { 
     if (!EqualityComparer<T>.Default.Equals(field, value)) 
     { 
      field = value; 
      OnPropertyChanged(name); 
      return true; 
     } 
     return false; 
    } 
} 

public class RelayCommand<T> : ICommand 
{ 
    readonly Action<T> _execute; 
    readonly Func<T, bool> _canExecute; 

    public event EventHandler CanExecuteChanged; 

    public RelayCommand(Action<T> execute, Func<T, bool> canExecute = null) 
    { 
     _execute = execute; 
     _canExecute = canExecute; 
    } 

    public void RefreshCommand() 
    { 
     var cec = CanExecuteChanged; 
     if (cec != null) 
      cec(this, EventArgs.Empty); 
    } 

    public bool CanExecute(object parameter) 
    { 
     if (_canExecute == null) return true; 
     return _canExecute((T)parameter); 
    } 

    public void Execute(object parameter) 
    { 
     _execute((T)parameter); 
    } 
} 

public class RelayCommand : RelayCommand<object> 
{ 
    public RelayCommand(Action execute, Func<bool> canExecute = null) 
     : base(_ => execute(), 
      _ => canExecute == null || canExecute()) 
    { 

    } 
} 
運行時
  • 檢視: on running

    問候,

  • 相關問題