How to: Intercept a Click on an Icon Decorator

The following procedure demonstrates how to intercept a click on an icon decorator by using the "User Interface Process Sample" as an example. For more information, see User Interface Process Sample (Domain-Specific Language Tools).

The objective is to make the icons on the wizard pages in the User Interface Process sample respond when a user double-clicks them. The decorators are carried on an instance of ImageField class, which has an OnDoubleClick method. You can intercept the clicks if you write an ImageField subclass and name it ClickableImageField. The fields are set up in the InitializeShapeFields method. Therefore, you must change that method to create a ClickableImageField subclass. The InitializeShapeFields method is in the generated code of the WizardPageShape class. You can override the WizardPageShape class if you set its Generates Double Derived property as described in the following procedure.

To intercept a click on an icon decorator

  1. Under the Dsl project, open the Shapes.cs file, and click WizardPageShape.

  2. In the Properties window, set the Generates Double Derived property to true.

  3. Click Transform All Templates in the Solution Explorer toolbar.

    This step removes all the code (except constructors) into a separate base class.

  4. Right-click the Dsl project, and click Properties.

  5. On the Resources tab, click This project does not contain a default resources file. Click here to create one.

  6. In Solution Explorer, open the Resources folder.

  7. Drag the StartDecoratorIcon.bmp and EndDecoratorIcon.bmp image files from Solution Explorer into the resources window.

  8. Open the File menu, and click the option to save the project properties.

  9. In the Dsl project, open the Properties folder, and verify that the file Resources.resx exists and has the file Resources.Designer.cs under it.

  10. In Solution Explorer, right-click the Dsl project, point to Add, and click New Folder.

  11. Name the folder Custom.

  12. Right-click the Custom folder, point to Add, and click New Item.

  13. In the Add New Item dialog box, in the Templates list, click Code File.

  14. In the Name box, type ClickIcons.cs, and click Add.

  15. Add the following code to the ClickIcons.cs file:

    using Microsoft.VisualStudio.Modeling;
    using Microsoft.VisualStudio.Modeling.Design;
    using Microsoft.VisualStudio.Modeling.Diagrams;
    using System.Collections.Generic;
    
    namespace Fabrikam.DSL.WizardUIP {
    
  16. Create the ClickableImageField : ImageField subclass by adding the following code:

    internal class ClickableImageField : ImageField
    {
        public override void OnDoubleClick(DiagramPointEventArgs e)
        {
            base.OnDoubleClick(e);
            System.Windows.Forms.MessageBox.Show("icon double clicked!");
        }
    
        public ClickableImageField(string fieldName)
            : base(fieldName)
        { }
    }
    
  17. Override the WizardPageShape.InitializeShapeFields method by adding the following code.

    public partial class WizardPageShape
    {
        protected override void InitializeShapeFields(IList<ShapeField> shapeFields)
      {
        base.InitializeShapeFields(shapeFields);
        // You can see the above method in WizardPageShapeBase in the generated Shapes.cs
        // It has already added fields for the Icons to intercept clicks on.
        // So you will have to retrieve them and replace with your own.
        List<ShapeField> unwanted = new List<ShapeField>();
        foreach (ShapeField field in shapeFields)
        {
          if (field.Name == "StartIcon" || field.Name == "EndIcon")
            unwanted.Add(field);
        }
        foreach (ShapeField field in unwanted)
        {
          shapeFields.Remove(field);
        }
        // Now replicate the generated code, but with your own image constructor
        ImageField field2 = new ClickableImageField("StartIcon");
        field2.DefaultImage = ImageHelper.GetImage(WizardUIP.Properties.Resources.StartDecoratorIcon);
        shapeFields.Add(field2);
        ImageField field3 = new ClickableImageField("EndIcon");
        field3.DefaultImage = ImageHelper.GetImage(WizardUIP.Properties.Resources.EndDecoratorIcon);
        shapeFields.Add(field3);
    }
    }
    
  18. Build and run the ClickIcons.cs file, and double-click the start or end icon on the wizard page shape.

    Although InitializeShapeFields is an instance method, it is called only once for each class. Therefore, only one instance of ClickableImageField exists for each field in each class, not one instance for each shape in the diagram. When the user double-clicks an instance, you must identify which instance has been hit, as the following code demonstrates:

    public override void OnDoubleClick(DiagramPointEventArgs e)
    {
      base.OnDoubleClick(e);
      // Work out which instance was hit.
      WizardPageShape shapeHit = e.HitDiagramItem.Shape as WizardPageShape;
      if (shapeHit != null) shapeHit.IconClicked();
    }
    

See Also

Reference

Properties of Decorators

Other Resources

Responding to Changes in the Model