手动设置MainWindow并组合应用程序(MEF),无法显示WPF应用程序

3
我现在已经接触MEF一周了,试图构建一个从MEF导入控件的WPF应用程序。
我创建了一个WPF应用程序项目,并删除了默认窗口和应用程序启动URI。然后我处理了应用程序启动事件来组合应用程序:
public partial class App : Application, IPartImportsSatisfiedNotification
{
    {...}

    private void App_Startup(object sender, StartupEventArgs e)
    {
        this.Compose();
    }

    public void Compose()
    {
        try
        {
            globalCatalog.Catalogs.Add(new DirectoryCatalog(extensionsDirectoryPath));
            CompositionContainer container = new CompositionContainer(globalCatalog);
            container.ComposeParts(this);
        }
        catch (Exception ex)
        {
            // Do something
        }
    }

    {...}
}

实际上,在导入满足后进行调试和观察对象时,一切都像我想要的那样分层组合得很好。但是当我尝试显示应用程序的MainWindow时,调用MainWindow.Show()会引发异常:

"指定的元素已经是另一个元素的逻辑子级。请先断开它。"

虽然我的OnImportsSatisfied方法中的代码看起来没问题,但在不使用MEF机制时它可以正常工作:

public void OnImportsSatisfied()
{
    Window mainWindow = new Window();
    mainWindow.Content = this.importedControl;
    this.MainWindow = mainWindow;
    this.MainWindow.Show();
}

我坚持认为,当不使用MEF导入控件时,这段代码可以完美运行。令人惊讶的是,即使是下面这段代码也无法正常工作:
Window mainWindow = new Window();
//mainWindow.Content = this.importedControl;
this.MainWindow = mainWindow;
this.MainWindow.Show();

我怀疑ComposeParts做了更多的事情,因为它是唯一在我的实际应用程序实例上操作的成员。
希望有人能帮助我(Glenn?)谢谢。
编辑:
我发现当我从我的部件中删除IPartImportsSatisfiedNotification接口时,就不会抛出异常并且窗口会显示出来。但是,当然,窗口是空的,因为我需要这个OnImportsSatisfied方法将窗口的DataContext设置为其关联的导入视图模型。
2个回答

1

0

我最终发现,我是通过使用默认的ImportAttribute构造函数导入我的WPF用户控件的,如果在导出期间未指定创建策略,则实际上会创建该类的共享实例。由于我的许多控件都实现了相同的接口,并且我正在将它们绑定到我的视图中,因此我实际上正在尝试将此共享用户控件实例添加到不同的可视元素中,这是WPF不允许的(因此异常)。

我使用RequiredCreationPolicy标记了我的导入项,设置为NonShared,一切都恢复正常了!这就是关于学习MEF的全部内容...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接