Click here to Skip to main content
15,880,392 members
Articles / Programming Languages / C#
Article

Filtering properties in a PropertyGrid

Rate me:
Please Sign up or sign in to vote.
4.89/5 (30 votes)
27 Mar 20063 min read 187.4K   7.8K   78   39
This articles describes some easy ways to filter the properties displayed in a Microsoft PropertyGrid.

Sample Image - FilteredPropertyGrid.jpg

Introduction

The wonderful PropertyGrid control, provided by Microsoft, is a very useful component for editing settings or parameters in your application. You can easily let the user customize any object at runtime. When you pass an object to the SelectedObject property of a PropertyDataGrid, the PropertyDataGrid will display all the properties of your object that has the BrowsableAttribute set to true. It is both very simple and efficient.

But sometimes, you only want to expose just some properties, not all of them. Suppose you want to allow the user of your application to edit the appearance of your main form. How would you do that ? In fact, this can be done very easily. Microsoft thought about this matter and gave us a very interesting property, named BrowsableAttributes. In this article, we'll first see how this property works, and how we can use it. Next, we'll see how it is not sufficient for most cases, and introduce a new approach, using inheritance.

BrowsableAttributes: the easy but insufficient way

With the PropertyGrid.BrowsableAttributes, you can choose to display only the properties that have the attributes contained in AttributeCollection. Suppose you want to only show the properties that are grouped in the "Appearance" category.

C#
// You first create the attribute
// you want to filter with :
Attribute myfilterattribute = 
     new CategoryAttribute("Appearance");
// And you pass it to the PropertyGrid,
// via its BrowsableAttributes property :
mypropertygrid.BrowsableAttributes = new 
   AttributeCollection(new Attribute[] 
   { myfilterattribute });

You can choose several attributes, and of any sort:

C#
mypropertygrid.BrowsableAttributes = 
  new AttributeCollection(new Attribute[] {
    new CategoryAttribute("Appearance"),
    new CategoryAttribute("Layout"),
    new DisplayNameAttribute("zzzz"),
    new BrowsableAttribute(false)
  });

Note that by default, all the browsable attributes are displayed. In other words, if you let the BrowsableAttributes empty, you'll display all the properties of the SelectedObject that have the BrowsableAttribute set to true.

This is simple and works fine. But how can we just filter by properties? Unfortunately, the PropertyGrid doesn't provide a BrowsableProperties. If you want to display a selection of properties, you have to write some code ... or read the paragraph below.

Inheritance for selected properties: the FilteredPropertyGrid

Now, we'll discuss about another problem. Suppose your SelectedObject is a TextBox, and you want to display in a PropertyGrid only the "Size" property of your TextBox. As the PropertyGrid control is, it is not possible. If you read what is written in the previous section, you may imagine passing to the PropertyGrid.BrowsableAttributes property a collection of attributes like "PropertyNameAttribute". But unfortunately, such attributes don't exist.

I propose another approach: using a wrapper object that contains the object you want to display in the PropertyGrid. This wrapper will be passed to the PropertyGrid, instead of the object itself. So, the PropertyGrid will not directly display the object's properties, but the wrapper's ones. In this case, you need to subclass the PropertyGrid with a new control that overrides the SelectedObject property. That's exactly what I did, while writing the FilteredPropertyGrid control. This control is inherited from PropertyGrid and works the same way. I just added these useful properties:

  • BrowsableAttributes: overridden from PropertyGrid.
  • HiddenAttributes: all the properties that have the attributes contained in the collection are hidden.
  • BrowsableProperties: all the properties contained in the collection are displayed.
  • HiddenProperties: all the properties contained in the collection are not displayed.

Here's how you can use it. To display only the "Size" property of your TextBox, write these lines of code:

C#
// Create the TextBox.
TextBox mycontrol = new TextBox();
// Create the inherited PropertyGrid.
FilteredPropertyGrid mygrid = new FilteredPropertyGrid();
// Set the only property visible.
mygrid.BrowsableProperties = new string[] { "Size" };
// Attach the control to the PropertyGrid.
mygrid.SelectedObject = mycontrol;
// Force the PropertyGrid to redraw itself
mygrid.Refresh();

That's all! You can combine these four properties as you wish. Suppose you want to display all the categories, except the "Accessibility" and "Layout" ones. But you want the "AccessibilityRole" property, and not the "DataBinidngs" one. Write this code:

C#
mygrid.HiddenPAttributes = 
   new AttibuteCollection(new Attribute[] {
       new CategoryAttribute("Accessibility"),
       new CategoryAttribute("Layout") });
mygrid.HiddenProperties = new string[] { "DataBinidngs" };
mygrid.BrowsableProperties = 
   new string[] { "AccessibilityRole" }

Note: these properties only work with SelectedObject. There is no warranty of them working with SelectedObjects.

How does it work?

Well, I will just describe the big pants of the FilteredPropertyGrid. For more information, you can download the source code above. When one of these four properties changes, the private method FilteredPropertyGrid.RefreshProperties() is called and builds a list containing all the PropertyDescriptors of the properties to display. This collection is passed to a wrapper, and the wrapper is linked to the PropertyGrid:

