2017-07-22 14 views
0

お願い - 現時点でMVVMlite(など)のような外部のフレームワークを採用/使用したくないです。これを手動で行う必要がありますので、完全なプロセスを見ることができます。ICommandのMvvmパターンを使用してMainWindow.xamlでUsercontrolを切り替える方法は?

私は質問している質問のさまざまな洞察を見ましたが、MainControllerをMainControllerに変更するためにユーザーコントロールにコマンドをバインドする質問はありませんでした。次のコードでは、MainWindow.xamlのusercontrolを切り替えるためのWpf/Mvvmアプリケーションを作成しようとした試行/試行を示します。質問/要求は、私がこのプロジェクトをフォローするために必要なステップです。

私のプロジェクトでは、標準のモデル/ ViewModels/Viewsフォルダ、MainWindow.xaml(MainWindow.xamlはプロジェクトのルートフォルダにあります)で切り替える3つのusercontrolビューを持っています - BlueView、OrangeView、 RedView。これらのビュー/ユーザーコントロールが持つ唯一のコンテンツは、Blueviewに青の背景グリッドがあり、OrangeViewにオレンジの背景グリッドがあり、RedViewに赤の背景グリッドがあることです。 MainWindow.xamlの左側のスタックパネルには3つのボタンがあり、MainWindow.xamlの右側にあるusercontrolsをロード/切り替えたいコンテンツコントロールがあります。私は3つの対応ViewModels、BlueViewModel、OrangeViewModel、RedViewModelを持っています。また、これらの3つのviewModelとRelayCommand.csをモデルフォルダに結びつけるためのMainViewModelもあります。しかし、私はそこからどこへ行くべきか分かりません。

ここで私のコードです - 注:私はMainWindow.xaml、RelayCommand.cs、MainViewModel、BlueViewModle/BlueViewを追加します。他のビュー/ ViewModelsは背景グリッドの色を除いて同じなので、追加します。 MainWindow.xamlのコンテンツコントロールにusercontrolsをロード/切り替えできるようにするには、何を行う/追加する必要がありますか?私はusercontrolを表示することはできません - 私はどのようにMainViewModel.csで表示/表示メソッドを持っていませんusercontrolsをロードするには? ViewModelにメソッドが必要ですか?

は--MainWindow.xaml - --RelayCommand.cs

<Window x:Class="ViewChangerFromICommand.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:local="clr-namespace:ViewChangerFromICommand" 
     xmlns:viewmodels="clr-namespace:ViewChangerFromICommand.ViewModels" 
     xmlns:views="clr-namespace:ViewChangerFromICommand.Views" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 

    <Window.Resources> 
     <DataTemplate x:Name="redViewTemplate" DataType="{x:Type viewmodels:RedViewModel}"> 
      <views:RedView DataContext="{Binding}"/> 
     </DataTemplate> 
     <DataTemplate x:Name="BlueViewTemplate" DataType="{x:Type viewmodels:BlueViewModel}"> 
      <views:BlueView DataContext="{Binding}"/> 
     </DataTemplate> 
     <DataTemplate x:Name="OrangeViewTemplate" DataType="{x:Type viewmodels:OrangeViewModel}"> 
      <views:OrangeView DataContext="{Binding}"/> 
     </DataTemplate> 
    </Window.Resources> 

     <Window.DataContext> 
      <viewmodels:MainViewModel /> 
     </Window.DataContext> 

    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition/> 
      <ColumnDefinition/> 
      <ColumnDefinition/> 
      <ColumnDefinition/> 
      <ColumnDefinition/> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition/> 
      <RowDefinition/> 
      <RowDefinition/> 
      <RowDefinition/> 
      <RowDefinition/> 
     </Grid.RowDefinitions> 

     <DockPanel Background="Gray" Grid.Row="0" Grid.Column="0" Grid.RowSpan="5"> 
      <StackPanel> 
       <Button Content="Red View"/> 
       <Button Content="Blue View"/> 
       <Button Content="Orange View"/> 
      </StackPanel> 
     </DockPanel> 
     <ContentControl Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="4" Grid.RowSpan="5" Content="{Binding}"/> 
    </Grid> 
