控制不同的DataContext

3

控制WPF中不同的DataContext

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

enter image description here

我正在使用Mvvm Light WPF4,我有不同的ViewModels和View,但我不知道如何处理多个DataContext并控制当前的DataContext以便在切换选项卡时进行更改。

编辑:

我已经有了解决方案的方法,具体如下:

  1. 为MainView创建一个ViewModel
  2. TabControl源是ObservableCollection
  3. 每个TabItem都有自己的DataContext
  4. 菜单的DataContext如下:DataContext="{Binding Path=CurrentTab.DataContext}",其中CurrentTab在ViewModel中添加新的TabItem时会更改

我遇到了以下问题:

  1. 当您更改选项卡时,如何连接TabControl的ViewModel?

解决方案:问题在于Mvvm Light使用ViewModelLocator以静态方式绑定ViewModel,在C#中添加选项卡时这就是问题所在,另外我需要手动加载每个选项卡的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)发送必要的参数。
1个回答

0
我会创建一个ViewModelContainer,其中包含每个视图模型的属性(例如MainViewModel、Tab1ViewModel、Tab2ViewModel)。 然后,您可以将ViewModelContainer绑定为窗口的DataContext,并以此方式将每个TabItem的DataContext绑定到正确的VM对象DataContext="{Binding Tab1ViewModel}"。
对于问题2没有建议。
更新
您的代码并不完全遵循MVVM。您的命令编辑了视图和视图模型。如果您想要严谨,命令必须仅与视图模型交互。然后,视图模型将通过ObservableCollection或INotifyPropertyChanged接口发出信号,通知视图添加新的tabItem。 我认为,使用ItemTemplate在XAML中定义面板应如何显示,可以完全管理视图部分。

TabControl 的 ItemSource 属性是 { Binding Path=TabItemList }。 - rkmax
使用ItemSource,就像rkmax所说的那样。视图应该对ViewModel的更改做出反应,而不应该由ViewModel控制。 - Roberto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接