Editing custom types in the WPF Property Grid

The WPF Property Grid knows how to edit a lot of common types — strings, numbers, dates, colours, etc. — but what if your users need to edit a property which has a type that the WPF Property Grid doesn’t know about? For example, a person’s phone number might be represented as a PhoneNumber object rather than a string.

By default, the WPF Property Grid handles unknown types by allowing users to drill into the type, in the manner of a tree view, until they get down to something that the grid does know how to handle. This is a reasonable fallback user experience, and it means that you can work with pretty much any kind of object right out of the box, even a fairly complicated one. But it would be nice to give users a way of seeing and editing the value in place, and of supplying them with type-specific tools. For example, the phone number editor could provide the option to invoke a yellow pages Web site or a directory enquiries Web service.

The WPF Property Grid supports this through a mechanism called type editors. A type editor is simply a WPF DataTemplate. Once you tell the WPF Property Grid to associate this DataTemplate with a particular type, the grid will take care of instantiating and binding the template whenever a property of that type comes up. The bindings defined in the template will take care of propagating the changes back to the data source.

Let’s see how this works. First, let’s define our PhoneNumber class as follows:

public class PhoneNumber : INotifyPropertyChanged
  public string CountryCode { ... }
  public string RegionCode { ... }
  public string Number { ... }
  /* ... INotifyPropertyChanged support ... */

Then if we ask the WPF Property Grid to display a Person with two PhoneNumber properties, we get the following:

Screenshot of editing a phone number without a type editor

As you can see, the grid gives the user a way to edit the phone numbers, but it’s a bit utilitarian. A user might reasonably expect to be able to view and edit a phone number in place rather than having to crack it open and edit each piece individually.

We can represent the way our users would like to work with phone numbers as a DataTemplate (omitting some cosmetic details for clarity):

<DataTemplate x:Key="PhoneNumberEditor">
  <StackPanel Orientation="Horizontal">
    <TextBlock Text="+" />
    <TextBox Text="{Binding CountryCode, UpdateSourceTrigger=PropertyChanged}" />
    <TextBlock Text=" (" />
    <TextBox Text="{Binding RegionCode, UpdateSourceTrigger=PropertyChanged}" />
    <TextBlock Text=") " />
    <TextBox Text="{Binding Number, UpdateSourceTrigger=PropertyChanged}" />

Having done this, we now need to tell the WPF Property Grid to use this template for editing PhoneNumber-type properties. We can do this by adding a TypeEditor declaration to the grid’s Editors collection:

<ms:PropertyGrid SelectedObject="{Binding}">
    <ms:TypeEditor EditedType="t:PhoneNumber" EditorTemplate="{StaticResource PhoneNumberEditor}" />

Now when we run up the grid, it looks like this:

Screenshot of editing a phone number with a type editor

That’s a lot more visual. Let’s go a bit further and link to a directory enquiries Web site:

<DataTemplate x:Key="PhoneNumberEditor">
    <TextBlock DockPanel.Dock="Right" VerticalAlignment="Center">
      <Hyperlink NavigateUri="http://..." Click="Hyperlink_Click">Search</Hyperlink>
    <StackPanel Orientation="Horizontal">
      ... as before ...

Here’s the result:

Screenshot of editing a phone number with a type editor including a Web link

Of course, type editors aren’t limited to textual elements. A type editor is just a DataTemplate, so it can use any kind of WPF framework element: controls, graphics, colours, animation, even 3D. But perhaps fortunately, I can’t think of an animated 3D user interface for entering a phone number, so you’re spared that particular demo. For now.

5 Responses to “Editing custom types in the WPF Property Grid”

  • What we would be the approach to dealing with this in a non-markup manor i.e. I have add-ins loaded at run time, which have their own strongly typed configuration classes and custom types – is there an equivalent to say the way WinForms does it with UITypeEditor, something that could be done with code attributes and embedded resources?

    Looking great by the way :) very impressed.

  • There’s nothing built into the grid that inspects a type or property for an editor declaration; at the moment, it is left entirely up to the hosting application to figure out what editors to hook up. But the application can certainly add editors at runtime from code. This would go something like:

    TypeEditor editor = new TypeEditor();
    editor.EditedType = myType;
    editor.EditorTemplate = GetEditorTemplate(myType);

    Here I am assuming that the application has defined a GetEditorTemplate method which returns a suitable DataTemplate. This might be implemented by inspecting an attribute on the custom type a la EditorAttribute, or by a naming convention, a configuration file mapping types to resources, or whatever. Similarly, it might load the DataTemplate from embedded resources in the add-in DLL, from a resource in the hosting application, from a satellite DLL, or wherever.

    Note that this does depend on the application having some way at runtime of getting the relevant types so it can hook them up. If you know in advance which properties are going to have runtime-determined types, this is easy enough: just do a GetType() on the relevant values (and then go off and inspect their attributes or whatever). But if the edited object has a complex, deeply nested structure, and/or you don’t know at compile time which properties may have runtime-determined types, it could become tedious. This use case wasn’t on our list for v1, and offhand I don’t think v1 provides any workaround easier than walking the graph yourself, but it sounds like a good candidate for the wishlist. Let me know if this is an immediate issue for you.

  • Not an immediate issue for me – was just wondering how that would be accomodated – being able to add the editors at run time would be more then enough to let me roll my own specific solution I would think :)

  • […] has posted a a blog article about using custom editors with the Mindscape WPF Property Grid – I’d urge anyone interested in it to download the trial and then check out his article. Pass […]

  • […] wrote previously about editing custom types in the WPF Property Grid—how to extend the grid to provide a good editing experience for, […]

  • Leave a Reply


Join our mailer

You should join our newsletter! Sent monthly:

Back to Top