TabItems在窗口关闭时会收到通知。
TabItems在窗口关闭时会收到通知。
假设我有一个带有多个选项卡项的TabControl,并且其实现基于这个,并且对于每个选项卡使用类似这个的用户控件。还使用了MVVM Light。如何以适当的方式(MVVM)通知选项卡项,当点击(x)关闭应用程序时,为每个选项卡保存数据?我知道如何在托管选项卡项的MainWindow中处理关闭事件,但我不知道如何通知每个选项卡项的UserControl(实际上是它的视图模型)。有任何想法吗?
此外,如果选项卡项未被选中并显示在屏幕上,是否会收到关闭通知?
已解决
我按照这个问题评论中的@3615的解决方案。使用基于中介者模式的Messenger。因此,我的MainViewModel侦听窗口关闭事件并将信息广播给选项卡项。
在MVVM模式下,选项卡(TabItems)在“Main”中有对应的“Document”视图模型。在退出时,检查视图模型是否需要保存。当通过选项卡关闭文档时,向负责管理和关闭文档的“Main”发送一条消息...
在窗口关闭事件处理程序中,将当前DataContext转换为MainViewModel,并检查是否可以关闭。如果不能关闭,则取消关闭操作;否则,执行其他操作。
对于MainViewModel,它接收一个参数,并通过Messenger.Default.Register方法注册了一个消息接收器。当接收到类型为DocumentViewModel的消息时,从Documents集合中移除该ViewModel,并调用Cleanup方法清理资源。如果Documents集合为空,则将ActiveDocument设置为null。
对于问题中提到的代码示例,具体如何通知选项卡的视图模型并不清楚。难道不应该在每个选项卡的视图模型中使用"Messenger.Default.Register..."来监听关闭消息吗?
实际上,这取决于软件的架构。在这个例子中,MainViewModel负责管理一个文档集合(this.Documents),并对其进行创建、保存、关闭等操作。这里提供了一个稍微复杂一些的示例:github.com/TheCamel/CBR
问题出现的原因是在关闭窗口时,TabItems无法收到通知。解决方法是使用事件。当创建一个Tab时,MainVM会订阅UserControl事件,该事件在Tab需要关闭时触发。然后,MainVM接收到事件并关闭Tab,因为它可以访问OpenedTabs集合。
代码示例(C#):
public class MainVM { public ObservableCollectionOpenedTabs { get; set; } public MainVM() { OpenedTabs = new ObservableCollection (); } public void AttachToTabClosingEvent(UserControl tab) { tab.Closing += Tab_Closing; } private void Tab_Closing(object sender, EventArgs e) { UserControl tab = (UserControl)sender; TabItem tabItem = FindTabItem(tab); if (tabItem != null) { OpenedTabs.Remove(tabItem); } } private TabItem FindTabItem(UserControl tab) { // Find the corresponding TabItem in the OpenedTabs collection based on the UserControl instance foreach (TabItem tabItem in OpenedTabs) { if (tabItem.Content == tab) { return tabItem; } } return null; } } // 在创建Tab时,将Tab对象传递给MainVM的AttachToTabClosingEvent方法 UserControl tab = new UserControl(); MainVM mainVM = new MainVM(); mainVM.AttachToTabClosingEvent(tab);
这样就可以确保当Tab需要关闭时,MainVM能够收到通知并关闭Tab。
解决方法:
1. 使用ObservableCollection<T>
的CollectionChanged
事件处理程序。
2. 在TabControl
的ItemsSource
属性上绑定这个ObservableCollection<T>
。
3. 当(x)按钮被点击时,从这个集合中移除被UserControl
所表示的数据对象。
原因:
在关闭窗口时,希望能够通知到TabControl
中的TabItems
。为了实现这个功能,可以使用ObservableCollection<T>
以及CollectionChanged
事件。当UserControl
中的(x)按钮被点击时,需要将其对应的数据对象从ObservableCollection<T>
中移除,以触发CollectionChanged
事件,从而通知TabControl
中的TabItems
。