</Window> 

は、プロジェクトのルートフォルダに存在する - モデルのフォルダに存在

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Input; 

namespace ViewChangerFromICommand.Models 
{ 
    public class RelayCommand : ICommand 
    { 
     readonly Action _execute; 
     readonly Func<bool> _canExecute; 

     public RelayCommand(Action execute, Func<bool> canExecute) 
     { 
      if (execute == null) 
       throw new NullReferenceException("execute"); 

      _execute = execute; 
      _canExecute = canExecute; 
     } 

     public RelayCommand(Action execute) : this(execute, null) 
     { 

     } 

     public event EventHandler CanExecuteChanged 
     { 
      add { CommandManager.RequerySuggested += value; } 
      remove { CommandManager.RequerySuggested -= value; } 
     } 

     public bool CanExecute(object parameter) 
     { 
      return _canExecute == null ? true : _canExecute(); 
     } 

     public void Execute(object parameter) 
     { 
      _execute.Invoke(); 
     } 
    } 
} 

--MainViewModel.cs - 常駐viewmodelsフォルダに

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using ViewChangerFromICommand.Models; 
using ViewChangerFromICommand.Views; 

namespace ViewChangerFromICommand.ViewModels 
{ 
    public class MainViewModel 
    { 
     public BlueViewModel blueVM { get; set; } 

     public OrangeViewModel orangeVM { get; set; } 

     public RedViewModel redVM { get; set; } 

     public MainViewModel() 
     { 
      blueVM = new BlueViewModel(); 
      orangeVM = new OrangeViewModel(); 
      redVM = new RedViewModel(); 

     }   
    } 
} 

--BlueViewModel.cs - のviewmodelsフォルダ

に常駐
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Input; 
using ViewChangerFromICommand.Models; 
using ViewChangerFromICommand.Views; 

namespace ViewChangerFromICommand.ViewModels 
{ 
    public class BlueViewModel 
    { 
     public BlueViewModel() 
     { 
     }   
    } 
} 

--BlueView.xaml - [ビュー]フォルダに

<UserControlx:Class="ViewChangerFromICommand.Views.BlueView" 
    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:ViewChangerFromICommand.Views" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="300"> 

    <Grid Background="Blue"> 

    </Grid> 
</UserControl> 
+0

私はちょうど私が答える前に明確にしたい - あなたの最終的なデザインに(これは単純化していると仮定)は、いずれかが存在することになりますRedViewModelクラス、BlueViewModelクラス、およびOrangeViewModelクラスの違いは?あるいは、彼らはすべて同じ性質、コマンドなどを持っていますか? –

+0

すべてのviewmodesl(MainViewModelを除く)は同じです(1つを除くすべての機能は青色の背景、1つは赤色の背景色はオレンジ色の背景色です)。この演習では、MainWindow.xamlでこれらのユーザコントロールをロード/スイッチングするためのMvvmパターン(Icommandを使用する場合はこれを使用する方法)を使用しています。 –

答えて

0

を常駐には、以下のアプローチを考えてみましょう。

MainViewModelでは、表示するViewModel/Viewを反映する 'Selected'プロパティを作成します。 RelayCommandsをセットアップして、[Selected]プロパティに目的のビューモデルを割り当てます。

ビュー(ウィンドウ)で、ContentControlのコンテンツを「選択済み」にバインドし、コマンドバインディングを設定します。

MainViewModelでは、ビューで認識される 'Selected'プロパティを変更するためにINotifyPropertyChangedも実装する必要があります。

ビューモデル:

public class MainViewModel:INotifyPropertyChanged //Look into using Prism and BindableBase instead of INotifyPropertyChanged 
{ 
    private BlueViewModel blueVM; 

