(Very) simple WPF PropertyGrid in 20 minutes

13.May.08 – 16:29

Everyone that has ever worked with the WinForms PropertyGrid will miss it in WPF.

Therefore i wrote this tiny turorial on how to write your own very basic PropertyGrid on top of WPF.

Disclaimer:This is not a ready to use fully-featured control for production use. It just shows in a very simple manner how to get Properties and their values from objects via reflection and show them using WPF and databinding.
It is by far not a replacement of commercial WPF PropertyGrids (e.g. MindScape WPF PropertyGrid), more a fast solution for minimal requirements.

This simple PropertyGrid will not contain special Editors for non trivial data types. For now we are confident with a simple TextBox for demonstration purposes.
We will see that because of the automatic conversion features of wpf , we’re easily able to edit not only strings, but also int’s, double’s, Color’s, SolidColorBrush’es and so on in a simple TextBox.

Our WPF PropertyGrid clone should look like this:


  • TextBox for searching (filtering) properties. This is especially usefule if your classes contain lots of properties
  • a panel (here StackPanel) that contains all the PropertyName/PropertyValue pairs (wrapped up in a Scrollviewer)
  • TextBox for descriptions that we obtain from the System.ComponentModel.DescriptionAttribute-Attribute of the property selected

First we want to realize the simple structure shown above in XAML to get started.
After short time this may look like this:



Next we reate a UserControl as a Wrapper for our Properties. This just contains a TextBlock (for the property name) and a TextBox (for the property value) bound to properties that we defined in our code-behind file.

Now where the actual work is done:

foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value)){

	if (!property.IsBrowsable) continue; //not browsable. ignore

        PropertyItem currentProperty = new PropertyItem();
        currentProperty.PropertyName = property.Name;
        Binding b = new Binding(property.Name);
        b.Source = selectedObject;
	//OneWay Binding if readonly, twoway else
        b.Mode = property.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay;

        currentProperty.SetBinding(PropertyItem.PropertyValueProperty, b);
	currentProperty.OnActive += new EventHandler(currentProperty_OnActive);

        foreach (Attribute attribute in property.Attributes)	//check attributes
        {
         if (attribute.GetType() == typeof(DescriptionAttribute)){ //description to show in description textbox
            currentProperty.PropertyDescription = ((DescriptionAttribute)attribute).Description;
         }
         if (attribute.GetType() == typeof(CategoryAttribute)) {  //categories known from winforms pg.not implemented
             currentProperty.PropertyCategory = ((CategoryAttribute)attribute).Category;
         }
        }      

	PropertyPanel.Children.Add(currentProperty); //add PropertyItem to panel
}

That’s it! Well, what happened here?
We iterate over all properties the object, we set as SelectedObject, contains. If it’s marked as non-Browsable (System.ComponentModel.BrowsableAttribute), we’ll just skip it, otherwise we create a PropertyItem, set its name and create a Binding to connect the PropertyItem’s PropertyValue-property with the value of the actual property from SelectedObject.

And before we add the PropertyItem to our Panel, we check the attributes of the source property (e.g. to get the description from the DescriptionAttribute or the get the corresponding category from the CategoryAttribute, which is not processed for simplicity in this demo).

When we now try to set some object to our PropertyGrid’s SelectedObject-property (in this case a dummy class containing several properties, including string, int, double, color, SolidColorBrush and a property marked with Browsable(false)) it should look like this:

In the screeshot above you can see different data types in their string representation. You don’t have to care about converting them back manually to their actual type as WPF’s Binding-Helpers do everything for you (and will throw Exceptions if the string-format for your type is wrong).

At last we add some Style to our PropertyGrid and received something like this:



To use the (very) simple PropertyGrid, just add a reference to PropertyGridDemo.dll, add the namespace in XAML to your window like this :


…and add the PropertyGrid itself somewhere in your XAML code


  

at last you have to provide some object (that contains some properties) to the SelectedObject property:

//...
this.propertyGrid.SelectedObject = myCustomObject;
//...

You can download the whole solution here: PropertyGridDemo.zip

  1. 2 Responses to “(Very) simple WPF PropertyGrid in 20 minutes”

  2. There’s another tutorial on creating a simple property grid control that hope will be of interest to the community:

    “Your own PropertyGrid in a couple of hours”
    http://dvuyka.spaces.live.com/blog/cns!305B02907E9BE19A!448.entry

    By Denis Vuyka on Jun 5, 2008

  3. And now: what you use as propertygrid for WPF apps?

    By alex on Sep 9, 2009

Post a Comment

Comment spam protected by SpamBam