Property grid extensibility

You can customize the property grid that's displayed when a given activity is selected within the designer, creating a rich editing experience. The PropertyGridExtensibility sample shows how this can be done.

Demonstrates

Workflow designer property grid extensibility.

Discussion

To extend the property grid, a developer has options to customize the inline appearance of a property grid editor or provide a dialog that appears for a more advanced editing surface. There are two different editors demonstrated in this sample; an inline editor and a dialog editor.

Inline editor

The inline editor sample demonstrates the following:

  • Creates a type that derives from PropertyValueEditor.

  • In the constructor, the InlineEditorTemplate value is set with a Windows Presentation Foundation (WPF) data template. This can be bound to a XAML template, but in this sample, code is used to initialize data binding.

  • The data template has a data context of the PropertyValue of the item rendered in the property grid. Note in the following code (from CustomInlineEditor.cs) that this context then binds to the Value property.

    FrameworkElementFactory stack = new FrameworkElementFactory(typeof(StackPanel));
    FrameworkElementFactory slider = new FrameworkElementFactory(typeof(Slider));
    Binding sliderBinding = new Binding("Value");
    sliderBinding.Mode = BindingMode.TwoWay;
    slider.SetValue(Slider.MinimumProperty, 0.0);
    slider.SetValue(Slider.MaximumProperty, 100.0);
    slider.SetValue(Slider.ValueProperty, sliderBinding);
    stack.AppendChild(slider);
    
  • Because the activity and the designer are in the same assembly, registration of the activity designer attributes are accomplished in the static constructor of the activity itself, as shown in the following example from SimpleCodeActivity.cs.

    static SimpleCodeActivity()
    {
        AttributeTableBuilder builder = new AttributeTableBuilder();
        builder.AddCustomAttributes(typeof(SimpleCodeActivity), "RepeatCount", new EditorAttribute(typeof(CustomInlineEditor), typeof(PropertyValueEditor)));
        builder.AddCustomAttributes(typeof(SimpleCodeActivity), "FileName", new EditorAttribute(typeof(FilePickerEditor), typeof(DialogPropertyValueEditor)));
        MetadataStore.AddAttributeTable(builder.CreateTable());
    }
    

Dialog editor

The dialog editor sample demonstrates the following:

  1. Creates a type that derives from DialogPropertyValueEditor.

  2. Sets the InlineEditorTemplate value in the constructor with a WPF data template. This can be created in XAML, but in this sample, this is created in code.

  3. The data template has a data context of the PropertyValue of the item rendered in the property grid. In the following code, this then binds to the Value property. It is critical to also include an EditModeSwitchButton to provide the button that raises the dialog in FilePickerEditor.cs.

    this.InlineEditorTemplate = new DataTemplate();
    
    FrameworkElementFactory stack = new FrameworkElementFactory(typeof(StackPanel));
    stack.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
    FrameworkElementFactory label = new FrameworkElementFactory(typeof(Label));
    Binding labelBinding = new Binding("Value");
    label.SetValue(Label.ContentProperty, labelBinding);
    label.SetValue(Label.MaxWidthProperty, 90.0);
    
    stack.AppendChild(label);
    
    FrameworkElementFactory editModeSwitch = new FrameworkElementFactory(typeof(EditModeSwitchButton));
    
    editModeSwitch.SetValue(EditModeSwitchButton.TargetEditModeProperty, PropertyContainerEditMode.Dialog);
    
    stack.AppendChild(editModeSwitch);
    
    this.InlineEditorTemplate.VisualTree = stack;
    
  4. Overrides the ShowDialog method in the designer type to handle the display of the dialog. In this sample, a basic FileDialog is shown.

    public override void ShowDialog(PropertyValue propertyValue, IInputElement commandSource)
    {
        Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
        if (ofd.ShowDialog() == true)
        {
            propertyValue.Value = ofd.FileName;
        }
    }
    
  5. Because the activity and the designer are in the same assembly, registration of the activity designer attributes are accomplished in the static constructor of the activity itself, as shown in the following example from SimpleCodeActivity.cs.

    static SimpleCodeActivity()
    {
        AttributeTableBuilder builder = new AttributeTableBuilder();
        builder.AddCustomAttributes(typeof(SimpleCodeActivity), "RepeatCount", new EditorAttribute(typeof(CustomInlineEditor), typeof(PropertyValueEditor)));
        builder.AddCustomAttributes(typeof(SimpleCodeActivity), "FileName", new EditorAttribute(typeof(FilePickerEditor), typeof(DialogPropertyValueEditor)));
        MetadataStore.AddAttributeTable(builder.CreateTable());
    }
    

To set up, build, and run the sample

  1. Build the solution, and then open Workflow1.xaml.

  2. Drag a SimpleCodeActivity from the toolbox onto the designer canvas.

  3. Click the SimpleCodeActivity and then open the property grid where there is a slider control and a file picking control.