Пример использование PropertyGrid в C#

Автор: | 31.12.2016

Для тех, кто постоянно использует Visual Studio, панель Properties (Свойства), является одним из основных инструментов для редактирования свойств элементов, в первую очередь это касается графических примитивов в Windows Forms и WPF. Несомненно, такой элемент может быть полезен и в собственном проекте. Далее речь пойдет о том, как использовать PropertyGrid в приложении.

Введение

В рамках данной статьи мы создадим приложение, в при построении которого научимся работать с элементом PropertyGrid (сетка свойств).

Код проекта можно скачать здесь.

Типичное окно сетки свойств выглядит так:

Example of propertygrid

Данный элемент предназначен для редактирования и отображения свойств различных объектов в удобном виде.

Свойства элемента могут быть сгруппированы по определенному признаку, либо выстроены по алфавиту. Каждое свойство имеет имя (левый столбец), значение (правый столбец) и описание (находится внизу окна). Свойство может быть изменяемым или неизменяемым.

В нашем проекте мы продемонстрируем работу со следующими типами свойств:

  • текст;
  • логическое значение;
  • перечисление;
  • цвет;
  • шрифт.

Работу с динамически изменяющимися массивами, которые, тоже, несомненно, можно использовать в качестве значения свойств, мы рассмотрим в следующей статье, посвященной данной теме.

Для того, чтобы в проекте использовать сетку свойств необходимо:

  1. Создать в родительском элементе (например форме) объект класса PropertyGrid.
  2. Создать класс, описывающий определенный набор свойств. Каждое такое свойство конфигурируется посредством атрибутов.
  3. Создать объект класса свойств и присвоить его полям необходимые значения.
  4. Присвоить свойству  SelectedObject объекта класса PropertyGrid объект с описанием свойств (созданный в пункте 3).

Создание каркаса приложения

Создадим новое приложение Windows Forms с именем “PropertyGridExample” и добавим на главную форму два элемента “ComboBox” и “PropertyGrid”.

Если в списке Toolbox нет элемента PropertyGrid, то его следует добавить. Для этого нажмите правой кнопкой мыши на панели Toolbox и выберите элемент меню “Choose Items…”.

Добавление PropertyGrid

На вкладке “.NET Framework Components” найдите в списке строку с именем “PropertyGrid” и отметьте ее галочкой.

Выбор элемента PropertyGrid

Теперь на панели “Toolbox” у вас должен появиться элемент “PropertyGrid”.

Элемент PropertyGrid

Зададим следующие свойства родительской форме:

Свойство Значение
FormBorderStyle FixedSingle
Text PropertyGrid Example
Size 340; 345

Элементу “ComboBox”:

Свойство Значение
FlatStyle Flat
(Name) cbKindOfProps
Location 12; 12
Size 310; 21
Items Example of PropertyGrid for TextField

Example of PropertyGrid for True/False field

Example of PropertyGrid for Categories

Example of PropertyGrid for Color field

Example of PropertyGrid for Font field

Example of PropertyGrid for Enum

Элементу “PropertyGrid”:

Свойство Значение
(Name) prgProperty
Location 12; 42
Size 310; 266

Должно получиться примерно следующее.

Форма приложения

Создадим пустую папку с именем “PropertyClasses” в нашем приложении, для этого нужно щелкнуть правой кнопкой мыши на имени проекта в дереве решения окна “Solution Explorer” и выбрать “Add->New Folder”.

В созданную папку добавим файлы C# классов со следующими именами:

  • PropertyTextField
  • PropertyTrueFalse
  • PropertyCategories
  • PropertyList
  • PropertyColorSelector
  • PropertyFontConfig

После этого окно решения должно выглядеть примерно так:

Окно решения Solution

Добавим обработчики событий для следующих элементов:

“Form1” (“Form”)

Событие Функция обработчик
Load Form1_Load

“cbKindOfProps” (“ComboBox”)

Событие Функция обработчик
SelectedIndexChanged cbKindOfProps_SelectedIndexChanged

Исходный код главной формы проекта приведен ниже.

using System;
using System.Windows.Forms;

using PropertyGridExample.PropertyClasses;

namespace PropertyGridExample
{
    public partial class Form1 : Form
    {
        private PropertyTextField prTextProp;
        private PropertyTrueFalse prLogicProp;
        private PropertyCategories prCategoryProp;
        private PropertyColorSelector prColorProp;
        private PropertyFontConfig prFontProp;
        private PropertyList prListProp;
        
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            prTextProp = new PropertyTextField();
            prLogicProp = new PropertyTrueFalse();
            prCategoryProp = new PropertyCategories();
            prColorProp = new PropertyColorSelector();
            prFontProp = new PropertyFontConfig();
            prListProp = new PropertyList();
            
            cbKindOfProps.SelectedIndex = 0;
        }

        private void cbKindOfProps_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch(cbKindOfProps.SelectedIndex)
            {
                case 0: prgProperty.SelectedObject = prTextProp;
                    break;
                case 1: prgProperty.SelectedObject = prLogicProp;                   
                    break;
                case 2: prgProperty.SelectedObject = prCategoryProp;
                    break;
                case 3: prgProperty.SelectedObject = prColorProp;
                    break;
                case 4: prgProperty.SelectedObject = prFontProp;
                    break;
                case 5: prgProperty.SelectedObject = prListProp;
                    break;               
            }
        }
    }
}

При загрузке формы в методе “Form1_Load” осуществляется инициализация объектов, которые являются демонстрацией использования тех или иных типов свойств. Метод “cbKindOfProps_SelectedIndexChanged” вызывается при выборе интересующего нас примера из выпадающего списка. Для управления сеткой свойств используется объект “prgProperty”.

