Completed
Last Updated: 23 Sep 2022 13:07 by ADMIN
Release R3 2022
Matthias
Created on: 04 Aug 2022 14:49
Category: PropertyGrid
Type: Bug Report
1
RadPropertyGrid: ReadOnly Attribute does not apply if selecting multiple objects (of same type)

When setting SelectedObject a ReadOnlyAttribute applies to the grid. But when wrapping it in an object[] and assign it to SelectedObjects the grid allows editing.

Sample application included.

Attached Files:
2 comments
Matthias
Posted on: 08 Aug 2022 07:03

Hello Dess,

thank you for the clarification and example code.

Regards,
Matthias

ADMIN
Dess | Tech Support Engineer, Principal
Posted on: 05 Aug 2022 11:10

Hello, Matthias,   

After reviewing the provided sample project, I would like to start with some details how RadPropertyGrid works.

When you set the RadPropertyGrid.SelectedObject property, RadPropertyGrid extracts all public properties for the object considering the ReadOnly attribute as well. Thus, when a property is marked as ReadOnly, the editor is not activated at all. 

    class Data
    {
        [ReadOnly(true)]
        public string Name { get; set; }
        public string Street { get; set; }
    }
            this.radPropertyGrid1.SelectedObject= 
                    new Data
                    {
                        Name = "John Doe",
                        Street = "e-Street"
                    };

When you set the RadPropertyGrid.SelectedObjects property to a collection of different (by type) objects, RadPropertyGrid extracts all public properties that are common between the objects in the collection. The editor is always activated and you can input any values. However, after committing the editor's value, only the editable properties are affected. These objects in the collection that have ReadOnly attribute for this property wouldn't be affected. This is desired behavior because you may have two classes where the Name property in the first class is ReadOnly but in the other class - not. You shouldn't be restricted to activate the editor in this case. 

    class Data
    {
        [ReadOnly(true)]
        public string Name { get; set; }
        public string Street { get; set; }
    }

    class Person
    { 
        public string Name { get; set; }
        public string Address { get; set; }
    }
             object[] collection = new object[]
                {
                    new Data
                    {
                        Name = "John Doe",
                        Street = "e-Street"
                    },
                     new Person
                    {
                        Name = "Ana Brown",
                        Address = "Paris"
                    }
                };
            radPropertyGrid1.SelectedObjects = collection;


A specific case is when you set the SelectedObjects property to a collection of only one object. Then, RadPropertyGrid checks that only a single object is available and all of its public properties are shown. In this case it is reasonable to consider the ReadOnly attribute since all of the properties are extracted.

             object[] collection = new object[]
                {
                    new Data
                    {
                        Name = "John Doe",
                        Street = "e-Street"
                    }
                };
            radPropertyGrid1.SelectedObjects = collection;

That is why I have approved this report. 

You can track its progress, subscribe for status changes and add your comments on the following link - feedback item.

I have also updated your Telerik points.

Currently, the possible solution that I can suggest is to use the following implementation:

 

        public class CustomPropertyGrid : RadPropertyGrid
        {
            public override string ThemeClassName
            {
                get
                {
                    return typeof(RadPropertyGrid).FullName;
                }
            }
            protected override PropertyGridElement CreatePropertyGridElement()
            {
                return new CustomPropertyGridElement();
            }
        }

        public class CustomPropertyGridElement : PropertyGridElement
        {
            protected override Type ThemeEffectiveType
            {
                get
                {
                    return typeof(PropertyGridElement);
                }
            }
            protected override PropertyGridSplitElement CreateSplitElement()
            {
                return new CustomPropertyGridSplitElement();
            }
        }

        public class CustomPropertyGridSplitElement : PropertyGridSplitElement
        {
            protected override Type ThemeEffectiveType
            {
                get
                {
                    return typeof(PropertyGridSplitElement);
                }
            }
            protected override PropertyGridTableElement CreateTableElement()
            {
                return new CustomPropertyGridTableElement();
            }
        }

        public class CustomPropertyGridTableElement : PropertyGridTableElement
        {
            protected override Type ThemeEffectiveType
            {
                get
                {
                    return typeof(PropertyGridTableElement);
                }
            }
            protected override bool IsItemEditable(PropertyGridItem item)
            {
                object[] collection = this.SelectedObjects as object[];
                if (collection != null && collection.Length == 1)
                {

                    Telerik.WinControls.UI.PropertyGridData.DescriptorItemAccessor accessor = item.Accessor as DescriptorItemAccessor;
                    if (accessor != null)
                    {

                        MultiObjectPropertyDescriptor multiDescriptor = item.Accessor.PropertyDescriptor as MultiObjectPropertyDescriptor;
                        if (multiDescriptor != null)
                        {
                            foreach (Attribute attribute in multiDescriptor.Attributes)
                            {
                                ReadOnlyAttribute readOnlyAtt = attribute as ReadOnlyAttribute;
                                if (readOnlyAtt != null && readOnlyAtt.IsReadOnly)
                                {
                                    return false;
                                }
                            }
                        }
                    }
                }
                return base.IsItemEditable(item);
            }
        }

I hope this information helps. If you need any further assistance please don't hesitate to contact me. 

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.