by Jim Lavin
Sometimes when defining a property for a domain model element you may need to use a complex type that has more than one property or can’t easily be displayed using a single text field or drop down in the property editor. A good example might be a class that holds a list of strings for a GUI interface or a Rich Text editor for a custom text field required by your framework.
To resolve this you can create a custom editor and hook it into your domain model that will provide a proper user interface to specify information for your property.
There are three steps you need to take in order to wire your domain property to display a custom editor:
1. Create a class derived from System.Drawing.Design.UITypeEditor that will launch the custom dialog box as below:
using System;
using System.Collections.Generic;
using System.Text;
// Need to add a reference to System.Drawing DLL.
using System.Drawing.Design;
using System.Security.Permissions;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Design;
namespace XXX.UIProcessDesigner.UIEditors
{
// FxCop rule: must have same security demands as parent class
[PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust"),
PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
public class FormPromptUITypeEditor :
System.Drawing.Design.UITypeEditor
{
/// <summary>
/// Overridden to specify that our editor is a modal form
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override UITypeEditorEditStyle
GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
/// <summary>
/// Called by VS whenever the user clicks on the ellipsis in the
/// properties window for a property to which this editor is linked.
/// </summary>
/// <param name="context"></param>
/// <param name="provider"></param>
/// <param name="value"></param>
/// <returns></returns>
public override object EditValue(
System.ComponentModel.ITypeDescriptorContext context,
IServiceProvider provider,
object value)
{
// Get a reference to the underlying property element
ElementPropertyDescriptor descriptor = context.PropertyDescriptor as
ElementPropertyDescriptor;
ModelElement underlyingModelElent = descriptor.ModelElement;
// context.Instance also returns a model element, but this will either
// be the shape representing the underlying element (if you selected
// the element via the design surface), or the underlying element
// itself (if you selected the element via the model explorer)
ModelElement element = context.Instance as ModelElement;
FormPromptUITypeEditorForm theForm = new FormPromptUITypeEditorForm();
theForm.Value = (string)value;
if (theForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
value = theForm.Value;
}
return value;
}
}
}
2. Create a Windows Form dialog that will be displayed when the editor is invoked, such as the one below:

3. Set the Custom Attributes for the Domain Property to reference the UITypeEditor class you have created.

The text is as follows:
[System.ComponentModel.Editor(typeof(XXX.UIProcessDesigner.UIEditors.FormActionTypeUITypeEditor),typeof(System.Drawing.Design.UITypeEditor))]
The bold faced text is the full namespace of your class that derives from UITypeEditor.
I normally store all code that I add to a DSL Designer in various folders such as; CustomCode, UIEditors, Validators, etc. That way it is easy to find when I am trying to reference it.
Also, you can debug the UITypeEditor and Dialog by setting breakpoints in the code before you start debugging.
There hasent been any pingbacks made to wordpress so far on this post.