Setting Property Editor at Runtime

Grids for WPF Forum

Posted 11 years ago by United Biosource - United Biosource
Version: 4.5.0486
Avatar
I have a property grid that needs to bind to different objects at runtime - so I can't use xaml to create the PropertyEditors at design time. Your sample app uses only xaml - do you have an example of how to:

1. Create a Property Editor Value Template that can be referenced in code
2. How to bind that template to a selected property at runtime

Thanks

p.s., I am very new to this and just starting an evaluation, so if you could be as explicit as possible in your answer, that would be most appreciated.

Comments (5)

Posted 11 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Sydney,

We don't currently have an example, but it is on the TODO list. You can define and associated editors dynamically, but the approach differs depending on how you are using the PropertyGrid.

This forum post describes how to build a property editor (in the form of a DataTemplate) in code using a FrameworkElementFactory. Associating that editor with one or more properties is the part that really varies:

1. If using SelectedObject(s), you can statically decorate your properties with an EditorAttribute.
2. If using SelectedObject(s), you can implement ICustomTypeDescriptor on your object and dynamically generate an EditorAttribute for a property.
3. If using a PropertyGridPropertyItem, then you can simply assign the PropertyGridPropertyItem.ValueTemplate.
4. You can associate your editor with any property that matches a given name, type, or both using PropertyGrid.PropertyEditors (per instance) or BuiltinEditors.PropertyEditors (global for all PropertyGrids).

Let us know if you need more information in one of these areas.


Actipro Software Support

Posted 11 years ago by United Biosource - United Biosource
Avatar
Thanks, yes, I could use a little more information on how to create a FrameworkElementFactory (is there an example of that? I searched the Sample solution and the Help file . . .).

Based on the Sample, I've got this so far (below), but I'm not sure how to put it together, and particularly don't understand what to do with the Bound properties.

Do you mean to say that there should be a FrameworkElementFactory for each of the objects below (Grid, Column Def, Text Box, etc.) or can there be one factory for the whole group? In either case, does this go in the constructor? How is it returned?


Grid grid = new Grid();
ColumnDefinition cd1 = new ColumnDefinition();
cd1.Width = new GridLength(0, GridUnitType.Star);
ColumnDefinition cd2 = new ColumnDefinition();
cd2.Width = new GridLength(0, GridUnitType.Auto);
grid.ColumnDefinitions.Add(cd1);
grid.ColumnDefinitions.Add(cd2);

TextBox tb = new TextBox();
tb.Margin = new Thickness(0);
tb.HorizontalAlignment = HorizontalAlignment.Stretch;
tb.VerticalAlignment = VerticalAlignment.Center;
tb.BorderThickness = new Thickness(0);

//I assume that this below won't work, so how do you do this in code?
tb.Text="{Binding Value, RelativeSource={RelativeSource AncestorType={x:Type propgrid:IPropertyDataAccessor}}, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}"

Thanks
Posted 11 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Sydney,

As I said, we do not currently have a sample that does this. There are examples on the Internet of how to use the FrameworkElementFactory (such as here). But yes, you need to create a factory for every element.

You would need to use the FrameworkElementFactory.SetBinding, in order to bind dependency properties.

Depending on your situation though, it is possible to define the DataTemplate in XAML as a resource and then simply load that resource from the code-behind. This is usually preferable, since defining complex DataTemplates using FrameworkElementFactory objects is a pain.


Actipro Software Support

Posted 11 years ago by United Biosource - United Biosource
Avatar
Okay, here's my situation. My objects are LINQ objects, plus, I would like to keep my model and presentation logic separate, so decorating my properties w/presentation logic is not ideal. I am using SelectObject. Can you say more about the steps to "implement ICustomTypeDescriptor on your object and dynamically generate an EditorAttribute for a property"?

Regarding options 3 & 4, if I am using SelectObject, then the Editors and/or PropertyItems are not present until after SelectObject is complete - will it work to set the ValueTemplate after the binding, or are these not options with SelectObject?

As for this: "it is possible to define the DataTemplate in XAML as a resource and then simply load that resource from the code-behind," what would be the code to load the resource?

Is this correct?


PropertiesGrid.
PropertyEditors.
GetValueEditor("PropertyName", typeof(string)).
ValueTemplate = new PropertyNameTemplate();

Thanks.
Posted 11 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
The ICustomTypeDescriptor interface can be used to customize how the PropertyGrid "sees" an object. This interface can be used to filter properties, add virtual properties, and/or customize existing properties (e.g. by adding/removing attributes). There are several examples of using ICustomTypeDescriptor on the Internet (most of which are for the WinForms PropertyGrid but should work as-is with our PropertyGrid).

You cannot use option #3 when using SelectedObject(s), but you can use option #4. The PropertyGrid.PropertyEditors collection allows you to "override" the default editors used. The "Actipro PropertyGrid\User Interface Layer\Property Editors" topic in the help file describes the precedence order of property editor definitions.

As for loading the resource, no that is not correct. I was referring to loading a WPF resource, such as using the FindResource method. I'm not sure what PropertyNameTemplate is. You would:

1. Load the DataTemplate using the FindResource method (if you don't know how to do this, then you may need to run through this page (external)).
2. Create a new instance of PropertyEditor (using parameterless constructor).
3. Assign PropertyEditor.PropertyName and/or PropertyType to specify which property/properties the associated DataTemplate should be used for.
4. Assign PropertyEditor.ValueTemplate to the DataTemplate that should be used (alternatively, you can assign the ValueTemplateKey if using a ComponentResourceKey).
5. Add the PropertyEditor to PropertyGrid.PropertyEditors (or add it to BuiltinEditors.PropertyEditors if you would like all instances of the PropertyGrid to use it).


Actipro Software Support

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

Add Comment

Please log in to a validated account to post comments.