Developing enterprise WPF apps – a list of very useful components

At the company I work for, we write lots of enterprise apps using WPF. The base for all of the apps started by using Catel, but we immediately felt we had to fill a lot of gaps. To prevent Catel becoming an unmanageable beast, we decided to create a second group of open source components under the Orc.* branding.

This week, we finally put all the components into their first stable release, meaning we think they are usable in production for WPF apps. This blog post will introduce all the components we have at the moment with a short description. Each component has a description on the corresponding GitHub page as well with examples.

Some history

The idea behind the Orc branding is to have a basic shell (Orchestra) that people can use to get up and running very quickly. You can pick your shell (for example, using a ribbon with Fluent.Ribbon) and start working on your actual application logic instead of the application boilerplate code.

The major advantage for you is that we use these components in over 10 applications. This means very active development (nearly daily updates to the components). We are also trying to make all components have the same look and feel to it really works as a component suite.

The components

The list of components is long, therefore I have chosen to create a table instead of a detailed summary of each component. In upcoming blog posts I plan to highlight more features and details of specific components.

Component name Description
Orc.Analytics Makes it very easy to integration Google Analytics with Catel projects.
Orc.AutomaticSupport Allows the user to easily download a remote file that will validate and provide automatic support to the end-user.
Orc.CommandLine Command line parsing with an easy context class and automatic help system.
Orc.Controls WPF controls like DatePicker, DateTimePicker, TimeSpanPicker, LogViewer, WatermarkTextBox and much more…
Orc.CrashReporting Catch unhandled exceptions and automatically gather information to submit for the end-user as crash reports.
Orc.CsvHelper Small library of extensions and helper methods for the CsvHelper library.
Orc.Feedback Allows developers to easily get feedback from the end-user.
Orc.FilterBuilder Adds complex filtering functionalities to your application. A user can create custom (dynamic) filters in a visual way and store them. Very nice component to allow a user to create filters of collections.
Orc.LicenseManager Check software licenses. Consists of client and server (example) code. Uses Portable.Licensing under the hood.
Orc.LogViewer If the LogViewer in Orc.Controls is too basic for you, this component expands that control by adding filtering and much more features.
Orc.Metadata Provides base classes to store metadata about objects. This can be useful for a lot of information about objects. Might seem abstract, but this prevents you from repeating the same code over and over again.
Orc.Notifications Show desktop notifications to the user with the ability to add commands to the notifications. In a few lines of code you have beautiful notifications in your app.
Orc.NuGetExplorer A custom NuGet explorer. We use this because plugins of our applications are deployed via NuGet. This component allows the users to install and update their plugins.
Orc.ProjectManagement Manage files and projects inside your application. Instead of messing around with lots of handlers and events, this library manages projects for you (can be a file, directory, database, really anything). Other components can subscribe to this if they are interested. Are you writing document-focused apps? You really want this one.
Orc.Search If you need search in your apps, this is the component to use. It can automatically index objects for you (in the background). Provides events to notify you when objects are being indexed or searched for. super fast searching thanks for Lucene.net which is being used under the hood.
Orc.Squirrel Wrapper around Squirrel (the new but better click-once). This library allows you to set up channels (like alpha, beta and stable) and manages the complex stuff under the hood.
Orc.SupportPackage Allows an end-user to create a support package with the right information for you to analyse issues. Because this component is plugin based, you can gather any information you need. The info will automatically be added to a zip file which the user can export and submit.
Orc.SystemInfo Ever needed system info of the end-user? This component gathers all the information. Also used by other components such as Orc.CrashReporting and Orc.SupportPackage.
Orc.WorkspaceManagement Workspaces are a combination of settings that represent the state of the UI. For example, if you want to allow your end-users to customize UI and store the customizations, workspaces is the solution. It also contains a workspace switcher so users can easily switch between workspaces. Since this component is plugin based, it can really be used for anything (from grids to ribbons to docking solutions, etc).
Orchestra Orchestra is a composable shell built on top of Catel. There are several shells like Fluent.Ribbon and MahApps. But Orchestra provides much more features like remappable keyboard shortcuts, splash screen, about window, consistent styling of your apps and much more.

Fix for WPF images and shared projects

Shared projects are crazy useful when developing for multiple platforms. Some people choose Portable Class Libraries (PCL), but if you need platform specific code, shared projects is the way to go.

TLDR;

Too long to read? Check out the animated gif on how to fix the issue.

sharedprojects_resources_wpf

The problem

Recently I was porting Orchestra and all Orc packages to support NET 4.5 besides NET 4.0. To do this, I introduce a shared project and create a NET40 and NET45 project that references the shared project. An example can be seen in the image below:

image

This works great because I only have to add files to the shared project, and the files will be compiled for both NET40 and NET45.

However, after converting my projects to shared projects, the WPF resources no longer worked. After digging into this issue, I found out that they don’t work very well with shared projects. As you can see in the image taking with .NET reflector below, it does not embed the resources correctly.

By default it uses the Content build action. Changing that to Resource manually via the properties window doesn’t work:

image

The next thing I tried was manually changing the item inside projitems (the shared project file).

This excludes the file from the projitems (no longer supported), but it does embed it as resource. Unfortunately the path is lost:

image

The solution

The solution is to use linked files for this. The following steps should be taken:

  1. Exclude the resources from the shared project (don’t delete them, just exclude them)
  2. Enable the Show all files toggle in the solution explorer
  3. Hold the Alt key and drag the resources to each project.
  4. Ensure that the build action of the resources is Resource

You can also check out the animated gif at the beginning of this post for a visual presentation of the fix.

Issue on MS Connect

Want this fixed? Please vote here on Microsoft Connect:

https://connect.microsoft.com/VisualStudio/feedback/details/1217939/wpf-resources-images-and-shared-projects-not-working-correctly

Easily measure performance of methods in .NET with MethodTimer

When developing applications in .NET, it’s wise to measure performance. While there are tools like performance counters available, they are simply too complex to set up and I hardly see anyone use them. The most used feature is the code below:

The downside of this is that it makes your code ugly to read (code waste) and you need to handle every return statement in the method to stop the stopwatch.

MethodTimer to the rescue

Simon Cropp has written a very nice weaver for Fody called MethodTimer that allows you to inject the stopwatch code above into any method by simply decorating it with an attribute.

Then it will be weaved into this:

Note that the code will take care of all return statements in the method, so all will be handled. Installing is super easy, just install the MethodTimer.Fody NuGet package.

Full support for async methods

Regular methods are easy, but what about async methods? They use state machines and there can be a lot of situations where the method can be returned. Starting with v1.15, async methods are fully supported. For example, the code below has a lot of return statements combined with await:

As you can see this method contains several return statements (before and after await statements), but will handle all situations. Measuring the duration of an (async) method has never been this easy!