Dynamic or indexed property bindings in the the PropertyGrid.

7 posts, 1 answers
  1. Ari
    Ari avatar
    14 posts
    Member since:
    Jul 2012

    Posted 18 Jun 2012 Link to this post

    Hi...

    I'm trying to build out a dynamic editor using the PropertyGrid.  I have had success getting the hierarchy working, but I'm running into trouble when I try to bind the data.  So far, I've tried it two different ways: first, by exposing a Dictionary<string, string> (I'll leave out any type issues, and just pretend that all my non-hierarchical fields are strings, for now), and second using dynamic types.  So, I set up the PropertyGrid, pretty simply in the xaml:

    <telerik:RadPropertyGrid x:Name="propertyGrid1" Grid.Column="1"
                                     SearchInNestedProperties="True"
                                     Width="620" Height="400"
                                     AutoGenerateBindingPaths="False"
                                     AutoGeneratePropertyDefinitions="False"
                                     NestedPropertiesVisibility="{Binding IsChecked, ElementName=CheckBox1, Converter={StaticResource converter}}"
                                     DescriptionPanelVisibility="Collapsed"/>

    Then, so that I can play with things, I'm adding PropertyDefinitions to propertyGrid1.PropertyDefinitions when a button is clicked.  I created a simple class with a dictionary of strings in it called MyEntity:

            public class MyEntity : INotifyPropertyChanged
            {
                public event PropertyChangedEventHandler PropertyChanged;

                public void AddString(string key, string value)
                {
                    _stringVal.Add(key, value);
                }

                private Dictionary<string, string> _stringVal = new Dictionary<string, string>();
                public Dictionary<string, string> StringVal
                {
                    get
                    {
                        return _stringVal;
                    }

                    set
                    {
                        if (value != _stringVal)
                        {
                            _stringVal = value;
                            NotifyPropertyChanged("StringVal");
                        }
                    }
                }

                private void NotifyPropertyChanged(string name)
                {
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs(name));
                }
            }

    Here's the class that corresponds to the xaml above:

    public partial class Example : UserControl, INotifyPropertyChanged
    {
            private MyEntity _ent = new MyEntity();
            
            public Example()
            {
                InitializeComponent();
                _ent.AddString("Item0", "000");
                _ent.AddString("Item1", "111");
                _ent.AddString("Item2", "222");
                DataContext = _ent;
            }
           
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                  var topDef = new PropertyDefinition()
                    {
                        DisplayName = "Top Item " + propertyGrid1.PropertyDefinitions.Count.ToString(),
                        Binding = new Binding("StringVal[Item0]")
                        {
                            Path = new PropertyPath("StringVal[Item0]")
                        },
                        OrderIndex = propertyGrid1.PropertyDefinitions.Count,
                        IsReadOnly = false
                    };
                propertyGrid1.PropertyDefinitions.Add(topDef);
            }
    }

    I can't get the data to bind though.  The PropertyGrid comes up, with no errors, but the properties seem to be considered null.  I can get bindings to work with paths like "StringVal[Item0]" using other controls, but not PropertyDefinitions.

    I've also tried this using a dynamic type (i.e. derived from DynamicObject), instead of the MyEntity class that contains the  dictionary, and gotten the same result.  I prefer that approach, but thought that showing it this way would be simpler to understand.

    Am I way off base here, or just missing something simple?

    Thanks,

    -Ari
  2. Answer
    Ivan Ivanov
    Admin
    Ivan Ivanov avatar
    1127 posts

    Posted 20 Jun 2012 Link to this post

    Hello Ari,

    Currently nested PropertyDefinitions do not directly support binding to indexers. Is utilizing a EditorTemplate DataTemplate that hosts an another control (i.e. TextBox) a viable option for you?

    Kind regards,
    Ivan Ivanov
    the Telerik team
    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
  3. DevCraft banner
  4. Ari
    Ari avatar
    14 posts
    Member since:
    Jul 2012

    Posted 20 Jun 2012 Link to this post

    I'm not sure.  Can I create those on the fly?  In other words, if I iterate through my dictionary of strings, can I create something to bind to for each element on the fly as I iterate, rather than name a property on a hard-coded property on an object that already exists?  It's hard to state this clearly. 

    I guess what I'm getting at is, can I show a Dictionary<string, string>{{"a", "aaa"}, {"b", "bbb"}}, rather than an object with fields named "a" and "b"?  What I've already done shows "a" and "b", but I can't figure a way to bind the data.

    It sounds like what your suggesting will work, but what do I pass to the Binding of the PropertyDefinitions?

    Thanks,

    -Ari
  5. Ari
    Ari avatar
    14 posts
    Member since:
    Jul 2012

    Posted 20 Jun 2012 Link to this post

    Actually, another alternative is that I use a dynamic, rather than a dictionary.  So, instead of having

    Dictionary<string, string>{{"a", "aaa"}, {"b", "bbb"}}

    I'd do something like

    dynamic myObjToBindWith = new MyDynamic();
    myObjToBindWith["a"] = "aaa";
    myObjToBindWith["b"] = "bbb";

    At that point, myObjToBindWith will have properties called "a" and "b" (if I derive MyDynamic from DynamicObject correctly).  Shouldn't I be able to bind to those properties?  It hasn't worked when I tried it that way either, but I'm wondering if I did something wrong, or if that isn't supported either.

    Thanks,

    -Ari
  6. Ari
    Ari avatar
    14 posts
    Member since:
    Jul 2012

    Posted 20 Jun 2012 Link to this post

    Hi...

    I think I misunderstood you earlier (i.e., if I use the EditorTemplate, I don't need the binding on the PropertyDefinition).  Looks like using the EditorTemplates should work perfectly, assuming I can figure a way to get their bindings set up correctly, and can my data into and out of them.

    Thanks,

    -Ari
  7. Rajendar
    Rajendar avatar
    69 posts
    Member since:
    Jun 2013

    Posted 01 Sep in reply to Ari Link to this post

    Hi Everyone,

    I have similar requirement, I need to bind Dictionary<string,string> to RadPropertyGrid. I am new telerik. Can anyone give simple sample application?

    Regards,

    Rajendar

  8. Stefan Nenchev
    Admin
    Stefan Nenchev avatar
    277 posts

    Posted 02 Sep Link to this post

    Hello Rajendar,

    In R2 2016 we have introduced Indexer Support for RadPropertyGrid. Please check the following article for more information - RadPropertyGrid - Indexer Support. If you have some more specific scenario, please provide more details regarding it.

    Regards,
    Stefan Nenchev
    Telerik by Progress
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
Back to Top
DevCraft banner