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

时间:2010-07-15 09:37:18

标签: wpf mef mainwindow

我现在已经拿到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 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比它说的更多,因为它是唯一一个代理我的实际应用程序实例的成员。

希望有人可以帮助我(格伦?)。 感谢。


编辑:

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

2 个答案:

答案 0 :(得分:1)

WPF Application Framework (WAF) 的示例应用程序展示了如何在WPF应用程序中使用MEF。

答案 1 :(得分:0)

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

我使用RequiredCreationPolicy设置为NonShared标记了我的导入,所有内容都按顺序返回!那就是学习MEF ......