手动设置主窗口并编写应用程序(MEF)时无法显示WPF应用程序

手动设置主窗口并编写应用程序(MEF)时无法显示WPF应用程序,wpf,mef,mainwindow,Wpf,Mef,Mainwindow,我从MEF获得了一周的时间,我正在尝试构建一个WPF应用程序,加载从MEF导入的控件 我创建了一个WPF应用程序项目,并删除了默认窗口和应用程序启动URI。然后,我处理了应用程序启动事件以编写应用程序: public partial class App : Application, IPartImportsSatisfiedNotification { {...} private void App_Startup(object sender, StartupEventArgs

我从MEF获得了一周的时间,我正在尝试构建一个WPF应用程序,加载从MEF导入的控件

我创建了一个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()调用会引发异常:

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

虽然我在OnImportssatifized方法中的代码看起来不错,因为它在不使用MEF mecanism时工作正常:

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所做的比它所说的要多一些,因为它是在我的实际应用程序实例上运行的唯一成员

希望有人能帮我(格伦?)。 谢谢


编辑:


我发现,当我从我的部件中删除iPartimportsAssetFiedNotification接口时,不会引发异常并显示窗口。但是当然,窗口是空的,因为我需要这个OnImportsAssetified方法来将窗口的DataContext设置为其关联的导入视图模型。

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


我用RequiredCreationPolicy设置为NonShared来标记我的导入,一切恢复正常!这就是学习MEF的全部内容。

的示例应用程序演示了如何在WPF应用程序中使用MEF