Инструменты пользователя

Инструменты сайта


Боковая панель

developers:tutorial:selectionset

Это старая версия документа.


Выделение элементов

За выделение объектов на видовом экране отвечает класс, наследник от абстрактного класса SelectionSet. Он за возвращение списка всех выделяемых элементов, выделение элементов и их хранение, а также за копирование элементов через буфер обмена и их перемещение, если это необходимо. Каждый слой видового экрана при реализации возвращает свой экземпляр SelectionSet.

Если слой не поддерживает выделение элементов, то в качестве SelectionSet можно вернуть экземпляр DefaultSelectionSet. Это реализация по умолчанию, не позволяющая выделить элементы.

Для реализации наследника от SelectionSet необходимо реализовать следующие функции и методы:

  • Select - предназначен для выделения или снятия выделения с объекта.
  • Clear - снимает выделение со всех выделенных объектов
  • Erase - удаляет все выделенные объекты.
  • GetObjectsAtPoint - выбор объектов в указанной точке и расстояние до них.
  • GetObjectsByFrame - выбор объектов рамкой
  • GetObjectsByPolygon - выбор объектов полигоном. В данный момент метод не поддерживается.
  • GetEnumerator - перечисление выделенных объектов.
  • GetSelectable - перечисление всех объектов которые можно выделить.
  • Count - количество выделенных элементов
  • IsEnable - проверяет включен ли объект на этом SelectionSet.
  • IsOwned - проверяет принадлежит ли объект выделяемым объектам этого SelectionSet.
  • IsSelected - проверяет выделен ли объект на этом SelectionSet.
В функцию GetObjectsAtPoint в качестве параметра приходит временной интервал, в течении которого вы должны завершить выполнение функции. Если интервал равен 0 то время на выполнение функции не ограничено.

Свойства объектов, которые будут выделены с помощью SelectionSet будут отображены на видовом экране. А в качестве типа объекта будет выведено значение функции ToString().

Для того чтобы управлять названием и положением свойства в инспекторе объектов можно использовать атрибуты [DisplayName] и [Category]. Для скрытия свойства доступен атрибут [Browsable]

Более подробно работа со свойствами описана в разделе Таблицы и диалоги.

Для реализации методов для выбора объектов, таких как GetObjectsAtPoint и сложной геометрии объектов можно использовать специальный класс - NullDeviceContext. Он позволяет определить принадлежит ли заданная точка объекту или рамке, нарисовав сам объект в памяти.

При реализации метода GetObjectsByFrame необходимо учитывать тип рамки, и в зависимости от этого пользоваться либо NullDeviceContext либо FullDeviceContext.

Создайте новую модель и видовой слой и подключите к программному комплексу Топоматик Робур.

Изменим модель таким образом, чтобы она хранила внутри несколько списков точек. Для этого создадим класс Points.cs описывающий список точек:

    //Класс для хранения точек в нашей модели
    //поддерживаем интерфесы IStgSerializable для сохранения и IOwned для определения владельца списка точек
    class Points : IStgSerializable, IOwned
    {
        private Model m_Owner;
 
        private List<Vector2D> m_Points = new List<Vector2D>();
 
        public Points(Model owner)
        {
            m_Owner = owner;
        }
 
        //Метод для добавления точки в список
        public void AddPoint(Vector2D point)
        {
            m_Points.Add(point);
        }
 
        //Метод для получения точки из списка
        public Vector2D this[int index]
        {
            get
            {
                return m_Points[index];
            }
        }
 
        //Количество точек в списке
        //Свойство декорировано атрибутом DisplayName для отображения в инспекторе объектов
        [DisplayName("Количество точек")]
        public int Count
        {
            get
            {
                return m_Points.Count;
            }
        }
 
        //Владелец нашего списка точек, у нас это наша модель
        //Свойство декорировано атрибутом Browsable чтобы исключить отображение в инспекторе объектов
        [Browsable(false)]
        public object Owner
        {
            get
            {
                return m_Owner;
            }
            set
            {
                //Владелец назначается один раз на конструкторе объекта, назначение отдельно недопустимо
                throw new NotSupportedException();
            }
        }
 
        //Реализация загрузки
        public void LoadFromStg(StgNode node)
        {
            m_Points.Clear();
            //При загрузке массива указывается тип составляющих массив значений
            var array = node.GetArray("Values", StgType.Node);
            for (int i = 0; i < array.Count; i++)
            {
                m_Points.Add(Vector2D.LoadFromStg(array.GetNode(i)));
            }
        }
 
        //Реализация сохранения
        public void SaveToStg(StgNode node)
        {
            //Сохраняем значения в узел
            //Сохраняем массив с указанием типа значений
            var array = node.AddArray("Values", StgType.Node);
            for (int i = 0; i < m_Points.Count; i++)
            {
                m_Points[i].SaveToStg(array.AddNode());
            }
        }
 
        //Дополнительно перекрываем метод ToString() для отображения типа объекта в инстпекторе объектов
        public override string ToString()
        {
            return "Точки модели";
        }
    }

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

developers/tutorial/selectionset.1552233787.txt.gz · Последние изменения: 2021/07/22 14:28 (внешнее изменение)