假设您使用的是 ViewModel 优先方法,您是否检查过 ISceens 和 Screen 实现?当前的 Caliburn.Micro 下载包含一个带有屏幕协调器实现 (SimpleMDI) 的演示项目
您可以使用主视图模型中的激活/停用功能来处理“属性”视图之间的切换。
主视图模型应源自 caliburn 提供的 Conductor<T>.Collection.OneActive 实现,其中 T 应为 IScreen。这允许您的主视图模型一次只能激活一个屏幕。
基本上,如果您将“选定项目”绑定到主视图模型中的属性,您可以观察属性更改通知(使用 NotifyOfPropertyChange),然后使用某种例程来决定切换到哪个视图。
Caliburn 将缓存视图(在您的指挥器上使用 GetChildren),以便您可以在它们之间切换 - 保持性能。
我使用类似这样的东西来根据数据库和可用库动态实例化我的控件(请注意,我的示例有点令人困惑,因为 CurrentView 实际上是自定义类型而不是真正的视图 - 它只是一个数据库对象描述了已被选中的控件。我可能应该更改它!)
public MainPageViewModel : Caliburn.Micro.Conductor<IScreen>.Collection.OneActive
{
#region Property Changed handler
public override void NotifyOfPropertyChange(string propertyName)
{
base.NotifyOfPropertyChange(propertyName);
// A property changed, update the views if it's the CurrentView property
UpdateViews(propertyName);
}
#endregion
private void UpdateViews(string propertyName)
{
// If the selected item in my list changes, it's bound to CurrentView and contains
// the fully qualified typename of the ViewModel that the items 'screen' should use
if (propertyName == "CurrentView")
{
// If the selected item changes we need to load the control or retrieve it from the
// control cache, making sure to update the cache and the active view dictionary
try
{
var controlType = Type.GetType(CurrentView.QualifiedTypeName, true);
// Check to see if the view is already loaded
var view = GetChildren().FirstOrDefault(x => x.GetType() == controlType);
// If it is, just activate it
if (view != null)
{
ActivateItem(view);
}
else
{
// Otherwise it's not loaded, load it and activate it
view = (IScreen)Activator.CreateInstance(controlType);
ActivateItem(view);
}
// etc...
}
}