PropertyGrid и динамические свойства
От: lutikman  
Дата: 17.05.10 17:43
Оценка:
Добрый день.
Хочу с помощью PropertyGrid реализовать изменение и сохранение настроек программы. Но параметры заранее не известны и будут иметь след структуру:

AppConfig
— Property1
— Property2
— // —
— Property N
DataBaseConfig
— DBProfile 1
— Property1
— Property2
— // —
— Property N
— DBProfile 2
— Property1
— Property2
— // —
— Property N
— // —
— DBProfile M

Помогите реализовать подобное.

17.05.10 23:34: Перенесено модератором из '.NET' — Хитрик Денис
Re: PropertyGrid и динамические свойства
От: Аноним  
Дата: 17.05.10 17:52
Оценка:
Помню, делал подобное так: генерировал исходный код класса (со всеми необходимыми атрибутами у свойств), затем компилировал и загружал в память (с помощью CSharpCodeProvider), создавал экземпляр объекта (с помощью Reflection) и передавал PropertyGrid'у.
Re: PropertyGrid и динамические свойства
От: Pavel_Agurov Россия  
Дата: 17.05.10 18:12
Оценка:
Здравствуйте, lutikman, Вы писали:

L>Добрый день.

L>Хочу с помощью PropertyGrid реализовать изменение и сохранение настроек программы. Но параметры заранее не известны и будут иметь след структуру:

C#. Разработка компонентов в MS Visual Studio 2005/2008

6.7. Виртуальные свойства
В предыдущем разделе мы удаляли свойство из списка свойств. Было бы логично разобраться с тем, как добавлять свойства в этот список, т. е. создавать дополнительные свойства компонента, которые существуют только в режиме разработки. Посмотрите, например, на свойства группы Design (рис. 6.8). Свойства GenerateMember, Locked являются виртуальными. Реально у компонента GradientLabel таких свойств нет.
Для того чтобы добавить свойство, существующее только в режиме разработки, нужно добавить его в словарь properties в методе PreFilterProperties(), а само свойство будет существовать только в классе дизайнера:

  class GradientLabelDesigner : ControlDesigner
  {
        int virtualProp;
        [DesignerSerializationVisibility(
                      DesignerSerializationVisibility.Hidden)]
        [Description("Виртуальное свойство")]
        public int VirtualProp
        {
            get { return virtualProp;  }
            set { virtualProp = value; }
        }
  }

Как я уже говорил, словарь properties представляет собой связь между именем свойства и его дескриптором, т. е. для добавления свойства нам потребуется дескриптор. Получить его можно двумя способами. Первый – создать дескриптор с помощью метода CreateProperty() класса TypeDescriptor:

PropertyDescriptor descr = TypeDescriptor.CreateProperty(
     base.GetType(), "VirtualProp", typeof(int), new Attribute[0]);

Первый параметр передает тип класса, к которому будет добавлен метод, второй – имя метода, третий – тип и четвертый задает атрибуты. Недостаток этого способа именно в отсутствии атрибутов. Перечислять необходимые атрибуты вручную довольно затруднительно, поэтому лучше пойти другим путем и копировать атрибуты существующего свойства:

PropertyDescriptor oldDescr =
        TypeDescriptor.GetProperties(this)["VirtualProp"];
Attribute [] attributes = new Attribute [descr.Attributes.Count];
descr.Attributes.CopyTo(attributes, 0);
PropertyDescriptor descr = TypeDescriptor.CreateProperty(
        base.GetType(), descr, attributes);

После этого можно добавить его в свойства компонента:
properties["VirtualProp"] = descr;
Очень важно чтобы виртуальное свойство имело атрибут DesignerSerializationVisibility.Hidden (см. разд. 10.4), т. к. иначе оно попадет в свойства режима выполнения.
Полный код дизайнера, добавляющего виртуальное свойство, приведен в листинге 6.9.
Еще раз к вопросу о виртуальных свойствах я вернусь в разд. 7.18.

