Discovering open source WPF components – Orc.Analytics

In the discovering open source WPF components series, I will look into useful open source components that can be used to create WPF apps. This weeks component is Orc.Analytics.

Analytics can be very helpful to analyze what features are being used the most. This information can be used when prioritizing new features or bug reports. Adding analytics to a WPF application can be cumbersome, but thanks to Orc.Analytics this is very easy to accomplish in a few steps:

  1. Create a Google Analytics ID
  2. Customize the service using this code:

Automatically sending data

Thanks to the auditing functionality in Catel, the library will automatically send data when one of the following events occur:

  • Command executed
  • ViewModel created
  • ViewModel closed (because it stores the timings / view model, it will also submit the lifetime of a view model so you can analyze how long a user is on a specific view)

Manually sending data

The library also allows you to manually send data for the following possible analytics events:

  • View (SendViewAsync method)
  • Event (SendEventAsync method)
  • Transaction (SendTransactionAsync method)
  • Timing (SendTimingAsync method)

Manually tracking views

Maybe not all the views have a view model. It is still possible to track these views by using the TrackViewForAnalyticsAsync extension method:

Viewing and analyzing the data

Once all the users are submitting the data (ask them for permission first!), then you can start analyzing your data using Google Analytics:

image

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.

Running code in a XAML designer at design-time

Recently I needed to show dynamic values in the XAML designer (WPF, Silverlight, Windows Phone, WinRT) to show real-time translations through a LanguageService that were wrapped in a markup extension. That sounds complex, but below is an image that shows what I wanted to achieve:

image

As the image shows, I needed quite some dynamic content to be loaded during design-time. When running the application, I can easily customize the IoC container in App.xaml.cs, but that doesn’t work at design-time.

After some searching on the internet, I found this article by Josh Smith.Unfortunately the Visual Studio 2013 designer (and maybe other versions as well) doesn’t load the assembly attributes thus it was not working for me. Though the solution represented below is part of Catel, it can be used without it as well.

Introducing the DesignTimeCode attribute

To allow users to run code in the designer (Visual Studio or Blend), we first need to introduce the DesignTimeCodeAttribute. This is an assembly-wide attribute which will specify the class to create at design time (just like Josh Smith recommended). This means that it is possible to create multiple attributes. Below is the class definition:

Below is an example of the usage of the attribute:

Introducing the DesignTimeInitializer

The DesignTimeCodeAttribute contains the types that are constructed during design-time. The problem is that every type specified in the DesignTimeCodeAttribute must check whether it is running in design mode, otherwise it might also fire at runtime. The DesignTimeInitializer base class will aid developers in process and check for this in the constructor.

Below is an example of the usage of the DesignTimeInitializer:

Making it actually run code at design-time

So far, we haven’t done much different from the solution Josh Smith provided. However, it was still not working at this level for me. The reason is that the Visual Studio 2013 designer does not read the assembly attributes and thus will not create our design time initializers.

The solution here is a two-step process, and requires the use of ModuleInit.Fody. If you are not familiar with ModuleInit.Fody, you can read about it here. Basically it allows you to run code as soon as an assembly is loaded (a.k.a. assembly-wide constructors). Installing it is really simple via NuGet.

The next step we need to take is to add initialization code as soon as our assembly is loaded. The code below reads the attribute from all loaded assemblies and initializes the code:

Checking out the final result

Below is a short gif showing that the designer now runs code at design-time. It does this by registering a custom source in the LanguageService. Then every time the project is rebuilt, the LanguageService is updated and will reflect the changes at design time.

Running code at design time