SoapBox 框架 (WPF, .NET) 的一个简单示例





5.00/5 (5投票s)
SoapBox Core 使用 WPF 的 MEF 提供了一个易于扩展的基础应用程序框架。这是一个简单的示例,包含了一个基本应用程序的元素(工具栏、状态栏、文档区域等)。
引言
有关 SoapBox.Core
(SBC) 框架的介绍,请阅读使用 MEF、WPF 和 MVVM 构建可扩展应用程序。
SoapBox 框架引入的演示项目是一个弹珠游戏。它演示了框架提供的一些功能,但缺少许多应用程序不可或缺的一些功能。例如,工具栏。
我发现弹珠游戏示例对我自己使用而言并不是特别有用,于是我开始编写代码,尝试在自己的简单示例中弄清楚 SBC 的各个部分是如何工作的。我想我会在 KODI 中分享我的成果。
此外,按其编写方式,SoapBox 框架是解决方案文件夹中的一组项目,并且 SoapBox.Core.Host
作为可执行文件输出。因此,使用 SoapBox 要求我们将整套 SoapBox 项目包含在我们的本地解决方案中,并将 SBC Host 设置为启动项目。这存在几个问题
- 包含这些额外的项目有点混乱(并且可能增加编译时间)。
- 当 SoapBox 有更新时,在我们的所有项目中更新 SoapBox 项目很麻烦。
- Visual Studio 的 Express 版本不支持解决方案文件夹(它们也不支持混合语言,因此不能在例如 Visual Basic 项目中使用 SoapBox C# 源代码)。(作为一种解决方法,您可以使用 SharpDevelop 或 MonoDevelop(有bug?)打开使用解决方案文件夹或混合语言的项目。)
概述
因此,对于本文,我将首先描述如何设置 SoapBox.Core.Host
,以便 SBC 可以用作一组 DLL。示例项目还将 DLL 移动到单独的文件夹中,而不是将它们全部放在应用程序的基本文件夹中。
其次,我将展示一个简单的示例解决方案,其中包含一个启动项目和一个“feature
”项目,该项目具有大多数应用程序所需的一些基本功能(工具栏、状态栏、文档区域等)。
修改 SoapBox.Core.Host
首先,将项目类型从 WinExe
更改为 Library
。
其次,将 App.xaml.cs 重命名为 App.cs 并删除 App.xaml。附加的源代码中包含新文件的详细信息。它主要是 App.xaml.cs 的副本,加上我添加的一些用于设置和访问其目录的内容。
您可能还需要手动从 SoapBox.Core.Host.csproj 中删除此行
<StartupObject>SoapBox.Core.Host.App</StartupObject>
现在您可以构建 SoapBox 解决方案,然后将您想要使用的任何 DLL 复制到您自己的项目库中。
创建启动项目 (Example.Host)
此项目输出启动应用程序的可执行文件。它所做的几乎所有事情就是提供对 SBC DLL 的引用,然后设置并运行框架。然后框架完成其余的工作。以下是分步说明。
- 启动编辑器(我使用的是 Visual Studio C# Express 2010)。
创建一个新项目(新建 > 项目 > WPF 应用程序),命名为Example.Host
将Example.Host
另存为 ...
名称:Example.Host
位置:F:\Projects\Soapbox
解决方案名称:Example(为解决方案创建目录) - 在 Windows 资源管理器中(不是 Visual Studio),在解决方案文件夹中创建一个文件夹(命名为 Lib),并将所有 SoapBox、NLog 和 AvalonDock DLL 放入其中。
- 添加对 Lib 文件夹中所有 DLL 的引用。我们需要对所有这些 DLL 的引用,并将 Visual Studio “复制本地”属性设置为
true
,即使Example.Host
不明确需要其中一些,以便它们被复制到输出文件夹。(这是一种方法;有许多不同的方法可以将这些文件复制到输出文件夹中。) - 添加对
System.ComponentModel.Composition
的引用 - 删除 App.xaml、MainWindow.xaml 和相关的 .cs 文件。
- 添加一个带有
Main
方法的 Program.cs,该方法创建一个新的SoapBox.Core.Host.App()
对象。 - 将目录添加到
app
对象,以便 SBC 知道在哪里查找它们。 - 调用
app
对象上的Run()
方法。 - 将构建位置更改为 ..\bin\Debug 和 ..\bin\Release(请确保所有项目都输出到正确的文件夹,否则当您运行应用程序时,如果内容没有出现,您会感到困惑)。
- 此时,如果您运行项目,您应该会得到一个纯净的工作台(比截图中更大,但其他方面相同)。
创建一个示例“功能”项目 (Example.HelloWorld)
对于应用程序的每个主要“功能”,您都希望有一个单独的项目。对于更松散耦合的解决方案,所有功能都将引用一个通用项目,例如 SoapBox 示例中出现的“Contracts
”项目。为简单起见(并且因为只有一个功能),所有契约都位于 HelloWorld
中(请参阅源代码中的 CompositionPoints
和 ExtensionPoints
文件)。
您可能还希望将其中一个功能(甚至上面的“主机”项目)设置为主 shell,以提供“主”工具栏、关于框等。
示例应用程序演示了以下项目
// Set application icon by reading it as an embedded resource
Uri u = new Uri("pack://application:,,,/Example.HelloWorld;component/App/star.png", UriKind.Absolute);
mainWindow.Value.Icon = new BitmapImage(u);
- 应用程序图标。SoapBox 示例使用作者评论为“hacky”的方式,即创建一个
Window
类并使用 VS 设计器设置图标……我实现了一个“不那么 hacky”的一行或两行方法,该方法将图像作为嵌入资源读取。即: - SBC
StartupCommands
(Shutdown 命令类似)。此示例中的启动命令用于在应用程序启动时显示食谱文档和说明面板。 - 一个 SBC Pad(弹珠演示也使用一个 pad)。
- 一个 SBC 文档。SBC 文档和 Pad XAML 基于带有
DataTemplate
的ResourceDictionaries
,这些在 Visual Studio 设计器中不可编辑。此示例演示了引用UserControl
,以便 Visual Studio 设计器可以用于编辑布局。对于这样一个简单的示例来说,这不是一个很大的优势,但如果布局更复杂,那就太棒了。 - 一个 SBC
ToolBar
,其中包含一个通过IExecutableCommand
链接的ToolBarButton
,用于执行一些操作(显示MessageBox
)。 - 一个 SBC
StatusBar
,其中包含几个不同的项目。 - 向菜单添加项目(例如“关于”项目)。
以下是最基本的逐步说明,作为创建这些项目之一的秘诀。
- 向解决方案添加一个新的 WPF 项目,命名为
Example.HelloWorld
。我发现这比使用库项目然后不得不添加所有 WPF 引用更容易。 - 删除 App.xaml、MainWindow.xaml 和相关的 .cs 文件。
- 在项目属性中,将项目类型更改为类库。
- 添加对
System.ComponentModel.Composition
的引用。 - 添加对
Soapbox.Core.Contracts
的引用。 - 将构建位置更改为 ..\bin\Debug。
- 根据需要使用 Export 和 Import 开始添加 SBC 项目....
关注点
要从作者处下载 SoapBox Core 及相关项目,请访问 SoapBox Core。有关常见问题解答和一些快速示例,请访问 ask.soapboxcore.com。
我花了一段时间尝试弄清楚如何将 SBC DLL 合并到一个文件中。ILMerge
这种传统方法不适用于 WPF。我尝试的其他几种方法都不奏效,并给了我各种错误,我想这意味着 MEF 找不到正确的程序集,或者同一个程序集正在不同的上下文中加载。
松散耦合项目的故障排除可能很棘手。这里有一个有趣的参考资料:如何调试和诊断 MEF 失败。
历史
- 2012-02-12: 第一版