Рис. 6.8. Виртуальные свойства компонента
Листинг 6.9 Добавление виртуального свойства VirtualProp

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms.Design;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;

namespace MyControl
{
    class GradientLabelDesigner : ControlDesigner
    {
        int virtualProp;
        [DesignerSerializationVisibility(
                       DesignerSerializationVisibility.Hidden)]
        [Description("Виртуальное свойство")]
        public int VirtualProp
        {
            get { return virtualProp; }
            set { virtualProp = value; }
        }

        protected override void PreFilterProperties(
                                       IDictionary properties)
        {
            base.PreFilterProperties(properties);

            // Берем существующее свойство
            PropertyDescriptor oldDescr =
                  TypeDescriptor.GetProperties(this)["VirtualProp"];
            // Копируем его атрибуты
            Attribute[] attributes =
                           new Attribute[oldDescr.Attributes.Count];
            oldDescr.Attributes.CopyTo(attributes, 0);
            // Создаем новое свойство
            PropertyDescriptor descr =
                           TypeDescriptor.CreateProperty(
                    base.GetType(), oldDescr, attributes);
            // Добавляем его в свойства компонента
            properties["VirtualProp"] = descr;
        }
    }
}
Re[2]: PropertyGrid и динамические свойства
От: lutikman  
Дата: 17.05.10 18:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Помню, делал подобное так: генерировал исходный код класса (со всеми необходимыми атрибутами у свойств), затем компилировал и загружал в память (с помощью CSharpCodeProvider), создавал экземпляр объекта (с помощью Reflection) и передавал PropertyGrid'у.

Не отказался бы от примера в виде исходного кода.
Re[3]: PropertyGrid и динамические свойства
От: Аноним  
Дата: 17.05.10 19:30
Оценка: -1 :)
Здравствуйте, lutikman, Вы писали:

L>Не отказался бы от примера в виде исходного кода.



        private string GenerateClassCode()
        {
            StringBuilder sb = new StringBuilder();
            
            for (int n = 0; n < 6; n++)
            {
                sb.AppendFormat(@"
private string field{0} = """";
[Category(""{1}"")]
[DefaultValue("""")]
public string Prop{0}
{{
    get {{ return field{0}; }}
    set {{ field{0} = value; }}
}}
",
                 n, n < 3 ? "Category1" : "Category2");
            }
            
            return string.Format(@"
using System.ComponentModel;
public class MyType
{{
{0}
}}",
             sb);
        }
        
        private Assembly CompileSourceCode(string text)
        {
            CompilerParameters parameters = new CompilerParameters();
            parameters.ReferencedAssemblies.Add("System.dll");
            parameters.GenerateInMemory = true;
            
            CSharpCodeProvider provider = new CSharpCodeProvider();
            CompilerResults results = provider.CompileAssemblyFromSource(parameters, text);

            return results.CompiledAssembly;
        }
        
        public Form1()
        {
            InitializeComponent();

            Assembly assembly = CompileSourceCode(GenerateClassCode());
            Type type = assembly.GetType("MyType");
            object obj = type.GetConstructor(Type.EmptyTypes).Invoke(null);
            this.propertyGrid1.SelectedObject = obj;
        }
Re: PropertyGrid и динамические свойства
От: ylem  
Дата: 17.05.10 23:52
Оценка:
http://www.google.ru/search?hl=ru&amp;newwindow=1&amp;q=Add++Items+to+PropertyGrid+runtime&amp;aq=f&amp;aqi=&amp;aql=&amp;oq=&amp;gs_rfai=
Re: PropertyGrid и динамические свойства
От: _FRED_ Черногория
Дата: 18.05.10 03:39
Оценка:
Здравствуйте, lutikman, Вы писали:

L>Хочу с помощью PropertyGrid реализовать изменение и сохранение настроек программы. Но параметры заранее не известны и будут иметь след структуру:


L>Помогите реализовать подобное.

Understanding the TypeDescriptor: A Metadata Engine for Designtime Code
Help will always be given at Hogwarts to those who ask for it.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.