尽管命名约定相同,为什么 Caliburn Micro 绑定了一些视图而不绑定其他视图?

Why is Caliburn Micro binding some views but not others despite same naming conventions?

我有 3 个视图模型:

和 3 次浏览:

在我的 AppBootstrapper 中,LoginView 是这样加载的:

protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
    var windowManager = IoC.Get<IWindowManager>();
    var loginModel = IoC.Get<ILogin>("Login");

    windowManager.ShowWindow(loginModel, "LoginView");
}

但是,returns 找不到该 ViewModel 的视图。 除非我将 LoginView 的命名空间 更改为 App.Views.Login.LoginView 并保持 VM 命名空间不变。然后它工作正常。

成功登录后,我使用相同的过程加载我的 NavigationViewModel。 (在将命名空间更改为 App.Views.Navigation.NavigationViewModel 以便它实际工作之后)

目前,这给我留下了以下视图命名空间:

NavigationViewModel 是一个导体,它有一个 ViewModel 列表和一个用于显示它们的视图上的 TabControl。

不幸的是,我必须手动将我的 AbcViewModel 绑定到视图,否则不会显示任何内容。例如:

AbcView abcv= new AbcView ();
AbcViewModel abcvm= IoC.Get<AbcViewModel>("Abc");
ViewModelBinder.Bind(abcvm, abc, null);

我希望所有事情都使用 Caliburn ViewModel 优先方法完成,这样我就不需要担心手动绑定视图的问题。我遵守了该结构,但它不起作用。我哪里错了?

基本上,有没有一种方法可以让 Caliburn 在我创建 ViewModel 时创建并绑定我的视图? 我是否需要以某种方式为我的每个模型调用 ViewLocator?如果是这样,这与我目前正在执行的手动绑定有何不同?

有谁知道视图模型第一个 Caliburn 项目的完整示例(整个项目),我可以偷看一下?

感谢任何帮助,提前致谢。

马特

您不需要自己绑定任何 Views/ViewModels,Caliburn.Micro 会处理它。您只需通过覆盖 Bootstrapper class 中的 OnStartup 来告诉 Caliburn.Micro 您的起点 class(参见 tutorial)。

您还必须在 App.xaml 中为 ResourceDictionary 提供 Bootstrapper class 并删除 Startup:

    <Application.Resources>
        <!--Declare your bootstrapper class-->
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <local:YourBootstrapperClass x:Key="bootstrapper" />
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

您的 Bootstrapper class 必须派生自 BootstrapperBase 并在构造函数中调用 Initialize()。这应该足以 Caliburn.Micro 绑定 views/viewmodels.


另外,如果你想在你的项目中使用 Dependency Injection,你可以设置一个 SimpleContainer 并注册你想要注入的类型。您可以在 Bootstrapper:

中执行此操作
public class Bootstrapper : BootstrapperBase
    {
        // Container for your registered types.
        private SimpleContainer _container = new SimpleContainer();

        public Bootstrapper()
        {
            Initialize();
        }

        protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
        {
            // Tells Caliburn.Micro where the starting point of your application is.
            DisplayRootViewFor<ShellViewModel>();
        }

        protected override void Configure()
        {
            // Register types you want to inject.
            _container.Singleton<IWindowManager, WindowManager>();
            _container.Singleton<IEventAggregator, EventAggregator>();
            base.Configure();
        }

        protected override object GetInstance(Type service, string key)
        {
            // This is called every time a dependency is requested. 
            // Caliburn.Micro checks if container contains dependency and if so, returns it.
            var instance = _container.GetInstance(service, key);
            if (instance != null)
                return instance;

            throw new InvalidOperationException("Could not locate any instances.");
        }

        protected override IEnumerable<object> GetAllInstances(Type service)
        {
            // Get all registered classes...
            return _container.GetAllInstances(service);
        }

        protected override void BuildUp(object instance)
        {
            _container.BuildUp(instance);
        }

    }

之后你可以像这样通过构造函数注入依赖项:

public class ShellViewModel 
{
    public ShellViewModel(IEventAggregator eventAggregator)
    {
          // You can use eventAggregator here. It is already injected.
    }
}

Caliburn.Micro 使用命名约定,以便它可以自动发现 Views/ViewModels。您应该将文件夹命名为:ViewsViewModels,并且您的 classes 应该命名为 YourClassViewYourClassViewModel。这样 Caliburn.Micro 就可以找到他们。因此,如果您像这样设置 OnStartup

protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
    DisplayRootViewFor<ShellViewModel>();
}

那么您的视图模型必须位于 ViewModels/ShellViewModel 中,您的视图模型必须位于 Views/ShellView 中。