Создание классов, описывающих разные типы свойств

Для управления видом свойства в окне “PropertyGrid” используются атрибуты, приведенные в таблице ниже.

Атрибут Описание
[Browsable(bool)] Отображение свойства. Отображать (true) или не отображать (false) данное свойство в окне “PropertyGrid”.
[ReadOnly(bool)] Редактируемость свойства. Свойство с возможностью редактирования (true) или только для чтения (false)
[Category(string)] Категория свойства. Позволяет логически группировать свойства.
[Description(string)] Описание свойства. Будет отображено в нижней части окна PropertyGrid.
[TypeConverter(System.Type)] Задание вида свойства в окне PropertyGrid.

Далее будут представлены классы, реализующие работу тех или иных типов свойств.

Тип свойства – текстовое поле.

class PropertyTextField
{
    String m_TextField;
    [Browsable(true)]
    [Description("Example of text field")]
    [DisplayName("Text field")]
    public String TextField
    {
        get { return m_TextField; }
        set { m_TextField = value; }
    }
}

Тип свойства – логическая переменная.

class PropertyTrueFalse
{
    bool m_LogicField;
    [Browsable(true)]
    [Description("Example of logic field")]
    [DisplayName("Logic field")]
    public bool LogicField
    {
        get { return m_LogicField; }
        set { m_LogicField = value; }
    }
}

Тип свойства – список.

class PropertyList
{
    Direction m_dir;
    [DisplayName("Direction")]
    [Description("Direction property")]        
    [TypeConverter(typeof(DirConverter))]
    public Direction Dir
    {
        get
        {
            return m_dir;
        }
        set
        {
            m_dir = value;
        }
    }       
}

Для того, чтобы данный список работал добавим перечисление “Direction”, элементы которого и будут содержаться в выпадающем списке.

enum Direction
{
    [Description("UP")]
    UP,
    [Description("DOWN")]
    DOWN,
    [Description("RIGHT")]
    RIGHT,
    [Description("LEFT")]
    LEFT
}

Также определим класс “DirConverter” для преобразования элементов перечисления “Direction” в строковое представление. Тип этого класса указывается в качестве параметра атрибута “TypeConverter” класса перечислительного свойства.

class DirConverter : EnumConverter
{
    private Type type;
    
    public DirConverter(Type type)
        : base(type)
    {
        this.type = type;
    }

    public override object ConvertTo(ITypeDescriptorContext context, 
        CultureInfo culture, object value, Type destType)
    {
        FieldInfo fi = type.GetField(Enum.GetName(type, value));
        DescriptionAttribute descAttr =
          (DescriptionAttribute)Attribute.GetCustomAttribute(
            fi, typeof(DescriptionAttribute));

        if (descAttr != null)
            return descAttr.Description;
        else
            return value.ToString();
    }

    public override object ConvertFrom(ITypeDescriptorContext context, 
        CultureInfo culture, object value)
    {
        foreach (FieldInfo fi in type.GetFields())
        {
            DescriptionAttribute descAttr =
              (DescriptionAttribute)Attribute.GetCustomAttribute(
                fi, typeof(DescriptionAttribute));

            if ((descAttr != null) && ((string)value == descAttr.Description))
                return Enum.Parse(type, fi.Name);
        }
        return Enum.Parse(type, (string)value);
    }
}

Тип свойства – цвет.

class PropertyColorSelector
{
    Color m_ColorField;
    [Browsable(true)]
    [Description("Example of color field")]
    [DisplayName("Color field")]
    public Color TextField
    {
        get { return m_ColorField; }
        set { m_ColorField = value; }
    }
}

Тип свойства – шрифт.

class PropertyFontConfig
{
    Font m_FontField;
    [Browsable(true)]
    [Description("Example of font field")]
    [DisplayName("Font field")]
    public Font FontField
    {
        get { return m_FontField; }
        set { m_FontField = value; }
    }
}

Демонстрация разбиения свойств на категории.

class PropertyCategories
{
    String m_TextParam1;
    [Browsable(true)]
    [Description("Property: Text param 1")]
    [Category("Text params")]
    [DisplayName("Text param 1")]
    public String TextParam1
    {
        get { return m_TextParam1; }
        set { m_TextParam1 = value; }
    }

    String m_TextParam2;
    [Browsable(true)]
    [Description("Property: Text param 2")]
    [Category("Text params")]
    [DisplayName("Text param 2")]
    public String TextParam2
    {
        get { return m_TextParam2; }
        set { m_TextParam2 = value; }
    }

    bool m_LogicParam1;
    [Browsable(true)]        
    [Description("Property: Logic param 1")]
    [Category("Logic params")]
    [DisplayName("Logic param 1")]
    public bool LogicParam1
    {
        get { return m_LogicParam1; }
        set { m_LogicParam1 = value; }
    }

    bool m_LogicParam2;
    [Browsable(true)]        
    [Description("Property: Logic param 2")]
    [Category("Logic params")]
    [DisplayName("Logic param 1")]
    public bool LogicParam2
    {
        get { return m_LogicParam2; }
        set { m_LogicParam2 = value; }
    }
}

Приложение PropertyGridExample

Запущенное приложение “PropertyGridExample” выглядит так.

Загруженное приложение PropertyGridExample

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

Логическое свойство PropertyGrid

Демонстрация разделения свойств на группы.

Разделение на группы PropertyGrid

Выбор цвета.

Выбор цвета PropertyGrid

Задание шрифта.

Выбор шрифта PropertyGrid

Выбор элемента из заданного списка.

Выбор элемента из списка ProprtyGrid

Работа с PropertyGrid довольно проста, достаточно разобраться с основными моментами, которые необходимо учитывать при его использовании. На этом все, спасибо за внимание!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *