我有一个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,并关闭该选项卡。 我的问题:一旦所有标签都消失了,我就不确定如何发出关闭窗口的信号。希望我不会错过一些明显的东西,但我已经经历了一大堆功能,事件和覆盖试图让它在我的情况下工作..我应该重组这个吗?
答案 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>