WPF 从多个视图模型向选项卡控件添加选项卡项

WPF Adding tab items to tab control from multiple view models

在我的 MainWindow 上,我有一个 TabControl,其 ItemSource 绑定到一个 ObservableCollection<TabItem> 在它的视图模型 (vmMainWindow) 中。

在主要 Window 我也有一个 Menu 和 2 MenuItems,(专辑,艺术家)

我已经为专辑和艺术家创建了 PageViewModel

单击 MenuItem 时,使用 RelayCommand 我正在创建一个 Frame 来保存绑定到其各自视图模型的相关事件 Page。然后我创建一个新的 TabItem 将它的 Content 设置为新的 Frame 然后将新的 TabItem 添加到 ObservableCollection<TabItem>.

    void MenuItemClick(object parameter)
    {
        switch (parameter)
        {
            case "Albums":
                Frame albumsFrame = new Frame { Content = new pgAlbums { DataContext = new vmAlbums() } };
                TabCollection.Add(new TabItem { Header = "Albums", Content = albumsFrame , IsSelected = true });
                break;
            case "Artists":
                Frame artistsFrame = new Frame { Content = new pgArtists { DataContext = new vmArtists() } };
                TabCollection.Add(new TabItem { Header = "Artists", Content = artistsFrame , IsSelected = true });
                break;
        }
    }

我想做的是能够以与其他 Page 的视图模型相同的方式向 ObservableCollection<TabItem> 添加选项卡,但我无权访问 TabCollection从他们。我要么需要全局放置它,要么以某种方式在视图模型之间共享它。

我知道我正在以错误的方式处理这件事,所以我把它放在这里,以便有人可以指导我朝着正确的方向前进。我是 MVVM 的新手,我只有 Winforms 方面的经验,但想继续前进。

您可以使用 EventAggregatorMessenger class 发送其他视图模型订阅的消息。有关此概念的更多信息,请参阅以下链接。

https://msdn.microsoft.com/en-us/magazine/jj694937.aspx

http://dotnetpattern.com/mvvm-light-messenger

https://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/

其他选项是将两个视图模型注入共享服务,或者从第二个视图模型中保留对第一个视图模型的强引用并引发事件。

使用事件聚合器或信使的好处是您可以避免在事件发布者和订阅者之间引入紧密耦合,这应该会使应用程序更易于维护。事件或消息的发布者和订阅者都只知道事件聚合器或信使,但他们对彼此一无所知。

顺便说一下,您不应该在视图模型中创建 TabItems 或任何其他视觉元素。您应该创建数据对象的实例,这些实例可能由视图中的 TabItems 等视觉元素表示。