【问题标题】:WPF MVVM: Binding a different ViewModel to each TabItem?WPF MVVM:将不同的 ViewModel 绑定到每个 TabItem?
【发布时间】:2014-10-06 14:45:40
【问题描述】:

我有一个带有选项卡控件的主窗口,其中包含 2 个tabItems:

我目前有 1 个ViewModel 为 Tab1 和 Tab2 提供服务。这个ViewModel 因 SOC 模糊而变得有点臃肿。我想将逻辑拆分为 2 个视图模型:ViewModel 1 和 ViewModel2。我的理解是,您可以将主窗口DataContext 设置为包含 ViewModel 集合的基本 ViewModel,然后您可以将每个 TabItem 断言为不同的 ViewModel。

我看到的这些基本 ViewModel 的示例公开了一个 ObservableCOllection,如下所示:

private ObservableCollection<ViewModel1> _viewModelCollection
Public Observable Collection<ViewModel1> ViewModelCollection
{
   get { return _viewModelCollection; }
   set
     {
        _viewModelCollection = value;
        OnPropertyChanged("ViewModelCollection");
     }
}

public BaseViewModel()
{
  ViewModelCollection = new ObservableCollection<ViewModel1>();
  ViewModelCollection.Add(new ViewModel1(Tab1);
  ViewModelCollection.Add(new ViewModel1(Tab2);
}

但是如何为每个 TabItem 分配不同的 ViewModel?我想要 Tab1= ViewModel1 & Tab2=ViewModel2?

【问题讨论】:

  • 我不确定是否有明确的最佳实践。将TabControl 的ItemsSource 绑定到您的ViewModelCollection 对您没有多大好处,因为没有通用的“模板”(每个选项卡可能都有自己的视图)。如果您有固定数量的选项卡,我只需将每个选项卡的DataContext 绑定到相应的视图模型,并将每个选项卡的内容设置为适当的视图。如果标签是动态的,事情就会变得棘手。
  • 您尝试过搜索吗? 1, 2, 3 ...
  • @Sinatr 是的,我已经阅读了这些问题。我想绑定到不同的 ViewModel,而不是同一 ViewModel 的不同实例的集合...

标签: c# wpf mvvm


【解决方案1】:

您确实可以将选项卡的视图模型添加到主视图模型。然后,您可以为您的选项卡绑定到 XAML 中的子视图模型。

假设您有三个视图模型:MainViewModel、Tab1ViewModel 和 Tab2ViewModel。在您的 MainViewModel 上,您保留了选项卡视图模型的集合:

class MainViewModel
{
    ObservableCollection<object> _children;

    public MainViewModel()
    {
        _children = new ObservableCollection<object>();
        _children.Add(new Tab1ViewModel());
        _children.Add(new Tab2ViewModel());
    }

    public ObservableCollection<object> Children { get { return _children; } }
}

将主窗口的DataContext 设置为MainViewModel 后,您可以通过引用Children 属性来绑定标签的DataContext:

<TabControl>
    <TabItem DataContext="{Binding Children[0]}" x:Name="Tab1" Header="Tab1" >
      <!-- Tab content -->
    </TabItem>
    <TabItem DataContext="{Binding Children[1]}" x:Name="Tab2" Header="Tab2" >
      <!-- Tab content -->
    </TabItem>
</TabControl>

【讨论】:

  • 太棒了!正是我需要的,我也喜欢绑定到 OC 中的索引 :)
【解决方案2】:
class MainViewModel
{
    ObservableCollection<object> _children;

    public MainViewModel()
    {
        _children = new ObservableCollection<object>();
        _children.Add(new Tab1ViewModel());
        _children.Add(new Tab2ViewModel());
    }

    public ObservableCollection<object> Children { get { return _children; } }
}

现在在 XAML 中将子项绑定到 ItemsSource。它将为我们添加到可观察集合中的每个视图模型生成每个选项卡

    <TabControl ItemsSource="{Binding Children}"/>

【讨论】:

  • 这段代码 sn-p 是 Jakob 上述代码的精确副本。
  • 这可能是 Jakob 的代码的副本,但这个答案更完整。它是强类型的(不使用object 或Children[x]),实际上向OP 展示了如何做他想做的事情。这应该是 IMO 接受的答案。
【解决方案3】:

我使用 Prism 等框架,它允许您定义区域并使用 RegionManager。然后,您可以将ContentControl 定义为TabItem 的“ui”

然后您可以使用RegionManager.RequestNavigate 来填充具有特定视图的命名区域(并且我们的视图导入视图模型并设置它们的数据上下文)。

【讨论】:

  • 是的,我对 Prism 进行了修补。虽然这个应用程序相当简单,但不值得为此设置引导程序等。
  • 我想我可以尝试一个带有 ObservableCollection 的基本模型。向其中添加我的不同 ViewModel 的实例,然后将选项卡项绑定到集合中的相应 ViewModel 实例?
  • 您可以将选项卡控件中的项目源绑定到将在 UI 中显示的 tabViewModel 列表。 TabVMs 可以从所有常见事物所在的 BaseTabVM 继承,并最终为项目资源中的每个选项卡视图模型创建一个数据模板,以便可以单独自定义它们。绑定将在每个单独的 tabVM 中进行,您在主窗口视图模型中有一个 BaseTabVM 列表要绑定到,并且所有项目都可以独立使用。
【解决方案4】:

对于找到此页面并提出相同问题的人,我在 YouTube 上找到了一个视频:WPF MVVM - Working with tab controls and tab content,由 DCOM Engineering, LLC 的一个人制作。

它很好地解释了“如何将不同的ViewModel 绑定到每个TabItem”,一步一步的,带有可下载的代码。

“了解如何使用带有 WPF 的 MVVM 模式有效地创建、打开和关闭选项卡。促进单元测试。”

【讨论】:

    【解决方案5】:

    不确定为什么所选答案建议使用 ObservableCollection 并创建选项卡集合,然后按索引引用它们。

    我觉得这样做更干净:

    主视图模型 tab1= 配置视图模型 Tab2 = UserProfileViewModel

    在 MainViewModel 中:

    private ConfigViewModels _configVM;
    public ConfigViewModels ConfigVM { get { return _configVM; } }
    
    private UserProfileViewModel _userProfileVM;
    public UserProfileViewModel UserProfileVM { get { return _userProfileVM; } }
    
    public MainViewModel(){
    
    _configVM = new ConfigViewModels();
    _userProfileVM = new UserProfileViewModel ();
    }
    

    在 XAML 文件中:

    <TabControl>
    <TabItem DataContext="{Binding ConfigVM }" >
    <TabItem DataContext="{Binding UserProfileVM }" >
    

    我不确定我是否理解通过可观察集合来执行此操作的好处。

    【讨论】:

      猜你喜欢
      • 2013-08-05
      • 1970-01-01
      • 2010-12-31
      • 1970-01-01
      • 2011-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多