Nested Categories?

Grids for WPF Forum

Posted 9 years ago by SledgeHammer01
Version: 9.2.0515
Avatar
Does the property grid support nested categories? I know I can expand complex types, but looking to have the category nested some how.

Like:

Cat #1
Cat #1a
Item
Cat #1b
Item
Cat #2

[Modified at 04/06/2010 01:17 PM]

Comments (5)

Posted 9 years ago by SledgeHammer01
Avatar
Hi, I discovered I can nest categories if I populate the grid via code:

PropertyGridCategoryItem ci = new PropertyGridCategoryItem();
ci.DisplayName = "Cat #1";
Test.Items.Add(ci);

PropertyGridCategoryItem ci1 = new PropertyGridCategoryItem();
ci1.DisplayName = "Cat #2";
Test.Items.Add(ci1);

PropertyGridCategoryItem ci2 = new PropertyGridCategoryItem();
ci2.DisplayName = "Cat #3";
ci.Accessors.Add(ci2);

I i = new I();
i.A = 5;

PropertyGridPropertyItem pi1 = new PropertyGridPropertyItem();
pi1.Description = "test description";

Binding b = new Binding("A");

b.Source = i;
b.Mode = BindingMode.TwoWay;
b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

pi1.SetBinding(PropertyGridPropertyItem.ValueProperty, b);

ci2.Accessors.Add(pi1);

And this all works... the property on I is read and written to correctly... However...

public int A
{
get
{
System.Diagnostics.Debug.WriteLine("get: " + a.ToString());
return a;
}

set
{
if (value > 10)
throw new Exception("The name can not be empty.");

a = value;

System.Diagnostics.Debug.WriteLine("set: " + a.ToString());
}
}

This is the accessor in my test app. For the I.A property.

It throws an exception if value > 10...

when I throw an exception in a setter when using PropertyGrid.SelectedObject instead, it puts the red rectangle around the cell as expected...

The above sample when building the entries manually does not. What do I need to add to get the red rectangle on error thing back?

[Modified at 04/06/2010 01:23 PM]
Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hello,

That is correct, nested categories are supported, but cannot be used out of the box when populating the PropertyGrid via SelectedObject(s)/Properties. Properties generated from these items utilize the CategoryAttribute, which takes a single string. You can achieve nested categories by populating PropertyGrid.Items/ItemsSource directly (as you show above), or by implementing a custom DataFactory. The latter of which is responsible for converting SelectedObject(s), Properties, and various other settings into a list of "data accessors".

We do have a TODO item down for supporting nested categories using the CategoryAttribute (using a special syntax like "One\Two"), but it is currently a lower priority item. I've added this post to the notes, so that you will be notified when it's completed.

The reason the validation errors are not presented has to do with your setup. You effectively have three object TextBox, PropertyGridPropertyItem, and I (your data object). TextBox.Text is bound to PropertyGridPropertyItem.Value, which is in turn bound to I.A.

By throwing an exception in the setter for I.A, the binding between PropertyGridPropertyItem.Value and I.A will be marked as invalid. The binding between the TextBox.Text and PropertyGridPropertyItem.Value is still considered valid, and this is the binding that WPF uses to determine if it should render the "error template" or the red box.

You might be able to use binding groups to link the two bindings, so the red box is shown. More info on that can be found here.


Actipro Software Support

Posted 9 years ago by SledgeHammer01
Avatar
As I indicated in the above post, when I do:

propGrid.SelectedObject = i;

throwing the exception in the I.A setter triggers the red error box. I assume you guys are using reflection and manually building the bindings when the SelectedObject property is set on the property grid? Obviously, you are building the bindings in a slightly different way.

To do what you suggested and link the two bindings, wouldn't I need to have access to TextBox.Text? It does not appear I have access to that from the application.

Is there an easier way to get the error to trigger?

[Modified at 04/06/2010 04:51 PM]
Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hello,

When you use SelectedObject(s)/Properties the PropertyGridPropertyItem isn't used at all. Instead, we access the underlying property using it's associated PropertyDescriptor, usually via an instance of PropertyDescriptorDataAccessor. In this case, the TextBox.Text is bound to PropertyDescriptorDataAccessor.Value. The setter of the PropertyDescriptorDataAccessor.Value will then call your property's setter, which may throw an exception. This exception passes up through the PropertyDescriptorDataAccessor.Value setter and the binding between TextBox.Text and PropertyDescriptorDataAccessor.Value is marked as having validation errors. When using PropertyGridPropertyItem, another Binding is being added into the mix.

You are correct that you would need access to the TextBox.Text binding, which you can't easily get to. I'm not sure there's a way to forward the validation errors from one binding to another, even if they are linked via a common property (i.e. PropertyGridPropertyItem.Value).

I've made some minor changes to PropertyDescriptorDataAccessor so that it is easier to construct, for cases like this. So your code would end up being:
I i = new I(); 
i.A = 5; 

ci2.Accessors.Add(new PropertyDescriptorDataAccessor(i, "A"));
This would then wrap the A property just as if it were created via the DataFactory (i.e. when using SelectedObject). This will be included in the 2010.1 release due out in a few weeks.

On a final note, you can probably use CategoryDataAccessor in place of PropertyGridCategoryItem. PropertyGridCategoryItem is only useful if you need to perform bindings, or would like to tie properties like Visibility to the container element. CategoryDataAccessor is a lighter weight object, and is what is generally used by the data factories.


Actipro Software Support

Posted 9 years ago by SledgeHammer01
Avatar
Thanks! Works like a charm!
The latest build of this product (v2018.1 build 0675) 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.