Caliburn Micro如何在没有孩子的情况下自动关闭导体

本文关键字:情况下 孩子 Micro Caliburn | 更新日期: 2023-09-27 18:25:26

我有一个MainComm VM,它创建了一个窗口MainChatWindow VM,MainChatWindowVM是一个导体。OneActive并包含一个选项卡控件,其中每个选项卡都是动态添加的ChatTabVM。一旦最后一次聊天会话关闭,MainChatWindow VM导体就不包含更多的项目,并且我需要以某种方式触发MainChatWindow窗口关闭,因为没有更多的选项卡以下是我的程序的结构(顺便说一句,我觉得这不是很正确):

public class MainCommViewModel : Conductor<IScreen>.Collection.OneActive, IHandle<RosterEvent>, IHandle<PrivateMessageEvent> //changed from Screen
{
    public MainCommViewModel(IEventAggregator events, IWindowManager windowManager, MainChatWindowViewModel mainChatWindowViewModel)
    {
        WindowManager = windowManager;
        MainChatWindowViewModel = mainChatWindowViewModel;
        conversationList = new Dictionary<string, ChatTabViewModel>();
        //...
    }
    public void Handle(PrivateMessageEvent message)
    {
        if (!MainChatWindowViewModel.IsActive)
        {
            dynamic settings = new ExpandoObject();
            settings.Title = "test title";
            WindowManager.ShowWindow(MainChatWindowViewModel, null, settings);
        }
        else
        {
            if(MainChatWindowViewModel.Items.Count == 0) //if there are no tabs, and the screen is active
            {
                MainChatWindowViewModel.Focus(); //then focus the window so they can see the newly added msg from below
            }
        }
        //Does tab already exist for this user/conversation?
        if (conversationList.ContainsKey(message.Pm.userId.User))
        {
            //Tab for user/conversation already exists
            ChatTabViewModel chatTabViewModel = conversationList[message.Pm.userId.User];
            chatTabViewModel.DisplayName = message.Pm.userId.User;
            chatTabViewModel.Conversation.chatMessages.Add(message.Pm);
        }
        else
        {
            ChatTabViewModel ctvm = new ChatTabViewModel(message.Pm.userId);
            ctvm.DisplayName = message.Pm.userId.User;
            ctvm.Conversation.chatMessages.Add(message.Pm);
            conversationList.Add(message.Pm.userId.User, ctvm);
            ctvm.Deactivated += new EventHandler<DeactivationEventArgs>(ChildTab_Deactivated);
            MainChatWindowViewModel.ActivateItem(ctvm);
        }
    }
    void ChildTab_Deactivated(object sender, DeactivationEventArgs e)
    {
        var ctvm = sender as ChatTabViewModel;
        if(ctvm != null)
        {
            if (e.WasClosed)
            {
                conversationList.Remove(ctvm.Conversation.User.User); //this users chat tab was closed, remove it from list
                //cant TryClose() here to close window if tab count = 0
            }
        }

和MainChatWindowViewModel:

public class MainChatWindowViewModel : Conductor<IScreen>.Collection.OneActive
{
    [ImportingConstructor]
    public MainChatWindowViewModel(IEventAggregator events, IWindowManager WindowManager)
    {
        events.Subscribe(this);
        //...
    }
    //...
}

MainChatWindowView.xaml:

<TabControl x:Name="Items" HorizontalAlignment="Left" Height="417" VerticalAlignment="Top" Width="654">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding DisplayName}" />
                <Button Content="X"
                        cal:Message.Attach="DeactivateItem($dataContext, 'true')" />
            </StackPanel>
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>

ChatTabViewModel:

public class ChatTabViewModel : Screen
{
    private Conversation conversation;
    public ChatTabViewModel(JID user)
    {
        conversation = new Conversation();
        conversation.User = user;
        //...
    }
    //...
}

如您所见,MainChatWindowView.xaml为每个选项卡定义了一个X按钮,单击该按钮时会调用该选项卡ViewModel的MainChatWindowView Model导体DeactivateItem,并关闭该选项卡。我的问题是:一旦所有选项卡都消失了,我不知道如何向窗口发出关闭信号希望我没有遗漏一些明显的东西,但我已经研究了一大堆函数、事件和覆盖,试图让它在我的情况下发挥作用。。我应该重组吗?

Caliburn Micro如何在没有孩子的情况下自动关闭导体

我用尽了Caliburn Micro的所有功能来自动完成这项工作,我认为不存在这样的事情。话虽如此,有一种明显而简单的方法可以通过替换选项卡关闭时的停用调用来处理这个问题,如下所示:

将此功能添加到MainChatWindowViewModel.cs

    public void DeactivateItemAndTryClose(IScreen item, bool close)
    {
        DeactivateItem(item, close);
        if(this.Items.Count == 0)
        {
            this.TryClose(); //No more tabs open, close window.
        }
    }

像这样更新MainChatWindowView.xaml TabControl:

        <TabControl x:Name="Items" HorizontalAlignment="Left" Height="417" VerticalAlignment="Top" Width="654">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding DisplayName}" />
                    <Button Content="X"
                            cal:Message.Attach="DeactivateItemAndTryClose($dataContext, 'true')" />
                </StackPanel>
            </DataTemplate>
        </TabControl.ItemTemplate>
    </TabControl>