Tag Archives: Security Demands

How to Create a Custom Editor for a Domain Model Element Property

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:

 

   1: 
   2: using System;
   3: using System.Collections.Generic;
   4: using System.Text;
   5:
   6: // Need to add a reference to System.Drawing DLL.
   7: using System.Drawing.Design;
   8: using System.Security.Permissions;
   9: using Microsoft.VisualStudio.Modeling;
  10: using Microsoft.VisualStudio.Modeling.Design;
  11:
  12: namespace XXX.UIProcessDesigner.UIEditors
  13: {
  14:
  15:     // FxCop rule: must have same security demands as parent class
  16:     [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust"),
  17:         PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
  18:     public class FormPromptUITypeEditor : System.Drawing.Design.UITypeEditor
  19:     {
  20:
  21:         /// <summary>
  22:         /// Overridden to specify that our editor is a modal form
  23:         /// </summary>
  24:         /// <param name="context"></param>
  25:         /// <returns></returns>
  26:         public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
  27:         {
  28:             return UITypeEditorEditStyle.Modal;
  29:         }
  30:
  31:
  32:         /// <summary>
  33:         /// Called by VS whenever the user clicks on the ellipsis in the 
  34:         /// properties window for a property to which this editor is linked.
  35:         /// </summary>
  36:         /// <param name="context"></param>
  37:         /// <param name="provider"></param>
  38:         /// <param name="value"></param>
  39:         /// <returns></returns>
  40:         public override object EditValue(
  41:             System.ComponentModel.ITypeDescriptorContext context,
  42:             IServiceProvider provider,
  43:             object value)
  44:         {
  45:
  46:             // Get a reference to the underlying property element
  47:             ElementPropertyDescriptor descriptor = context.PropertyDescriptor as ElementPropertyDescriptor;
  48:             ModelElement underlyingModelElent = descriptor.ModelElement;
  49:
  50:             // context.Instance also returns a model element, but this will either
  51:             // be the shape representing the underlying element (if you selected
  52:             // the element via the design surface), or the underlying element 
  53:             // itself (if you selected the element via the model explorer)
  54:             ModelElement element = context.Instance as ModelElement;
  55:
  56:             FormPromptUITypeEditorForm theForm = new FormPromptUITypeEditorForm();
  57:
  58:             theForm.Value = (string)value;
  59:
  60:             if (theForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
  61:             {
  62:                 value = theForm.Value;
  63:             }
  64:
  65:             return value;
  66:         }
  67:
  68:     }
  69:
  70: }
  71:
  72: 

 

2. Create a Windows Form dialog that will be displayed when the editor is invoked, such as the one below:

 

SampleWindowsForm

 

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.

 

SamplePropertiesForm

 

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.