3

WPF で異なる DataContext を制御する

さまざまなタブに複数の DataContext を展開し、現在の DataContext を制御できるため

ここに画像の説明を入力

私はMvvm Light WPF4を使用しています。さまざまな ViewModels、View がありますが、複数の DataContext を処理し、タブ スイッチで変更するために現在の DataContext を制御する方法がわかりません。

編集:

私は次のように解決策へのアプローチを持っています:

  1. MainView の ViewModel を作成する
  2. タブコントロールのソースは ObservableCollection です
  3. 各 TabItem には独自の DataContext があります
  4. メニューには、次のような DataContext がありますDataContext="{Binding Path=CurrentTab.DataContext}"。ViewModel に新しい TabItem を追加すると、CurrentTab が変更されます。

私は次の問題を抱えています:

  1. タブを変更するときに、TabControl から ViewModel を接続するにはどうすればよいですか?

解決策: 問題は、Mvvm Light が静的な方法で ViewModel をバインドするために ViewModelLocator を使用することです。これは、C# でタブを追加すると ViewModelLocator が機能しないという問題です。他の方法では、次のように各タブの ViewModel を手動でロードする必要があります。

// in MainModelView.cs

public RelayCommand MyCommand { get; set; }

private void RegisterCommand()
{
  MyCommand = new RelayCommand(() =>
  {
    AddTab("Tab Header", new TabViewModel(), new TabContentControl());
  });
}

private void AddTab(string header, object context, ContentControl content)
{
  TabItem = null;

  foreach(TabItem tab in TabItemList)
  {
    if(tab.Header.Equals(header);
    {
      tabItem = tab;
    }
  }

    if(null == tabItem)
    {
      tabItem = new TabItem();
      tabItem.Header = header;
      tabItem.Content = content;
      tabItem.DataContext = context;
      TabItemList.Add(tabItem);
    }

    CurrentTabIndex = TabItemList.IndexOf(tabItem);    
}

2. メニューで DataContext が更新されません。コードが間違っていますか?

解決策:前のポイントもこれを解決し、次のコードを解決するだけです:

// in RegisterCommands()
ChangeTabCommand = new RelayCommand<TabItem>(tab =>
{
  if (null == tab) return;
  CurrentTabContext = tab.DataContext;
}

MainWindow.xml で:

  <!-- MainWindow.xaml -->

  <Button Content="NewTab" Command="{Binding Path=MyCommand }" />

  <TabControl
      Margin="5 5 5 0"
      Grid.Row="1"
      ItemsSource="{Binding Path=TabItemList}"
      SelectedIndex="{Binding Path=CurrentTabItemIndex}"
      x:Name="Workspace">
      <i:Interaction.Triggers>
          <i:EventTrigger EventName="SelectionChanged">
              <cmd:EventToCommand
              Command="{Binding ChangeTabCommand }"
              CommandParameter="{Binding SelectedItem, ElementName=Workspace}"/>
          </i:EventTrigger>
      </i:Interaction.Triggers>
  </TabControl>    

編集2:

  1. ViewModel でのビューの変更を回避し、同じビュー (ContenControl、Header、Context) から必要なパラメーターを送信する方法
4

1 に答える 1

0

各ビュー モデル (MainViewModel、Tab1ViewModel、Tab2ViewModel など) のプロパティを持つ ViewModelContainer を作成します。ViewModelContainer を Window の DataContext としてバインドし、この方法で各 TabItem DataContext を適切な VM オブジェクトにバインドできます DataContext="{Binding Tab1ViewModel}"

問題 2 の提案はありません。

アップデート

コードは MVVM に 100% 準拠していません。あなたのコマンドは、ビューとビューモデルを編集します。骨の折れる作業が必要な場合は、コマンドはビューモデルとのみ対話する必要があります。その後、viewmodel は、(ObservableCollection または INotifyPropertyChanged インターフェイスを介して) 新しい tabItem を追加することによって応答するビューに通知します。View パーツは、パネルの表示方法を定義するために ItemTemplate を使用して XAML で 100% 管理できると思います。

于 2012-05-02T08:10:38.067 に答える