This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
Howdy, I'm experimenting with the trial and have hooked it into an app I'm working on. The property grid seems ridiculously slow when I assign it an object, but I think that is because the grid is displaying every possible property. My object descends from DrawingVisual, so there are a lot to add. I want to be able to only display properties of my choosing, not every single public property for the object or any of the classes it inherits from. I searched teh forums and found this thread: http://www.mindscape.co.nz/forums/Thread.aspx?PostID=3086 Which has:
Depending on the kind of condition you want, you may also find it useful to create a custom GroupDescription so that the group "name" can carry richer information than just the display text. Could I get an example of how to do that? Say I have a list of predefined categories, how would I do the changes suggested above so that it only displayed these categories? Also, if I filter it like this will it speed up the grid significantly? Sorry if it's meant to be obvious.. I'm new to WPF and the documentation for the grid seems a little sparse. There's a lot of assumed knowledge...
|
|
|
The thread you cite refers more to hiding groups (identified with something like CategoryAttribute) than to filtering out properties. In particular the presumption there is that all properties and categories are "available" but there is a requirement for the user to be able to hide or show categories at runtime. From your description of your scenario it sounds like you are more interested in just excluding unwanted properties altogether, as though they just didn't exist. Is that correct? Normally you would do this by applying BrowsableAttribute(false) to properties you want to hide. However since you are descending from a base class which is not under your control this is not really an option for you. You will therefore need to do one of the following: * Implement ICustomTypeDescriptor on your object, and override GetProperties to return only the properties that you want displayed. This is a fairly heavyweight solution for your scenario, though it provides maximum flexibility in the more general case. * Apply TypeConverterAttribute to your class. In your TypeConverter implementation, override GetPropertiesSupported to return true, and override GetProperties to return only the properties you want: public class MyTypeConverter : TypeConverter This should speed up the grid depending on how many properties remain after filtering. (We believe the main performance cost is WPF performing layout and measurement on the grid contents, so the fewer items the faster.) If performance remains problematic then let us know and we will see if we can improve matters. |
|
|
Oops, I forgot to say: Property filtering via TypeConverter is only available in the nightly build. You can download the trial version from http://www.mindscape.co.nz/products/wpfpropertygrid/nightlybuilds.aspx if you're not already using a recent nightly. |
|
|
"Normally you would do this by applying BrowsableAttribute(false) to properties you want to hide. However since you are descending from a base class which is not under your control this is not really an option for you."
Yeah... More what I'd be looking for is to by default display no properties, unless It belongs to a specific list of categories that I've specified. If I follow the first option, would it be something like: private PropertyDescriptorCollection GetObjectProperties() ? But would that then muddle up sub properties? Or collections of properties in the objects? I like the way the grid automatically handles those.
|
|
|
Oh and then implement all the other ICustomTypeDescriptor members... |
|
|
Looking at your suggestions again, the second option is applying a type converter... If I implement ICustomTypeDescriptor I'm going to need a type converter anyway for the interface GetConverter() member, so are there any advantages to doing it the former method over the latter? |
|
|
No, I'd go for the TypeConverter approach (see note at end though). In which case your implementation of TypeConverter.GetProperties will look something like this: public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, System.Attribute[] attributes) where ShouldShow is your filtering criterion, e.g. checking the Category. This will still work fine with subproperties because you're not creating your own descriptors -- you're just filtering out of a few of the "base" descriptors. We do have a restriction that you can't use this with multiple selection at the moment (i.e. if you are using the SelectedObjects property rather than SelectedObject), because of the possibility of a heterogeneous selection where different classes might declare different type converters. If this is an issue for you then you would probably need to implement ICustomTypeDescriptor instead. |
|
|
Hi Ivan, I've created a type converter and implemented it with my class. The constructor for the type converter is called when an object of the class is insantiated, so I assume the hookup is working correctly. The GetProperties method of the type converter is never called though... Is there something else I have to do to hook this up properly so that the getproperties method of the type converter is called? I downloaded and reinstalled from the nightly build. |
|
|
Did you implement GetPropertiesSupported on the TypeConverter? If you did, and it's still not working, could you send me a small repro project so I can take a look please? You can attach a zip file via the Options tab, or email via the contact form (please strip out all binaries first). Thanks! |
|
|
Hello Ivan, I hadn't. Have now and it is now calling GetProperties. When get properties is called the base.getproperties(context, value, attribute) returns null though. So when it tries to filter the properties it can't, then it returns null for the properties. I noticed the context passed when the function is called is null, should it be? Are there any other functions I need to implement at a minimum for this to work? So far I only have GetProperties and GetPropertiesSupported.
Thanks |
|
|
Ah, try deriving from ExpandableObjectConverter rather than from TypeConverter. Sorry, I was working from code supplied by another customer and didn't realise that detail was significant -- apologies! |
|
|
Thanks Ivan, that did it. |
|
|
I've come across another related issue... Some of my objects have pen members (and other WPF classes). How will I filter these so they don't display every property imagineable? The show in the grid as system.windows.media.pen, but are then expandable to all the standard properties, plus tooltips, context menus, typographies, typographies etc. Is there a way to restrict the properties that WPF classes display? |
|
|
Yes, but it is a little hairy. Obviously we cannot implement ICustomTypeDescriptor or place TypeConverterAttribute on the existing WPF Pen class, so what we need to do instead is somehow register our own type descriptor for the Pen class instead. To do this, we must create a class that derives from TypeDescriptionProvider, and override its GetTypeDescriptor method. GetTypeDescriptor returns an ICustomTypeDescriptor, so we will also need to create a class that implements this interface. A quick way of doing the latter is to derive from CustomTypeDescriptor. So our type description provider will look something like this: public class PenTypeDescriptionProvider : TypeDescriptionProvider Now we need to associate this custom class with the Pen class. We do this using the TypeDescriptor.AddProvider method: TypeDescriptionProvider provider = new PenTypeDescriptionProvider(); Note that this is a process-wide registration and will affect all Pen instances. If different Pens need different ShouldShow logic, that probably needs to be encapsulated in your custom type descriptor. Also, be sure not to add the provider more than once. |
|
|
What about if I just create my own class that derives from the Pen class, then place the type converter attribute on that? |
|
|
Nevermind, pen class is sealed... |
|