This is a migrated thread and some comments may be shown as answers.

Add property definitions dynamically from code-behind

4 Answers 640 Views
PropertyGrid
This is a migrated thread and some comments may be shown as answers.
Robert
Top achievements
Rank 1
Robert asked on 03 Sep 2013, 06:46 PM
I have a situation where I would like to be able to add property definitions from code behind, however it doesn't appear to be working properly.

Here's what I have: I made a custom object for use in xaml called a PropertyDefinitionList:

public class PropertyDefinitionList : List<Telerik.Windows.Controls.Data.PropertyGrid.PropertyDefinition>
{
    public PropertyDefinitionList() { }
}

In a resource dictionary I instance such a list like follows:

<local:ObjectPropertyFilterList x:Key="PropertyDefinitions" >
    <propertyGrid:PropertyDefinition Binding="{Binding Name}" />
    <propertyGrid:PropertyDefinition Binding="{Binding ID}" />
</local:ObjectPropertyFilterList>

I get a reference to this list in my code behind and call it PropertyList. At a certain
point I want to the property definitions to the .PropertyDefinitions collection on the
RadPropertyGrid, so in the function that does it I have the following code:

rpg1.PropertyDefinitions.AddRange(propertyDefinitionList1);
rpg1.item = targetitem;

However when the code executes I get two blank definition entries in the property grid
display. There is no display name nor value. The properties definitely exist in the object
being assigned to "item", but its like these property definitions don't get their binding
set. In another thread it was stated that property definitions have their binding
evaluated when the .item property changes, so what is happening (or not happening) here? I
figure I must be doing something wrong.

Thanks!

4 Answers, 1 is accepted

Sort by
0
Robert
Top achievements
Rank 1
answered on 04 Sep 2013, 04:45 PM
Ok, here is some added information. After some further testing I found out this is happening with any custom property definitions when the PropertySet mode is not None.

Is there a way to define custom property definitions that work when the property grid is using property sets?
0
Ivan Ivanov
Telerik team
answered on 05 Sep 2013, 01:15 PM
Hi,

Your code looks fine to me. Would it be possible for you to send us a runnable sample project, which we would be able to debug on our side?

Regards,
Ivan Ivanov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Robert
Top achievements
Rank 1
answered on 12 Sep 2013, 04:45 PM
Sorry it took a bit to get back to you, but I've made an example of what I mean. I'm attaching code here since I can't attach solutions.

The project is simple that in that it includes 2 custom classes?: A List of Property Definitions and a custom item for properties. The custom item includes a string property called A and an int property called B. My property definition list has two definitions, which bind to "A" and "B" respectively, and my property grid is set to not auto generate definitions. Also its PropertySetMode set to "Intersection" so it can handle lists of items.

Finally I have a button which will show a messagebox to show me the value of the first item of the list, so I can see if the properties were edited or not.

In my program code I create two instances of the class and add them to a list, then I add the property definitions from my resource list to the propertygrid's "PropertyDefinitions" collection using an .AddRange() call. Finally I set the Item property of the PropertyGrid to my list of items.

When the display comes up, the fields are blank (which I would expect for two objects with different values) but when I change values in the textboxes and then press my button, I see that the property has not been updated. It works if I assign the property grid to just a single object, but not in intersection or union mode.

Xaml:

<Window x:Class="RadPropGrid_Example.MainWindow"
        xmlns:local="clr-namespace:RadPropGrid_Example"
        xmlns:propGrid="clr-namespace:Telerik.Windows.Controls.Data.PropertyGrid;assembly=Telerik.Windows.Controls.Data"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:PropertyDefinitionList x:Key="propertyDefinitionList1">
            <propGrid:PropertyDefinition Binding="{Binding A}" />
            <propGrid:PropertyDefinition Binding="{Binding B}" />
        </local:PropertyDefinitionList>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <telerik:RadPropertyGrid x:Name="rpg1" AutoGeneratePropertyDefinitions="False" PropertySetMode="Intersection" />
        <Button Grid.Row="1" Content="Show Item Values" Click="Button_Click" />
    </Grid>
</Window>

C# code:
using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;
using Telerik.Windows.Controls.Data.PropertyGrid;
 
namespace RadPropGrid_Example
{
    public partial class MainWindow : Window
    {
        MyItem myItem;
        MyItem myItem2;
 
        public MainWindow()
        {
            InitializeComponent();
 
            myItem = new MyItem("Me", 1);
            myItem2 = new MyItem("You", 2);
 
            List<MyItem> items = new List<MyItem>();
            items.Add(myItem);
            items.Add(myItem2);
 
            PropertyDefinitionList pdl = this.Resources["propertyDefinitionList1"] as PropertyDefinitionList;
 
            rpg1.PropertyDefinitions.AddRange(pdl);
            rpg1.Item = items;
        }
 
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(string.Format("A={0} B={1}", myItem.A, myItem.B));
        }
    }
 
    public class PropertyDefinitionList : List<PropertyDefinition>
    {
        public PropertyDefinitionList() : base() { }
    }
 
    public class MyItem
    {
        public string A { get; set; }
        public int B { get; set; }
 
        public MyItem(string a, int b)
        {
            A = a;
            B = b;
        }
    }
}

I'm guessing the problem comes from the Bindings in the custom property definitions. I know you're using a DynamicObject behind the scenes, but how can I use custom PropertyDefinitions in this case? This becomes even more important as I start having more complex definitions, such as having a property that is a reference object and wanting nested properties to bind to that object's properties. Is this even possible?

Thanks!

0
Ivan Ivanov
Telerik team
answered on 18 Sep 2013, 07:35 AM
Hello,

 Please excuse me for the delayed answer. We do us DynamicObject under the hood. However, as we do not want replace the original Item property value with it, the DynamicObject instane is exposed through the CurrentPropertySet property. You can bind to its properties at runtime like this:

rpg.PropertySetMode = Telerik.Windows.Controls.Data.PropertyGrid.PropertySetOperation.Intersection;
            rpg.Item = new List<FrameworkElement>() { new Button(), new TextBox() };
            rpg.PropertyDefinitions.Add(new Telerik.Windows.Controls.Data.PropertyGrid.PropertyDefinition() { Binding = new Binding("CurrentPropertySet[BorderThickness]") });

Regards,
Ivan Ivanov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
Tags
PropertyGrid
Asked by
Robert
Top achievements
Rank 1
Answers by
Robert
Top achievements
Rank 1
Ivan Ivanov
Telerik team
Share this question
or