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

时间:2014-10-02 18:26:02

标签: c# mvvm caliburn.micro

我有一个MainComm VM,它创建一个MainChatWindow VM窗口,MainChatWindowVM是一个conductor.OneActive并包含一个tab控件,其中每个tab都是一个动态添加的ChatTabVM。关闭最后一个聊天对话后,MainChatWindow VM导体不再包含Items,并且我需要以某种方式触发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按钮,单击该按钮会调用该tabViewModel的MainChatWindowViewModel指令DeactivateItem,并关闭该选项卡。 我的问题:一旦所有标签都消失了,我就不确定如何发出关闭窗口的信号。希望我不会错过一些明显的东西,但我已经经历了一大堆功能,事件和覆盖试图让它在我的情况下工作..我应该重组这个吗?

1 个答案:

答案 0 :(得分:0)

我已经用尽所有Caliburn Micro的功能来自动执行此操作,而且我不认为存在这样的事情。话虽如此,有一种明显而简单的方法可以通过替换tab close上的去激活调用来处理这个问题,如下所示:

将此功能添加到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>