Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > свойтсва в PropertyGrid


Автор: vantusiatina 21.11.2008, 17:31
Я пишу дизайнер формы.
В PropertyGrid при выделении стандартного компонента отображаются все его свойства. Как сделать так, чтобы отображались только необходимые свойства, которые я укажу для каждого добавляемого компонента?

Автор: Partizan 21.11.2008, 17:36
vantusiatina, для ненужных добавьте атрибут Browsable(false)

Автор: ProgrammingLife 21.11.2008, 17:53
 smile  Вы уж извените...не ту тему въехал  :

Автор: vantusiatina 21.11.2008, 18:35
Partizan, т.е. придется писать свой класс, наследующий этот Control и там прописывать эти атрибуты? Если не сложно, то можно пример?

Автор: Partizan 21.11.2008, 19:02
vantusiatina, давно я делал что-то подобное....сейчас попробую накидать пример...
класс писать не придётся ) придётся возиться с TypeDescriptor|PropertyDescriptor и иже с ними )

Автор: diadiavova 21.11.2008, 20:20
ProgrammingLife, ЖЖОШ

Автор: Partizan 21.11.2008, 20:27
vantusiatina, вот накидал:

Код

    public class MyCustomTypeDescriptor : CustomTypeDescriptor
    {
        private List<string> _shadowedProperties;
        
        private Type _shadowedType;
        
        public MyCustomTypeDescriptor(Type shadowedType, string[] shadowedProps)
        {
            this._shadowedType = shadowedType;
            this._shadowedProperties = new List<string>(shadowedProps);
        }
        private PropertyDescriptorCollection FilterProps(PropertyDescriptorCollection props)
        {
            if (props == null)
                return null;

            List<PropertyDescriptor> validProps = new List<PropertyDescriptor>();
            foreach (PropertyDescriptor pd in props)
            {
                if (!_shadowedProperties.Contains(pd.Name))
                {
                    validProps.Add(pd);
                }
            }

            return new PropertyDescriptorCollection(validProps.ToArray());
        }

        public override PropertyDescriptorCollection GetProperties()
        {
            return this.FilterProps(TypeDescriptor.GetProperties(_shadowedType));
        }

        public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            return this.FilterProps(TypeDescriptor.GetProperties(_shadowedType, attributes));
        }
    }



Код

    public class MyTypeDescriptionProvider : System.ComponentModel.TypeDescriptionProvider
    {
        public override System.ComponentModel.ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
        {
            if (objectType == typeof(Button))
            {
                return new MyCustomTypeDescriptor(objectType, new string[] {"Visible", "Enabled"});
            }
            return base.GetTypeDescriptor(objectType, instance);
        }
    }


Код

...
        private void button1_Click(object sender, EventArgs e)
        {
            TypeDescriptor.AddProvider(new MyTypeDescriptionProvider(), button1);
            this.propertyGrid1.SelectedObject = this.button1;
        }
...


Идея ясна?

Автор: vantusiatina 21.11.2008, 22:03
да, большое спасибо.
Меня интересует ещё такой вопрос, а как при это изменить наименование свойства и описание для него?

Автор: Partizan 21.11.2008, 23:16
vantusiatina, изменить у свойства атрибуты Description и DisplayName

Автор: vantusiatina 22.11.2008, 00:18
что-то я не догоняю, так они же только для чтения, можно тоже пример?

Автор: Partizan 22.11.2008, 01:04
Аналогично классу TypeDescriptorProvider перегружается класс PropertyDescriptorProvider

Автор: vantusiatina 23.11.2008, 12:52
чё-то я не нашел PropertyDescriptorProvider

в итоге конечный вариант кот. отображает только нужные свойства выглядит так

Код

public class MyCustomTypeDescriptor : CustomTypeDescriptor
    {
        private List<string> _shadowedProperties;
        
        private Type _shadowedType;
        
        public MyCustomTypeDescriptor(Type shadowedType, string[] shadowedProps)
        {
            this._shadowedType = shadowedType;
            this._shadowedProperties = new List<string>(shadowedProps);
        }
        private PropertyDescriptorCollection FilterProps(PropertyDescriptorCollection props)
        {
            if (props == null)
                return null;
            List<PropertyDescriptor> validProps = new List<PropertyDescriptor>();
            foreach (PropertyDescriptor pd in props)
            {
                if (!_shadowedProperties.Contains(pd.Name))
                {
                    validProps.Add(new MyCustomPropertyDescriptor(pd));
                }
            }
            return new PropertyDescriptorCollection(validProps.ToArray());
        }
        public override PropertyDescriptorCollection GetProperties()
        {
            return this.FilterProps(TypeDescriptor.GetProperties(_shadowedType));
        }
        public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            return this.FilterProps(TypeDescriptor.GetProperties(_shadowedType, attributes));
        }
    }


Код

public class MyCustomPropertyDescriptor : PropertyDescriptor
    {
        private PropertyDescriptor baseProp;

        public EPropertyDescriptor(PropertyDescriptor baseProp)
            : base(baseProp)
        {
            this.baseProp = baseProp;
        }

        public override string DisplayName
        {
            get
            {
                return GetNewDisplayName(base.DisplayName);
            }
        }

        public override string Category
        {
            get
            {
                return GetNewCategoryName(base.Category);
            }
        }

        public override Type ComponentType
        {
            get { return baseProp.ComponentType; }
        }

        public override bool IsReadOnly
        {
            get { return baseProp.IsReadOnly; }
        }

        public override Type PropertyType
        {
            get { return baseProp.PropertyType; }
        }

        public override void ResetValue(object component)
        {
            baseProp.ResetValue(component);
        }

        public override bool CanResetValue(object component)
        {
            return baseProp.CanResetValue(component);
        }

        public override object GetValue(object component)
        {
            return baseProp.GetValue(component);
        }

        public override void SetValue(object component, object value)
        {
            baseProp.SetValue(component, value);
        }

        public override bool ShouldSerializeValue(object component)
        {
            return baseProp.ShouldSerializeValue(component);
        }

        private string GetNewDisplayName(string displayname)
        {
            if (displayname == "Text")
            {
                return "Текст";
            }
            return base.DisplayName;
        }

        private string GetNewCategoryName (string categoryname)
        {
            if (categoryname == "Appearance")
            {
                return "Внешний вид";
            }
            return base.DisplayName;
        }
    }


большое спасибо smile 

Автор: vantusiatina 25.11.2008, 05:23
столкнулся с проблемой сокрытия и переменования вложенных свойств. Почему метод GetChildProperties() не вызывается?

Автор: Partizan 25.11.2008, 11:33
vantusiatina, а в чём проблема? свойство объекта - такой же объект. С ним можно проделать всё то же самое, что и с вашив корневым объектом.

Автор: vantusiatina 25.11.2008, 21:47
а можно самый простенький пример?
я пытался перегружать GetProperties и возвращать только нужную мне коллекцию и нового типа MyCustomPropertyDescriptor, только метод GetProperties не вызывается. Как ещё перехватить вызов вложенных свойств и вернуть что нужно?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)