Binding to sub-properties in property grid

Grids for WPF Forum

Posted 9 years ago by Mick
Avatar
I'm trying to get a property in the property grid to display the value of its sub property as its header.

My structure looks something like this

public class A
{
   public int B { get; set; }
   public string C { get; set; }
   public CustomProperty D { get; set; }
}

public class CustomProperty
{
   public int E { get; set; }
   public string { get; set; }
}
---

"A" is the class that I want to use for the property editor. It exposes property D, which is a property with sub properties. I want to use "E" (i.e. A->D->E) as the header for my expandable property editor.

I have implemented everything to make it work the way I want in a PropertyEditor DataTemplate using this binding:

"{Binding Value.E, RelativeSource={RelativeSource AncestorType={x:Type propgrid:IPropertyDataAccessor}}, Mode=TwoWay}"

Everything works as expected, but when I select multiple items for the property grid, this binding is ignored and the header displayed for my "D" class in the property grid is blank.

I have recreated the issue I am experiencing in a small sample project if clarification is needed.

Is there something I'm overlooking?

Thank you,
Mick

Comments (3)

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Mick,

This is the default behavior. The problem is what should Value.E bind to when you have several objects selected? The E value on each of each of the selected objects could be different.

The PropertyGrid will return null for Value when the associated values (i.e. the value from each property on all the selected objects ) are not equal. If they are equal, then it will return the first instance of the value (which should technically be equal to the remaining items).

You can see this in action in the Multiple Objects QuickStart in our Sample Browser. If you select the First and Second objects, you will see that the Name property is now empty. This is because the names are different. If they are updated to be the same value, then it will display in the PropertyGrid.

This behavior is identical to how the WinForms PropertyGrid handles multiple objects, but can be customized if needed. Are just trying to have the property D display/update the value for it's associated E property?


Actipro Software Support

Posted 9 years ago by Mick
Avatar
Thank you,

I understand that properties with different values cannot be merged, but that's not what I'm after. I am trying to replace the "header" of the property tagged with the ExpandableObject TypeConverter with the value from one of the sub-properties.

I am interested in binding the value (D.E) to the header of the expander (next to the control as opposed to within the collapsible region). I know it's possible to do for one item, but not sure it's possible to do for multiple items.

Here is a link to a screenshot from my sample project, because I know this is confusing to read:
http://i.imgur.com/TmYy8.png

You'll see that when one item is selected, my re-templating of the header "floats" the value of "Main Property" to the top (next to the +/- sign). However, when more than one object is selected, this binding for the header is lost (while the sub-item binding remains - both fields are equal, so the PropertyGrid automatically merges them).

Thank you,
Mick
Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Mick,

There really isn't a good way allow a sub-property to be modified by it's parent property like that right now (atleast for merged properties). You'd need to access the E property values using the associated MergedPropertyDataAccessor. This is located in the Items collection of the PropertyGridDataAccessorItem of the D value, but there's no easy way to "find" it in the Items using just XAML.

We've put down a TODO item to look into adding this ability in the future.

If it just needs to be read-only, then you have a couple of options:

1. If you override Equals on your CustomProperty, then you can have it return the results of the comparision of the E property. This will allow the PropertyGrid to merge the instances of CustomProperty.

But, this might not fit into your object model. This would effectively merge the D property, if the E property will be merged.

This won't work if you try to update E from the property editor for D. Since it's only going to be bound to the E of the first selected object, then only that object would be updated with any changes. If it just needs to be read-only, then this would work.

2. You can access the first instance using the Values property. Something like this:

{Binding Values[0].E, RelativeSource={RelativeSource AncestorType={x:Type propgrid:IPropertyDataAccessor}}, Mode=TwoWay}

But again, this won't work if the property editor for D should update the value of E. If it's read-only, then this is probably the best approach.


Actipro Software Support

The latest build of this product (v2019.1 build 0681) was released 10 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.