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

Change & update display name of a property at run-time

0 Answers 2467 Views
PropertyGrid
This is a migrated thread and some comments may be shown as answers.
Yefan
Top achievements
Rank 1
Veteran
Yefan asked on 20 Jul 2020, 12:17 PM

Hello,

I have a new issue. I'd like to change and update the display name of a property at run-time.

The scenario is that if we want to change the name of a property (for example, LinkBudgetApp1 with "App1" as display name),

we do the changes in the project settings, so the current display is overwritten. So far, I did the appropriate changes in the code 3.

However, nothing changes.

Maybe I'm using ICustomTypeDescriptor and PropertyDescriptor in the wrong way, please tell me what are the changes to do to make

this work. Thank you.

 

A sample model class

public class LinkBudgetExpandableAttribute : ObservableObjectBase
    {
 
        // Constructor here
 
        // Implementation of ObservableObjectBase
 
  
        [DisplayName("App1")]
        public string LinkBudgetApp1
        {
            get { // some code here }
            set { // some code here }
        }
 
        [[DisplayName("App2")]
        public string LinkBudgetApp2
        {
            get { // some code here }
            set { // some code here }
        }
 
        [DisplayName("App3")]
        public string LinkBudgetApp3
        {
            get { // some code here }
            set { // some code here }
        }
 
        public override string ToString()
        {
            // returns all properties values
        }
}

 

Implementation of ICustomTypeDescriptor

class LinkBudgetToPropertyGridAdapter : ICustomTypeDescriptor
    {
        public readonly LinkBudgetExpandableAttribute lbe;
        Dictionary<string, IEnumerable<Attribute>> dctPropertyConfiguration = new Dictionary<string, IEnumerable<Attribute>>();
         
        public LinkBudgetToPropertyGridAdapter(object feature, Dictionary<string, IEnumerable<Attribute>> attributes)
        {
            this.lbe = feature as LinkBudgetExpandableAttribute;
            this.dctPropertyConfiguration = attributes;
        }
 
        public object GetValue()
        {
            return lbe;
        }
 
        public AttributeCollection GetAttributes()
        {
            return TypeDescriptor.GetAttributes(lbe, true);
        }
 
        public string GetClassName()
        {
            return GetType().Name;
        }
 
        public string GetComponentName()
        {
            throw new NotImplementedException();
        }
 
        public TypeConverter GetConverter()
        {
            return TypeDescriptor.GetConverter(lbe, true);
        }
 
        public EventDescriptor GetDefaultEvent()
        {
            return TypeDescriptor.GetDefaultEvent(lbe, true);
        }
 
        public PropertyDescriptor GetDefaultProperty()
        {
            return TypeDescriptor.GetDefaultProperty(lbe, true);
        }
 
        public object GetEditor(Type editorBaseType)
        {
            return TypeDescriptor.GetEditor(lbe, editorBaseType, true);
        }
 
        public EventDescriptorCollection GetEvents()
        {
            return TypeDescriptor.GetEvents(lbe, true);
        }
 
        public EventDescriptorCollection GetEvents(Attribute[] attributes)
        {
            return TypeDescriptor.GetEvents(lbe, attributes, true);
        }
 
        public PropertyDescriptorCollection GetProperties()
        {
            return GetProperties(new Attribute[0]);
        }
 
        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            List<PropertyDescriptor> props = new List<PropertyDescriptor>();
            string[] linkBudgetAttributeNames =
                {FeatureAttributes.LinkBudgetInput,
                FeatureAttributes.LinkBudgetInputApp1,
                FeatureAttributes.LinkBudgetInputApp2,
                FeatureAttributes.LinkBudgetInputApp3
            };
             
            foreach (var attributeName in linkBudgetAttributeNames)
            {
                if (dctPropertyConfiguration.Keys.Contains(attributeName))
                {
                    var prop = new LinkBudgetDescriptor(attributeName, lbe, dctPropertyConfiguration[attributeName]);
                    props.Add(prop);
                }
            }
            return new PropertyDescriptorCollection(props.ToArray());
        }
 
        public object GetPropertyOwner(PropertyDescriptor pd)
        {
            return this;
        }
    }

 

A method to define and retrieve attributes in some class

protected virtual Project GetCurrentProject { get; }
 
protected Dictionary<string, IEnumerable<Attribute>> getAttributeConfiguration()
        {
            Dictionary<string, IEnumerable<Attribute>> result = new Dictionary<string, IEnumerable<Attribute>>();
 
            foreach (var fa in FeatureAttributes.StandardFeatureAttributes)
            {
                var attributes = new List<Attribute>();
                attributes.Add(new CategoryAttribute(fa.Category));
                attributes.Add(new DisplayNameAttribute(fa.DisplayName));
                attributes.Add(new DescriptionAttribute(fa.Description));
                attributes.Add(new ReadOnlyAttribute(fa.IsReadOnly));
                if (fa.Converter != null)
                {
                    attributes.Add(new TypeConverterAttribute(fa.Converter));
                }
                attributes.Add(new BrowsableAttribute(fa.IsBrowsable));
                 
 
                /// *** HACK *** Telerik uses a DisplayAttribute instead of a DisplayNameAttribute to define the name displayed
                var displayAttribute = new DisplayAttribute();
                if (fa.Name.Contains("App1"))
                {
                    displayAttribute.Name = GetCurrentProject.Settings.Applications["Application1"].Name;
                    displayAttribute.AutoGenerateField = true;
                
                else if (fa.Name.Contains("App2"))
                {
                    displayAttribute.Name = GetCurrentProject.Settings.Applications["Application2"].Name;
                    displayAttribute.AutoGenerateField = GetCurrentProject.Settings.Applications["Application2"].IsVisible;
                }
                else if (fa.Name.Contains("App3"))
                {
                    displayAttribute.Name = GetCurrentProject.Settings.Applications["Application3"].Name;
                    displayAttribute.AutoGenerateField = GetCurrentProject.Settings.Applications["Application3"].IsVisible;
                }
                else
                    displayAttribute.Name = fa.DisplayName;
                displayAttribute.GroupName = fa.Category;
                displayAttribute.Description = fa.Description;
                 
                attributes.Add(displayAttribute);
 
                result.Add(fa.Name, attributes);
            }
 
            return result;
        }

Implementation of PropertyDescriptor

public class LinkBudgetDescriptor : PropertyDescriptor
    {
        private readonly List<Attribute> PropertyAttributes;
        private readonly LinkBudgetExpandableAttribute lbe;
        public LinkBudgetDescriptor(string attributeName, LinkBudgetExpandableAttribute lbe,
            IEnumerable<Attribute> dctPropertyConfiguration)
            : base(attributeName, dctPropertyConfiguration.ToArray())
        {
            this.lbe = lbe;
            PropertyAttributes = dctPropertyConfiguration.ToList();
        }
        public override AttributeCollection Attributes
        {
            get
            {
                return base.Attributes;
            }
        }
        public override string Category { get { return PropertyAttributes.OfType<CategoryAttribute>().SingleOrDefault()?.Category; } }
        public override string Description { get { return PropertyAttributes.OfType<DescriptionAttribute>().SingleOrDefault()?.Description; } }
        public override string DisplayName { get { return PropertyAttributes.OfType<DisplayNameAttribute>().SingleOrDefault()?.DisplayName; } }
        public override bool IsReadOnly { get { return PropertyAttributes.OfType<ReadOnlyAttribute>().SingleOrDefault() != null ? PropertyAttributes.OfType<ReadOnlyAttribute>().SingleOrDefault().IsReadOnly : false; } }
        public override Type ComponentType { get { return typeof(LinkBudgetToPropertyGridAdapter); } }
        public override Type PropertyType
        {
            get
            {
                var val = lbe.GetType();
                return val;
            }
        }
    
        public override bool CanResetValue(object component)
        {
            return true;
        }
        public override object GetValue(object component)
        {
            return (component as LinkBudgetToPropertyGridAdapter).GetValue();
        }
        public override void ResetValue(object component)
        {
            
        }
        public override void SetValue(object component, object value)
        {
           
        }
        public override bool ShouldSerializeValue(object component)
        {
            return false;
        }
    }
Albano
Top achievements
Rank 1
commented on 06 May 2021, 02:38 PM

Have you found a solution? I am also interested.

No answers yet. Maybe you can help?

Tags
PropertyGrid
Asked by
Yefan
Top achievements
Rank 1
Veteran
Share this question
or