collection properties

Grids for WPF Forum

Posted 12 years ago by Mary Fontana - Rudolph Technologies
Avatar
I am using PropertyGrid with an object that has collection properties.
I would like to instead of having the + Add new button. To have a custom button that
will popup another dialog window that will manage adding/removing items in the collection.

Is this possible?

Comments (4)

Posted 12 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Mary,

Yes, it is possible to add your own custom buttons. You'd need to redefine the Style with the key PropertyGridCommonDictionary.ValueCellContainerStyleKey. Our default Style for this includes the add/remove buttons. You could take our default version (from our default Styles) and then remove the add button and define your own that uses a custom command.


Actipro Software Support

Posted 12 years ago by Mary Fontana - Rudolph Technologies
Avatar
Thanks.
I saw that PropertyGridCommonDictionary.ValueCellContainerStyleKey style addChildButton has
Command="{x:Static propgrid:PropertyGrid.AddPropertyChildCommand}".
Instead of redefining the Style, I just added my own command binding:

<propgrid:PropertyGrid.CommandBindings>

                <CommandBinding Command="{x:Static propgrid:PropertyGrid.AddPropertyChildCommand}" Executed="AddPropertyChild_Executed"  />

            </propgrid:PropertyGrid.CommandBindings>

I have another question relating to collection properties.
I have a collecion of objects where each object has a Name and Value properties.
Instead of the name cell field containing [0] [1] etc.
How can I define the name cell to be the object's Name property ?

I saw in common.xaml that there is a PropertyGridCommonDictionary.NameCellContainerStyleKey
but I don't see the definition for this.
Posted 12 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Mary,

The NameCellContainerStyleKey is actually defined in two places (Common.NameCell.AeroNormalColor.xaml and Common.NameCell.Generic.xaml), since it has two looks. We are consolidating these for the next release, but the overall structure will be the same.

As for you original question, there are several places you could do this. The most straight forward approach would be to build a custom TypeDescriptor that injects that information. Basically, you'd need to:

1. Create a class that derives from ExpandableCollectionConverter (i.e. MyExpandableCollectionConverter)
This is the TypeDescriptor and is responsible for translating the object (in this case a list) to a list of PropertyDescriptors, which are presented by the PropertyGrid.

2. Create a nested class that derives from ExpandableCollectionConverter.ListPropertyDescriptor (i.e. MyExpandableCollectionConverter.MyListPropertyDescriptor)
This wraps each "property" (in this case an item in the list) and provides metadata about the property (i.e. display name, type, value, etc).

3. Override the DisplayName property of MyExpandableCollectionConverter.MyListPropertyDescriptor and return your object's Name property.
Using the ListPropertyDescriptor's List and Index property you can get the associated object, or just call GetValue(null).

4. Create a constructor on MyListPropertyDescriptor that matches the ListPropertyDescriptor's only constructor. Such as:
public MyListPropertyDescriptor(IList list, int index, Type itemType, Attribute[] attributes, bool isReadOnly)
    : base(list, index, itemType, attributes, isReadOnly) {
    // No-op
}
5. Override the ExpandableCollectionConverter.CreateListPropertyDescriptor method and return a new instance of your MyListPropertyDescriptor and do not call the base implementation.

You can now decorate properties using [TypeDescriptor(typeof(MyExpandableCollectionConverter))] if that property is a list of the type that has the Name property. You could also create a custom list class and decorate that once and it will be picked up for all properties that use it. Such as:
[TypeDescriptor(typeof(MyExpandableCollectionConverter))]
public class MyObjectList : List<MyObject> {
}


Actipro Software Support

Posted 12 years ago by Mary Fontana - Rudolph Technologies
Avatar
That worked. Thank you!

I have another question on removing a property child.

I am adding a command binding to my property grid for
PropertyGrid.RemovePropertyChildCommand
so that I can add a MessageBox Dialog to confirm that the item should be removed.

<CommandBinding
Command="{x:Static propgrid:PropertyGrid.RemovePropertyChildCommand}"
Executed="RemovePropertyChild_Executed" />


In my method:
private void RemoveChildProperty_Executed(object sender, ExecutedRoutedEventArgs e)

I can see the item I want to remove in e.Parameter.Value;
But I don't know how to remove the item from the collection holding on to it.

I only see passed to this method the item to remove.
How do I get to the collection holding on to this object?

[Modified at 10/11/2011 10:33 PM]

[Modified at 10/11/2011 10:34 PM]
The latest build of this product (v24.1.1) was released 2 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.