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:
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:
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!
Great tip.
Hi
In the intellisense pop up can you show the attribute of a property instead of the class property/method name itself. This can make the ruleseteditor more business user friendly…
for example:
the attribute of the propert Amount if declared as follows where the property Amount has a user friendly description as specified in it’s attribute.
[IncludeInRuleSetDialog(RuleSetDialogTextBoxType.Condition, “Order’s Amount”)]
public int Amount
{
get { return amount; }
set { amount = value; }
}
Now the intellisense pop up should show “Order’s Amount” instead of “Amount”.
Hi Jon,
Really wonderful Article. But I would like to ask you one question.
Does Ruleset Dialog support multilingual? For Ex: Default Ruleset Dialog box comes in English but can we show it in different language say french, german etc.
It would be really great if you suggest your comments and some references to acheive multilinguality.
Thanks a lot.
@PS,
Hmm… I don’t know anything about having other languages in that dialog. All of the text in that dialog is loaded from a resource file, so it might be possible.
Hi Jon,
First of all, Thank you for the valuable reply. But how do we access or get that resource file.
Could you please provide your comments.
Thanks & Regards,
PS
Hi Jon
Grait tip, but I’m having problems implementig this
[IncludeInRuleSetDialog(RuleSetDialogTextBoxType.Condition, “Order’s Amount”)]
public int Amount
{
get { return amount; }
set { amount = value; }
}
I’m getting this Error: “The identifier >>Order’s Amount<< could not be resolved”. Would you be kind and send me PG’s mail address if you can’t help me on this one.
Thanks