3

在 WPF 中控制不同的 DataContext

因为我可以在不同的选项卡中部署多个 DataContext 并控制哪个是当前 DataContext

在此处输入图像描述

我正在使用Mvvm Light WPF4我有不同的 ViewModel,View 但我不知道如何处理多个 DataContext 并控制当前 DataContext 以在选项卡开关上进行更改

编辑:

我有一个解决方案的方法如下:

  1. 为 MainView 创建一个 ViewModel
  2. tabcontrol 源是 ObservableCollection
  3. 每个 TabItem 都有自己的 DataContext
  4. 菜单的 DataContext 如下所示:DataContext="{Binding Path=CurrentTab.DataContext}"where CurrentTab change when add new TabItem in ViewModel

我有以下问题:

  1. 更改选项卡时如何从 TabControl 连接 ViewModel?

解决方案:问题是 Mvvm Light 使用 ViewModelLocator 以静态方式绑定 ViewModel,这是当我在 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

我会创建一个 ViewModelContainer,它对您的每个视图模型(例如 MainViewModel、Tab1ViewModel、Tab2ViewModel)都有一个属性。您可以将 ViewModelContainer 绑定为 Window 的 DataContext,并以这种方式将每个 TabItem DataContext 绑定到正确的 VM 对象 DataContext="{Binding Tab1ViewModel}"

没有对问题 2 的建议。

更新

您的代码没有 100% 遵循 MVVM。您的命令编辑视图和视图模型。如果您想费力,该命令必须仅与 viewmodel 交互。然后,视图模型将发出信号(通过 ObservableCollection 或 INotifyPropertyChanged 接口)将通过添加新 tabItem 来回复的视图。我想 View 部分可以使用 XAML 100% 管理,使用 ItemTemplate 来定义面板的显示方式。

于 2012-05-02T08:10:38.067 回答