0

我知道默认情况下 CM 会在 Views 文件夹中查找 ShellView 以用作 ShellViewModel 视图,但我想改用 MainWindow ......这可以做到吗?怎么做?

4

2 回答 2

1

这个怎么运作

CM 使用一组View/ViewModel Naming Conventions,一般来说,如果您有一个名为FooViewModelCM 的 ViewModel 将尝试定位具有相似名称的类型FooViewor FooPage

如果你真的想要“MainWindow”和“ShellViewModel”怎么办?

如果您只想将现有的“MainWindow”与现有的“根视图模型”一起使用,请考虑子类化Bootstrapper<TRootModel>和覆盖OnStartUp。这是一种规定的方法,但似乎令人生畏。

(我没有测试过这段代码。)

    protected override void OnStartup(object sender, StartupEventArgs e)
    {
        var rootModel = IoC.Get<TRootModel>();
        var rootView = new MainWindow();
        ViewModelBinder.Bind(rootModel, rootView, this);
        rootView.Show();
    }

当然,上述方法仅适用于启动期间显示的根视图模型的初始视图。未来尝试显示视图ShellViewModel可能会起作用,或者可能会导致错误,我不确定。

扩展约定

有几种方法可以自定义约定本身。最灵活和直接的方法是拦截/挂钩Caliburn.Micro.ViewLocator.LocateForModelType,这允许您修改在视图定位期间应用的行为/策略。

    private static void CustomViewLocatorStrategy()
    {
        // store original implementation so we can fall back to it as necessary
        var originalLocatorStrategy = Caliburn.Micro.ViewLocator.LocateForModelType;

        // intercept ViewLocator.LocateForModelType requests and apply custom mappings
        Caliburn.Micro.ViewLocator.LocateForModelType = (modelType, displayLocation, context) =>
        {
            // implement your custom logic
            if (modelType == typeof(ShellViewModel))
            {
                return new MainWindow();
            }
            // fall back on original locator
            return originalLocatorStrategy(modelType, displayLocation, context);
        };
    }

可以从Bootstrapper<TRootModel>.Configure覆盖内部调用上述内容:

    protected override void Configure()
    {
        CustomViewLocatorStrategy();
        base.Configure();
    }

这种方法更可能与 CM 配合使用(即,就任何视图缓存而言)。但是,它仍然打破常规,并且仍然是相当多的代码。

注册附加后缀?

我想指出但没有机会尝试的一件事是ViewLocator.RegisterViewSuffix实施。我相信如果您执行ViewLocator.RegisterViewSuffix(@"Window"),那么您可以依靠 CM 映射MainViewModelMainWindow.

这将允许更具表现力的后缀(例如 Window、Dialog、Form 或您可能想要使用的其他后缀。)我个人不喜欢使用 'View' 作为后缀,我认为它太通用了(毕竟,它们都是意见。)

于 2013-06-29T07:34:08.697 回答
0

默认情况下,Caliburn.Micro 不查找 ShellView,这就是事情的工作方式。假设您有一个这样定义的引导程序:

class MyBootsrtapper : Bootstrapper<MyViewModel> { }

然后 CM (Caliburn.Micro) 将查找名为 MyView 的视图。所以是的,只要您的视图模型名称是 MainWindowViewModel,您就可以使用 MainWindow。
我已经回答了您提出的另一个问题,而且您似乎没有完全理解 CM,所以我真的建议从这里开始,您可以随时查看codeplex 上 的项目文档,因为它包含所有更新的信息和文档。

编辑:

Caliburn.Micro 使用简单的命名约定来定位 ViewModel 的视图。本质上,它采用 FullName 并从中删除“Model”。因此,给定 MyApp.ViewModels.MyViewModel,它将查找 MyApp.Views.MyView。

取自官方文档here

于 2013-06-28T21:41:41.140 回答