控制不同的DataContext

时间:2012-05-01 21:02:38

标签: c# xaml mvvm mvvm-light

在WPF中控制不同的DataContext

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

enter image description here

我正在使用 Mvvm Light WPF4 我有不同的ViewModel,View但我不知道如何处理多个DataContext并控制当前DataContext以便在Tab键切换上进行更改

编辑:

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

  1. 为MainView创建ViewModel
  2. tabcontrol源是一个ObservableCollection
  3. 每个TabItem都有自己的DataContext
  4. 菜单包含DataContext,如下所示:DataContext="{Binding Path=CurrentTab.DataContext}"当ViewModel中添加新的TabItem时,CurrentTab会发生变化
  5. 我有以下问题:

    1. 如何在更改选项卡时从TabControl连接ViewModel?
    2. 解决方案:问题是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)

1 个答案:

答案 0 :(得分:0)

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

没有问题2的建议。

<强>更新

您的代码不遵循MVVM 100%。您的命令编辑视图和视图模型。如果您想要苦心经营,那么命令必须只与viewmodel进行交互。然后,viewmodel将通过添加新的tabItem(通过ObservableCollection或INotifyPropertyChanged接口)发出将回复的视图。 我想可以使用ItemTemplate使用XAML 100%管理View部分,以定义面板的显示方式。