C#
public class FilteredPropertyGrid : PropertyGrid
{
    private List<PropertyDescriptor> 
            m_PropertyDescriptors  = 
            new List<PropertyDescriptor>();
    private ObjectWrapper m_Wrapper = null;
    
    ( ... )

    public new object SelectedObject {
    get { return m_Wrapper != null ? 
          ((ObjectWrapper)
          base.SelectedObject).SelectedObject : 
          null; }
        set {
            if(m_Wrapper == null) {
                m_Wrapper = new ObjectWrapper(value);
                m_Wrapper.PropertyDescriptors = 
                         m_PropertyDescriptors;
                RefreshProperties();
            } else {
                // Link the wrapper to the parent PropertyGrid.
                base.SelectedObject = m_Wrapper;
            }
        }
    }
    
    ( ... )
}

The RefreshProperties() method strongly uses the TypeDescriptor class and its GetProperties() method, to get the properties of the SelectedObject and build the list.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer
France France
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionAnother Solution - ICustomTypeDescriptor Pin
JaedenRuiner24-Jul-21 14:28
JaedenRuiner24-Jul-21 14:28 
QuestionFilterPropertGrid not opening SpreadSkin editor window For Farpoint Spread object While clicking on eclipse button of Skin propert Pin Pin
vikas@19907-Sep-14 18:20
vikas@19907-Sep-14 18:20 
BugFilterPropertGrid not opening SpreadSkin editor window For Farpoint Spread object While clicking on eclipse button of Skin propert Pin
vikas@19904-Sep-14 5:13
vikas@19904-Sep-14 5:13 
QuestionGreat job! Pin
zackp19838-Dec-11 11:20
zackp19838-Dec-11 11:20 
Question5 years over. Pin
RobbKirk14-Aug-11 1:50
RobbKirk14-Aug-11 1:50 
GeneralBug / Utilisation Pin
Eric Ouellet1-Apr-11 9:49
professionalEric Ouellet1-Apr-11 9:49 
GeneralSetting only BrowsableProperties not work?! Pin
serhhio29-Apr-10 5:49
serhhio29-Apr-10 5:49 
GeneralReuse of code in commercial product Pin
2twotango9-Feb-09 4:45
2twotango9-Feb-09 4:45 
GeneralCode License Pin
eosjack16-Sep-08 15:20
eosjack16-Sep-08 15:20 
Questionhow about SelectedObjects Pin
sean 9112-May-08 15:46
sean 9112-May-08 15:46 
AnswerRe: how about SelectedObjects Pin
Jake See12-Dec-12 18:57
Jake See12-Dec-12 18:57 
GeneralRe: how about SelectedObjects Pin
Member 1008257718-Oct-13 1:28
Member 1008257718-Oct-13 1:28 
GeneralGood Reserch Pin
Manas_Patnaik10-Dec-07 23:36
Manas_Patnaik10-Dec-07 23:36 
GeneralSmall Bug fixed Pin
Protocol Builder27-Aug-07 5:31
Protocol Builder27-Aug-07 5:31 
GeneralTabbing from Item To Item Pin
theMouse13-Jul-07 9:25
theMouse13-Jul-07 9:25 
QuestionDataBindings dropdown selection only shows "None" Pin
Peter Radvolution30-Jun-07 23:00
Peter Radvolution30-Jun-07 23:00 
GeneralDo not use BrowsableAttributes?! Pin
sahami18-Jun-07 10:41
sahami18-Jun-07 10:41 
GeneralThank you Pin
ruben ruvalcaba8-May-07 13:59
ruben ruvalcaba8-May-07 13:59 
QuestionWhat about expandable properties, dynamic components? Pin
wcoenen27-Feb-07 5:47
wcoenen27-Feb-07 5:47 
AnswerRe: Need a sample implementation of the same Pin
jackie_19846-Aug-07 18:43
jackie_19846-Aug-07 18:43 
GeneralRe: Need a sample implementation of the same Pin
connectpalm29-Feb-08 2:01
connectpalm29-Feb-08 2:01 
GeneralGreat Article [modified] Pin
Todd Wilder28-Aug-06 17:38
Todd Wilder28-Aug-06 17:38 
Questiondisplay property in PropertyGrid Pin
poonam_iitr25-Jul-06 12:13
poonam_iitr25-Jul-06 12:13 
GeneralICustomTypeDescriptor Pin
visualhint2-May-06 5:24
visualhint2-May-06 5:24 
GeneralRe: ICustomTypeDescriptor Pin
philippe dykmans8-Jun-08 5:47
philippe dykmans8-Jun-08 5:47 
For as far as i can see, the method presented in this article allows to filter dynamically (i.e. at runtime). You could have different propertygrids showing the same object in different ways. I think that this is not possible with ICustomTypeDescriptor because this is a static attribute. Or am i wrong?

Grtz,
Phil

Philippe Dykmans
Software developpement
Advanced Bionics Corp.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.