    private OrangeViewModel orangeVM; 

    private RedViewModel redVM; 

    public event PropertyChangedEventHandler PropertyChanged=delegate { }; 

    object selectedView; 
    public object SelectedView 
    { 
     get { return selectedView; } 
     private set 
     { 
      selectedView = value; 
      RaisePropertyChanged("SelectedView"); 
     } 
    } 

    public ICommand SelectBlueViewCommand { get; private set; } 
    public ICommand SelectOrangeViewCommand { get; private set; } 
    public ICommand SelectRedViewCommand { get; private set; } 

    public MainViewModel() 
    { 
     blueVM = new BlueViewModel(); 
     orangeVM = new OrangeViewModel(); 
     redVM = new RedViewModel(); 
     SelectBlueViewCommand = new RelayCommand(() => SelectedView = blueVM); 
     SelectOrangeViewCommand = new RelayCommand(() => SelectedView = orangeVM); 
     SelectRedViewCommand = new RelayCommand(() => SelectedView = redVM); 
    } 

    void RaisePropertyChanged(string property) 
    { 
     PropertyChanged(this, new PropertyChangedEventArgs(property)); 
    } 
} 

ビュー/ウィンドウ

<Window x:Class="WpfApp1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:system="clr-namespace:System;assembly=mscorlib" 
    xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:local="clr-namespace:ViewChangerFromICommand" 
    xmlns:viewmodels="clr-namespace:ViewChangerFromICommand.ViewModels" 
    xmlns:views="clr-namespace:ViewChangerFromICommand.Views" 

      Title="Window1" Height="650" Width="750"> 
<Window.Resources> 
    <DataTemplate x:Name="redViewTemplate" DataType="{x:Type viewmodels:RedViewModel}"> 
     <views:RedView DataContext="{Binding}"/> 
    </DataTemplate> 
    <DataTemplate x:Name="BlueViewTemplate" DataType="{x:Type viewmodels:BlueViewModel}"> 
     <views:BlueView DataContext="{Binding}"/> 
    </DataTemplate> 
    <DataTemplate x:Name="OrangeViewTemplate" DataType="{x:Type viewmodels:OrangeViewModel}"> 
     <views:OrangeView DataContext="{Binding}"/> 
    </DataTemplate> 
</Window.Resources> 

<Window.DataContext> 
    <viewmodels:MainViewModel /> 
</Window.DataContext> 

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition/> 
     <ColumnDefinition/> 
     <ColumnDefinition/> 
     <ColumnDefinition/> 
     <ColumnDefinition/> 
    </Grid.ColumnDefinitions> 
    <Grid.RowDefinitions> 
     <RowDefinition/> 
     <RowDefinition/> 
     <RowDefinition/> 
     <RowDefinition/> 
     <RowDefinition/> 
    </Grid.RowDefinitions> 

    <DockPanel Background="Gray" Grid.Row="0" Grid.Column="0" Grid.RowSpan="5"> 
     <StackPanel> 
      <Button Content="Red View" Command="{Binding SelectBlueViewCommand}"/> 
      <Button Content="Blue View" Command="{Binding SelectOrangeViewCommand}"/> 
      <Button Content="Orange View" Command="{Binding SelectRedViewCommand}"/> 
     </StackPanel> 
    </DockPanel> 
    <ContentControl Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="4" Grid.RowSpan="5" 
        Content="{Binding SelectedView}"/> 
</Grid> 

+0

お返事ありがとうございました。私はそれを試して、それは素晴らしい働いた!注:xamlの 'Selected'プロパティを 'SelectedView'に変更する必要がありました。ご協力いただき誠にありがとうございます! –

+0

歓迎します、私はxamlを編集して 'SelectedView'を述べました。あなたは答えを「受け入れられた」とマークできますか? –

+0

質問:プリズムを実装した場合、これはどのように変化しますか? –

関連する問題