Filtering Intellisense lists in the WF RuleSetDialog

Recently on our project we’ve been diving into Windows Workflow Foundation, particularly the rules engine. This process is relatively painless since Microsoft was kind enough to expose the RuleSetDialog class so that you can use the WF Rule Set editor in your application. This code is as easy as doing something like this:

// Create a RuleSet that works with Orders (just another .net Object)
RuleSetDialog ruleSetDialog = new RuleSetDialog(typeof(Order), null, null);

// Show the RuleSet Editor
ruleSetDialog.ShowDialog();

// Get the RuleSet after editing
RuleSet ruleSet = ruleSetDialog.RuleSet;

That’s how simple it is to include the RuleSetDialog in your application. The problem is that the Intellisense dropdowns in the RuleSetDialog expose private and protected members of your class, and Microsoft doesn’t give you any way to filter the Intellisense list. So you end up with stuff like this:

Intellisense with private and protected members

Microsoft is aware of this issue, and they haven’t said anything definite about doing anything about this problem.

When you’re writing a commercial application or something that non-developers are going to use, you don’t want this kind of cryptic stuff in the list. I don’t want to expose all of the private members of my classes to the user, just like how you don’t expose private members of a class in a public API.

One way to filter the list is to create an interface and pass the interface type in as the first parameter in the RuleSetDialog constructor. This way you won’t have all of the private and protected members of the class in the Intellisense because an interface only exposes public methods. So now you’re constructor looks like this:

// Create a RuleSet that works with Orders (just another .net Object)
RuleSetDialog ruleSetDialog = new RuleSetDialog(typeof(IOrder), null, null);

This is a decent solution, but it still has problems:

  • You have to create the interface.
  • System.Object members like Finalize(), GetHashCode(), and Equals() are still exposed.

Like I said before, in my commercial application, I don’t want users to have to see all of this extra stuff. I only want to show them the things that I want to show them.

Well, thanks to Reflector, I was able to come up with a way to let you filter the list. In my example, I can filter out all of the protected and private members, filter out static types, only display members decorated with an attribute, or completely override the list to only display strings that I’ve added. So now you can easily get something that looks more like this:

Filtered Intellisense

Much better!

Now I must warn you. This solution is making extensive use of reflection to get at private and internal methods and events that Microsoft didn’t feel like exposing to us. So I felt a little dirty while I was writing it, but it gets the job done!

Here is the code. Please leave a comment if you find anything wrong with it.

Here are some other good posts about the WF Rules Engine:

Execute Windows Workflow Rules without Workflow
Introduction to the Windows Workflow Foundation Rules Engine
External Ruleset Demo

Enjoy!