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

Cannot populate Popup on dynamically generated list

2 Answers 542 Views
PropertyGrid
This is a migrated thread and some comments may be shown as answers.
John
Top achievements
Rank 1
Veteran
John asked on 10 Jun 2020, 01:36 PM

Hello,

First, I'm loading a PropertyGrid with dynamically generated PropertyDefintions at run-time, instead of hard coded XAML.  Second, for one PropertyGrid entry, I'm trying to load a Combobox whose model includes both a value and the list of items to show in the Combobox.  Unfortunately when I try to do this, I just get a blank Combobox (nothing in either the entry or the dropdown list) and an error:

System.Windows.Data Error: 40 : BindingExpression path error: 'Items' property not found on 'object' ''ObservableCollection`1' (HashCode=35225966)'. BindingExpression:Path=Items; DataItem='ObservableCollection`1' (HashCode=35225966); target element is 'RadComboBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')

 

 

So obviously XAML does not "see" Items from the model, but I thought I had everything defined properly (see code below).  So I'm missing something somewhere.  Or maybe something is not structured right.  I've looked at several example projects given in this forum, but nothing works or the sample does not fit what I'm trying to do.

The goal is to emulate an Enum but make it dynamic by loading the Comboxbox with dynamically generated lists, and I want both the entry and the list of items to be dynamically generated in the model.  Any suggestions would be welcome!!

Thanks in advance

Here is where the property definitions are being loaded

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    PropertyDefinitionCollection properties = EditorPropertyGrid.PropertyDefinitions;
 
    ObservableCollection<object> testList = new ObservableCollection<object>();
 

           // WORKS

    TestEnumKeyValue first = new TestEnumKeyValue() { Key = "Static Enum Prop", Value = TestEnum.test3 };
    testList.Add(first);
    properties.Add(new PropertyDefinition()
    {
        DisplayName = first.Key,
        Binding = new Binding("Value") { Source = first }
    });
 

           // DOES NOT WORK

    ComboListKeyValue third = new ComboListKeyValue() { Key = "List Prop", Value = "A3" };
    testList.Add(third);
    properties.Add(new PropertyDefinition()
    {
        DisplayName = third.Key,
        Binding = new Binding("Value") { Source = third } ,
        EditorTemplate = (DataTemplate)EditorGrid.Resources["ComboBoxTemplate"]
    });
 
    EditorPropertyGrid.Item = testList;
}

 

Here is the model

enum TestEnum
{
    test1,
    test2,
    test3
}
 
abstract class KeyValueBase
{
    public string Key { get; set; }
}
 
class TestEnumKeyValue : KeyValueBase
{
    public TestEnum Value { get; set; }
}
 
class ComboListKeyValue : KeyValueBase, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string _value;
    private List<string> _values;
 
    public ComboListKeyValue()
    {
        _values = new List<string>() // list for combobox dynamically generated here
            {
                "A1",
                "A2",
                "A3",
                "A4"
            };
    }
    public string Value
    {
        get { return this._value; }
        set
        {
            if (value != this._value)
            {
                this._value = value;
                this.OnPropertyChanged("Value");
            }
        }
    }
 
    public List<string> Items
    {
        get
        {
            return _values;
        }
        set
        {
            _values = value;
        }
    }
 
    protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, args);
        }
    }
 
    private void OnPropertyChanged(string propertyName)
    {
        this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }
}

 

And here is the XAML

<Grid x:Name="EditorGrid">
    <Grid.Resources>
        <DataTemplate x:Key="ComboBoxTemplate">
            <telerik:RadComboBox ItemsSource="{Binding Items, Mode=OneWay}" SelectedValue="{Binding Value}"/>
        </DataTemplate>
    </Grid.Resources>
    <telerik:RadPropertyGrid x:Name="EditorPropertyGrid" Margin="10,10,10,10" DescriptionPanelVisibility="Collapsed" SearchBoxVisibility="Collapsed" AutoGeneratePropertyDefinitions="False" NestedPropertiesVisibility="Visible" AutoGenerateBindingPaths="False" SortAndGroupButtonsVisibility="Collapsed" />
</Grid>

 

Thanks!

2 Answers, 1 is accepted

Sort by
0
Accepted
Vladimir Stoyanov
Telerik team
answered on 15 Jun 2020, 09:17 AM

Hello John,

Thank you for the shared code snippets. 

The reason for the binding error is that the DataContext inside the EditorTemplate is whatever is set to the Item property of the RadPropertyGrid, which is an ObservableCollection in the demonstrated scenario.

That said, you can use a RelativeSource binding for the RadComboBox properties. I am attaching a sample project to show what I have in mind. Do check it out and let me know, if you find it helpful. 

Regards,
Vladimir Stoyanov
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
John
Top achievements
Rank 1
Veteran
answered on 16 Jun 2020, 05:06 AM

Hello Vladimir,

Thank you so much for your reply!  The relative source binding works great for my sample application!  Not only that, bonus points for the same XAML bindings working on nested properties as well!  This has helped me very much.

So this thread can be closed...

Thank you!

John

Tags
PropertyGrid
Asked by
John
Top achievements
Rank 1
Veteran
Answers by
Vladimir Stoyanov
Telerik team
John
Top achievements
Rank 1
Veteran
Share this question
or