【问题标题】:Calburn Micro - IoC is not initialized in WPF designerCalburn Micro - IoC 未在 WPF 设计器中初始化
【发布时间】:2015-04-14 11:48:18
【问题描述】:

我有一个 WPF 应用程序,使用 Caliburn Micro 和用于 DI 的 StructureMap。

在我的窗口上,我有一个 ContentControl,它的名称是我的视图模型上的一个属性 - 在运行时,Caliburn 会根据该属性的类型成功定位正确的视图并将其显示在该区域中。

但是,在设计时,会引发异常:“InvalidOperationException:IoC 未初始化。”。查看堆栈跟踪,很明显 Caliburns ViewLocator 正在尝试使用 IoC 创建视图的实例,但 IoC 容器在设计时未初始化。

那么,问题是:如何在设计时初始化 Caliburn 的 IoC?

编辑:

这是我的 UserControl 声明:

<UserControl x:Class="MyNamespace.Views.Checklist.ChecklistQuestionEditView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         xmlns:vm="clr-namespace:MyNamespace.ViewModels.Checklist"
         xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro.Platform"
         d:DataContext="{d:DesignInstance Type=vm:ChecklistQuestionEditDesignerViewModel, IsDesignTimeCreatable=True}"
         cal:Bind.AtDesignTime="True"
         d:DesignHeight="700" d:DesignWidth="1000">

这是导致问题的 ContentControl:

<ContentControl IsTabStop="False" Grid.Row="2" Grid.Column="0" Margin="12" Name="TranslationView"/>

此控件通过视图模型中的此属性由 Caliburn 的名称约定填充:

private ChecklistQuestionTranslationViewModel _TranslationView;
public ChecklistQuestionTranslationViewModel TranslationView
{
    get { return _TranslationView; }
    set
    {
        if (_TranslationView != value)
        {
            _TranslationView = value;
            NotifyOfPropertyChange(() => TranslationView);
        }
    }
}

如果我从 XAML 中删除上面的 ContentControl 行,所有其他设计器功能都会按预期工作。

由于某种原因,您无法复制设计器的异常消息,所以我在这里放了一个屏幕截图。您可以看到 Caliburn 正在尝试使用 IoC 创建 View 的实例。但我没有 10 声望,所以我无法发布我的屏幕截图。

【问题讨论】:

  • 您是否已经为设计时进行了任何设置?代码 sn-p 有帮助。 caliburnmicro.com/documentation/design-time
  • 您能否在您的引导程序中添加对 StartDesignTime 的显式调用,看看它是否因异常而失败。
  • 我在我的 Bootstrapper 构造函数中添加了对 StartDesignTime 的调用 - 没有设计时更改 - 异常仍然发生,并且在运行时没有异常。
  • 我有类似的问题,我注意到当 ContentControl 尝试显示普通的 string 对象时会发生这种情况。当它试图显示一个复杂的对象时,通常会显示cannot find view for XYZ。但是对于string,要么是这次崩溃,要么很少是cannot find view for string
  • 我也遇到了这个问题。这是由于Configure 中的自定义引导程序中的异常所致。由于Configure 抛出异常,IoC 从未初始化。如果StartDesignTime 函数中有异常,那么 IoC 可能无法正常工作。您最终从另一个实例调试 XAML 设计器 XDesProc 以查找异常。

标签: wpf caliburn.micro


【解决方案1】:

您可能想看看this SO thread 我最近问(并回答):到目前为止对我们来说效果很好。

这种方法的要点是:

  1. 为您的每个视图模型准备一个设计时版本,包括容器/以及映射到@987654322的那个@你的观点(孩子)。

  2. 每个设计时版本都有空构造函数,无需设置外部依赖项。它必须完全依赖 DI/IoC 容器。

  3. 对于视图和原始视图模型之间的每个公共属性数据绑定,设计时视图模型应该具有同名的属性...不一定相同的类型。

    • 这是您的子视图模型映射到 ContentControl 的情况:真正的父视图模型具有例如MyCommandBarViewModel 类型的属性,而假父视图模型具有 MyDesignTimeCommandBarViewModel 类型之一。
  4. 这可能适用于视图模型的整个可视化树,叶子是仅显示简单属性类型(字符串、数字等)的视图模型

为了让 Designer 和 Caliburn.Micro 协同工作以生成这些设计时版本,您需要在根 UI 元素(Window、UserControl、...)上添加以下内容:

<Window 
  d:DataContext="{d:DesignInstance Type=fake:YourDesignTimeViewModel, IsDesignTimeCreatable=True}"
  cal:Bind.AtDesignTime="True">

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 2013-05-23
    相关资源
    最近更新 更多