Click here to Skip to main content
15,867,860 members
Articles / Desktop Programming / WPF

A Simple Example for the SoapBox Framework (WPF, .NET)

Rate me:
Please Sign up or sign in to vote.
5.00/5 (5 votes)
10 Aug 2012LGPL36 min read 29.4K   1.3K   13   4
SoapBox Core uses WPF's MEF to provide a base application framework that is easy to extend. This is a simple example that includes elements of a basic application (toolbar, statusbar, document area, etc.).

328951/ExampleApplication.png

Introduction

For an introduction to the SoapBox.Core (SBC) framework, read Building an Extensible Application with MEF, WPF, and MVVM.

The demo project that is introduced with the SoapBox framework is a pinball game. It demonstrates a few things that the framework provides, but is missing a few that are integral to many applications. A toolbar, for example.

I did not find the pinball example particularly useful for my own use and started writing code to figure out how various parts of SBC work in a simple example of my own. I figured I would share my results here.

Also, as it's written, the SoapBox framework is a set of projects within solution folders, and SoapBox.Core.Host is output as an executable. So using SoapBox requires that we include the whole set of SoapBox projects within our local solution and set SBC Host as the startup project. There are several problems with this:

  1. Including these extra projects is kind of messy (and can increase compile time).
  2. When SoapBox has an update, updating the SoapBox projects in all of our projects is messy.
  3. The Express editions of Visual Studio don't support solution folders (they also don't support mixed languages, so can't use the SoapBox C# sources within, say, a Visual Basic project). (As a workaround, you can use SharpDevelop or MonoDevelop (buggy?) to open projects that use solution folders or mixed languages.)

Overview

So for this article, first I will describe how to set up the SoapBox.Core.Host so the SBC can be used as a set of DLLs. The example project also moves the DLLs into separate folders instead of having them all in the application's base folder.

Second, I will present a simple example solution containing a startup project and a "feature" project that has some basic things most applications need (toolbar, status bar, document area, etc.).

Modifying SoapBox.Core.Host

First, change the project type from WinExe to Library.

Second, rename App.xaml.cs to App.cs and remove App.xaml. The attached source code has the details for the new file. It is mainly a copy of App.xaml.cs, plus some things I added for setting and accessing its catalog.

You may also need to manually remove this line from SoapBox.Core.Host.csproj:

XML
<StartupObject>SoapBox.Core.Host.App</StartupObject>

Now you can build the SoapBox solution and then copy whichever DLLs you want to use to your own project library.

328951/SolutionFolders.png

Creating the Startup Project (Example.Host)

This project outputs the executable file that starts the application. Pretty much all it does is provide references to the SBC DLLs and then set up and run the framework. Then the framework does the rest of the work. Here's a step-by-step.

  1. Start the editor (I am using Visual Studio C# Express 2010).
    Create a new project (New > Project > WPF Application), named Example.Host
    Save Example.Host As ...
    Name: Example.Host
    Location: F:\Projects\Soapbox
    SolutionName: Example (Create directory for solution)
  2. In Windows Explorer (not Visual Studio), create a folder (named Lib) in the solution folder and put all of the SoapBox, NLog, and AvalonDock DLLs in it.
  3. Add references to all of the DLLs in the Lib folder. We need references to all of these with the Visual Studio "Copy Local" property set to true, even though Example.Host doesn't explicitly need some of them, so they get copied to the output folder. (This is one way to do it; there's a number of different ways to get these copied to the output folders.)
  4. Add a reference to System.ComponentModel.Composition
  5. Delete App.xaml, MainWindow.xaml, and related .cs files.
  6. Add Program.cs with a Main that creates a new SoapBox.Core.Host.App() object.
  7. Add catalogs to the app object, so SBC knows where to look for them.
  8. Add a call to Run() on the app object.
  9. Change the build Location to ..\bin\Debug and ..\bin\Release (Be *sure* that all projects output to the correct folders or you will be scratching your head when things don't appear in the application when you run it).
  10. At this point, if you run the project, you should get a plain workbench (bigger than the screenshot, but otherwise the same).

Creating an Example "Feature" Project (Example.HelloWorld)

For each main "feature" of your application, you'll want a separate project. For a more loosely coupled solution, all features would refer to common project, such as the "Contracts" project that appears in SoapBox examples. For simplicity (and because there's only one feature), all of the contracts are in HelloWorld (see the CompositionPoints and ExtensionPoints files in the source code).

