2016-12-19 19 views
0

私は、MainWindowViewModelとMainViewModelで構成され、ViewModelsの3つのタブを持つUIの構造を持っています。私はそれらのタブをインスタンス化するためにMVVMLightを使用しています。私はメインビュー上に表示するために、firstviewmodelからxamlに文字列を渡す必要があります。 MainWindowViewModelを使用しても機能しませんが、MainViewModelはMainWindowViewModelの一部です。だから、私の質問 - MainWindowViewModel内でMainViewModelを初期化して、自分のタブからTextプロパティを取得してそれを私のウィンドウに表示できるようにする正しい方法は何ですか?wpfでのViewModel階層

マイMainWindow.xaml

<Window 
x:Class="Tabs.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:local="clr-namespace:Tabs" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
Title="MainWindow" 
Width="525" 
Height="350" 
mc:Ignorable="d"> 
<Grid> 
    <TabControl 
     Width="340" 
     Height="202" 
     Margin="21,41,0,0" 
     HorizontalAlignment="Left" 
     VerticalAlignment="Top" 

     > 
     <TabItem Header="Page 1"> 
      <Grid Background="#FFE5E5E5" DataContext="{Binding MainViewModel.FirstViewModel}"> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="11*"/> 
        <ColumnDefinition Width="24*"/> 
        <ColumnDefinition Width="34*"/> 
        <ColumnDefinition Width="265*"/> 
       </Grid.ColumnDefinitions> 
       <TextBlock Height="100" Text="{Binding MainViewModel.FirstViewModel.Text}" Grid.ColumnSpan="4" Margin="0,37" /> 
      </Grid> 
     </TabItem> 
     <TabItem Header="Page 2"> 
      <Grid Background="#FFE5E5E5" DataContext="{Binding MainViewModel.SecondViewModel}"> 
       <TextBlock Height="100" Text="{Binding Text}" /> 
      </Grid> 
     </TabItem> 
     <TabItem Header="Page 3"> 
      <Grid Background="#FFE5E5E5" DataContext="{Binding MainViewModel.ThirdViewModel}"> 
       <TextBox Height="100" Text="{Binding Input}" /> 
      </Grid> 
     </TabItem> 
    </TabControl> 

</Grid> 

public partial class MainWindow : Window 
     { 
      public MainWindow() 
      { 
       InitializeComponent(); 
       DataContext = new MainWindowViewModel(); 
      } 
     } 

マイMainWindowViewModel

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace Tabs.ViewModel 
{ 
    class MainWindowViewModel : INotifyPropertyChanged 
    { 
     private MainViewModel mainViewModel; 

     public MainWindowViewModel() 
     { 
      mainViewModel = new MainViewModel(); 

     } 

     public MainViewModel MainViewModel 
     { 
      get 
      { 
       return mainViewModel; 
      } 

      set 
      { 
       mainViewModel = value; 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
    } 
} 

マイMainViewModel

背後にあるコード

Text="{Binding MainViewModel.FirstViewModel.Text}" 

をするだけでなく:

using GalaSoft.MvvmLight; 
using Tabs.ViewModel.Base; 

namespace Tabs.ViewModel 
{ 

    public class MainViewModel : ViewModelBase 
    { 

     public FirstViewModel FirstViewModel { get; set; } 
     public SecondViewModel SecondViewModel { get; set; } 
     public ThirdViewModel ThirdViewModel { get; set; } 
     public MainViewModel() 
     { 
      FirstViewModel = new FirstViewModel(); 
      FirstViewModel.Text = "ehe"; //all i need is to show 
      SecondViewModel = new SecondViewModel(); 
      ThirdViewModel = new ThirdViewModel(); 
     } 
    } 
} 

マイFirstViewModelとテキストフィールドが、私は実際に

public class FirstViewModel:BaseViewModel 
{ 
    private string _text; 

    public string Text 
    { 
     get { return _text; } 
     set { Set(() => Text, ref _text, value); } 
    } 

    public FirstViewModel() 
    { 

    } 
} 
+0

1. **すべての**ビューモデルのプロパティは変更時に通知する必要があります。 2. TextBlockをテキストに変換する(グリッドレベルのDataContextをFirstViewModelに設定するため) –

+0

BTW「{Binding Path = ...」と入力すると、IntelliSenseの機能を使用することができます。これは非常に便利です(コンパイルするのを忘れないでくださいXAMLファイルを編集する前の解決策) –

+0

実行時にバインドを検査するためにスヌープを取得すると、バインディングエラーやDataContextのフローが簡単にわかるようになります。 – Will

答えて

4

あなたの持つあなたのTextBlockテキスト結合であることに、次のようにということである問題を取得したいですあなたのTextBlockは、それがdatacontextとして設定されているグリッドにあるという事実:

DataContext="{Binding MainViewModel.FirstViewModel}" 

だから、効果的に何が起こっているのか、それはこの場所であなたのテキストを探しているということです。

MainViewModel.FirstViewModel.MainViewModel.FirstViewModel.Text 

あなたのTextBlockのDataContextのは、あなたのFirstViewModelですので、あなたが Text="{Binding DataContext}"を行けば、あなたはこのようなケースであることが表示されます。

Text="{Binding Text}" 

追加メモ:
何がやりたいことは行く単にある

あなたがText="{Binding Text}"を行くとき、WPFは、要素の現在のDataContext、常に同じになりますチェックするためであります明示的に設定されていない限り、その親のDataContextとして返されます。

+0

ありがとうございました!私はまた、プロパティとしてTabItemsを含めるためにTabControlのBaseViewmodelを使用する必要があるかどうかを知りたいと思っていますか? –

+0

あなたのビューのほとんどではないにしても、モデルはBaseViewModelから派生します。一般に、MVVMアプローチを使用している場合、ViewModelはビューが使用する/表示されるプロパティを公開します。ビューモデルはBaseViewModelmから導かれる必要があります。これは、ビューがプロパティ、つまりINotifyPropertyChangedインタフェース。 – Heinrich