我是Caliburn Micro的新手,想要了解我的应用程序界面和视图之间导航的路径。 我的想法是有一个MainWindow,它将包含一个按钮菜单,每个按钮都与一个特定的视图相关。每个视图都将存储在单独的WPF UserControl中。 mainWindow还将包含一个TabControl,该TabControl绑定到viewmodel上的ObservableCollection选项卡。每次单击菜单上的按钮时,我想添加一个内部有ContentPresenter的新选项卡,它将动态加载视图及其相应的视图模型。
所以我的问题:
1)我应该在这里使用屏幕收藏吗?
2)UserControl应该实现Screen界面吗?
3)如何告诉MainWindow ViewModel在新添加的选项卡上加载哪个视图,保持viewmodels解耦?
提前感谢所有人。
更新
经过大量的阅读和社区的帮助,我设法解决了这个问题。这是结果AppViewModel:
class AppViewModel : Conductor<IScreen>.Collection.OneActive
{
public void OpenTab(Type TipoVista)
{
bool bFound = false;
Screen myScreen = (Screen)Activator.CreateInstance(TipoVista as Type);
myScreen.DisplayName = myScreen.ToString();
foreach(Screen miItem in Items)
{
if (miItem.ToString() == myScreen.ToString())
{
bFound = true;
ActivateItem(miItem);
}
}
if (!bFound) ActivateItem(myScreen);
}
public ObservableCollection<MenuItem> myMenu { get; set; }
public ObservableCollection<LinksItem> myDirectLinks { get; set; }
public ICommand OpenTabCommand
{
get
{
return new RelayCommand(param => this.OpenTab((Type) param), null);
}
}
public AppViewModel()
{
OpenTab(typeof(ClientsViewModel));
MenuModel menu = new MenuModel();
myMenu = menu.getMenu();
myDirectLinks = menu.getLinks();
}
public void CloseTab(Screen param)
{
DeactivateItem(param, true);
}
}
我必须保持ICommand不受OpenTabCommand的影响,因为Caliburn.micro的名称约定似乎不适用于DataTemplate。希望它可以帮助别人。感谢所有
答案 0 :(得分:3)
我使用Caliburn.Micro
完成了类似的操作,并基于示例中包含的SimpleMDI
示例,并根据我的需要进行了一些调整。
在示例中,我有一个主ShellViewModel
:
public class ShellViewModel : Conductor<IScreen>.Collection.OneActive
{
}
使用包含ShellView
- TabControl
的相应<TabControl x:Name="Items">
,将其绑定到Items
的{{1}}属性。
在这种特殊情况下,我的Conductor
上有一个ContextMenu
,绑定(使用ShellView
约定)到一系列实例化的命令Caliburn.Micro
各种其他Activated
(通常使用相应的ViewModels
,使用UserControl
上的ActivateItem
方法。
Conductor
在这种情况下,我不需要使用任何特定的依赖关系创建public class YourViewModel: Conductor<IScreen>.Collection.OneActive
{
// ...
public void OpenItemBrowser()
{
// Create your new ViewModel instance here, or obtain existing instance.
// ActivateItem(instance)
}
}
,也不需要从程序中的任何其他位置创建。{/ p>
在其他时候,当我需要从应用程序的其他位置触发ViewModels
时,我已使用ViewModel
Caliburn.Micro
发布自定义事件(例如{{1} }),可以由实现相应接口的类(例如EventAggregator
)处理,因此您的主OpenNewBrowser
可以有一个简单的IHandle<OpenNewBrowser>
方法负责打开所需的ViewModel
:
Handle
This section文档可能会有用,尤其是Simple MDI部分。
我在评论中提到的其他代码:
我有时会沿着这些行使用泛型方法,确保如果我有特定类型屏幕的现有实例,请切换到它,或者如果没有则创建新实例。
View
用过:
public class YourViewModel: Conductor<IScreen>.Collection.OneActive, IHandle<OpenNewBrowser>
{
// ...
public void Handle(OpenNewBrowser myEvent)
{
// Create your new ViewModel instance here, or obtain existing instance.
// ActivateItem(instance)
}
}