You might also want to set up one of the features (or even the 'host" project above) as the main shell, to provide a "main" toolbar, about box, etc.

The example application demonstrates the following items:

C++
// 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);
  • Application icon. SoapBox examples use a way that the author comments as "hacky", which creates a Window class and sets the icon with the VS designer... I implemented a "less hacky" one- or two-liner method that reads the image as an embedded resource. Namely,
  • SBC StartupCommands (Shutdown commands are similar). The startup command in this example is used to display the recipe document and instructions pad when the application starts.
  • An SBC Pad (the pinball demo uses a pad, as well).
  • An SBC Document. SBC Document and Pad XAMLs are based on ResourceDictionaries with a DataTemplate, which are not editable in Visual Studio designer. This example demonstrates referencing a UserControl so that the Visual Studio designer CAN be used to edit the layout. Not a big advantage for a simple example like this, but great if the layout is more complex.
  • An SBC ToolBar with a ToolBarButton that is linked via an IExecutableCommand to perform some action (display a MessageBox).
  • An SBC StatusBar with several different items in it.
  • Adding items to the menu (such as the About item).

Here is the most basic step-by-step, as a recipe for creating one of these projects.

  1. Add a New WPF project, named Example.HelloWorld, to the solution. I find this easier than using a library project and then having to add all of the WPF references.
  2. Delete App.xaml, MainWindow.xaml, and associated .cs files.
  3. In the project properties, change the project type to Class Library.
  4. Add a reference to System.ComponentModel.Composition.
  5. Add a reference to Soapbox.Core.Contracts.
  6. Change the build Location to ..\bin\Debug.
  7. Start adding SBC items by using Export and Import as needed....

Points of Interest

For downloading the SoapBox Core and related projects from its author, visit SoapBox Core. For FAQs and some quick examples, visit ask.soapboxcore.com.

I messed around for a while trying to figure out how to merge the SBC DLLs into a single file. ILMerge, the traditional method, doesn't work for WPF. Several other methods I tried didn't work and gave me various errors that I think meant MEF couldn't find the correct assemblies or that the same assembly was being loaded in different contexts.

Troubleshooting loosely coupled projects can be tricky. Here's an interesting reference: How to Debug and Diagnose MEF Failures.

History

  • 2012-02-12: First edition

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
United States United States
I am an Electrical Engineer. I play with stuff (hardware, software, graphics, documentation).

Comments and Discussions

 
Questionproblem with package distribution Pin
CursorByte3-Jan-17 20:48
CursorByte3-Jan-17 20:48 
QuestionSome help to get started Pin
helkhoury29-Jun-14 7:06
helkhoury29-Jun-14 7:06 
QuestionProblems getting started Pin
Member 865000616-Feb-12 3:22
Member 865000616-Feb-12 3:22 
In the "Modifying SoapBox.Core.Host" section you say "Now you can build the SoapBox solution ". What solution? Do I make a new solution ? What do I include in it? All of the SoapBox.Core projects? Only the SoapBox.Core.Host project? That doesn't simply compile. What are the dependencies on this? I could get as far missing "Composition" in order to build SoapBox.Core.Contracts.

I downloaded your modified source, and I experienced the same issues and questions. In that solution you only have SoapBox.Core.Host, and equally it doesn't compile off the bat, missing refferences to "IArgumentsService" and a lot of other ones.

Any help would be appreciated
AnswerRe: Problems getting started Pin
dreamgarden16-Feb-12 7:55
dreamgarden16-Feb-12 7:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.