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

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


developers:tutorial:selectionset

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

Следующая версия
Предыдущая версия
developers:tutorial:selectionset [2019/03/10 14:59]
vasya создано
developers:tutorial:selectionset [2022/03/15 19:15] (текущий)
proxor
Строка 10: Строка 10:
   * [[developers:​references:​topomatic.cad.view.selectionset.clear|Clear]] - снимает выделение со всех выделенных объектов   * [[developers:​references:​topomatic.cad.view.selectionset.clear|Clear]] - снимает выделение со всех выделенных объектов
   * [[developers:​references:​topomatic.cad.view.selectionset.erase|Erase]] - удаляет все выделенные объекты.   * [[developers:​references:​topomatic.cad.view.selectionset.erase|Erase]] - удаляет все выделенные объекты.
-  * [[developers:​references:​topomatic.cad.view.selectionset.getobjectsatpoint_topomatic.cad.foundation.vector3d_system.predicate_1_system.int32|GetObjectsAtPoint]] - возвращает список элементов в указанной точке и расстояние до них.  +  * [[developers:​references:​topomatic.cad.view.selectionset.getobjectsatpoint_topomatic.cad.foundation.vector3d_system.predicate_1_system.int32|GetObjectsAtPoint]] - выбор объектов в указанной точке и расстояние до них.  
-  * [[developers:​references:​194476d8735a41d451648829001e3a70|GetObjectsByFrame]] - выделение ​объектов рамкой +  * [[developers:​references:​194476d8735a41d451648829001e3a70|GetObjectsByFrame]] - выбор ​объектов рамкой 
-  * [[developers:​references:​f6f3e815a6f715eef33c195c169a8798|GetObjectsByPolygon]] - выделение ​объектов полигоном. В данный момент метод не поддерживается.+  * [[developers:​references:​f6f3e815a6f715eef33c195c169a8798|GetObjectsByPolygon]] - выбор ​объектов полигоном. В данный момент метод не поддерживается.
   * [[developers:​references:​topomatic.cad.view.selectionset.getenumerator|GetEnumerator]] - перечисление выделенных объектов.   * [[developers:​references:​topomatic.cad.view.selectionset.getenumerator|GetEnumerator]] - перечисление выделенных объектов.
   * [[developers:​references:​topomatic.cad.view.selectionset.getselectable|GetSelectable]] - перечисление всех объектов которые можно выделить.   * [[developers:​references:​topomatic.cad.view.selectionset.getselectable|GetSelectable]] - перечисление всех объектов которые можно выделить.
Строка 23: Строка 23:
 В функцию [[developers:​references:​topomatic.cad.view.selectionset.getobjectsatpoint_topomatic.cad.foundation.vector3d_system.predicate_1_system.int32|GetObjectsAtPoint]] в качестве параметра приходит временной интервал,​ в течении которого вы должны завершить выполнение функции. Если интервал равен 0 то время на выполнение функции не ограничено.</​note>​ В функцию [[developers:​references:​topomatic.cad.view.selectionset.getobjectsatpoint_topomatic.cad.foundation.vector3d_system.predicate_1_system.int32|GetObjectsAtPoint]] в качестве параметра приходит временной интервал,​ в течении которого вы должны завершить выполнение функции. Если интервал равен 0 то время на выполнение функции не ограничено.</​note>​
  
 +Свойства объектов,​ которые будут выделены с помощью [[developers:​references:​topomatic.cad.view.selectionset|SelectionSet]] будут отображены на видовом экране. А в качестве типа объекта будет выведено значение функции [[developers:​references:​system.object.tostring|ToString()]]. ​
 +<​note>​Для того чтобы управлять названием и положением свойства в инспекторе объектов можно использовать атрибуты [DisplayName] и [Category]. Для скрытия свойства доступен атрибут [Browsable]</​note>​
 +
 +Более подробно работа со свойствами описана в разделе [[developers:​tutorial:​dlgandpropertygrid|Таблицы и диалоги]].
 +
 +Для реализации методов для выбора объектов,​ таких как [[developers:​references:​topomatic.cad.view.selectionset.getobjectsatpoint_topomatic.cad.foundation.vector3d_system.predicate_1_system.int32|GetObjectsAtPoint]] и сложной геометрии объектов можно использовать специальный класс - [[developers:​references:​topomatic.cad.view.nulldevicecontext|NullDeviceContext]]. Он позволяет определить принадлежит ли заданная точка объекту или рамке, нарисовав сам объект в памяти. ​
 +<​note>​
 +При реализации метода [[developers:​references:​194476d8735a41d451648829001e3a70|GetObjectsByFrame]] необходимо учитывать тип рамки, и в зависимости от этого пользоваться либо [[developers:​references:​topomatic.cad.view.nulldevicecontext|NullDeviceContext]] либо [[developers:​references:​topomatic.cad.view.fulldevicecontext|FullDeviceContext]].
 +</​note>​
 +
 +Создайте новую [[developers:​tutorial:​addlayer|модель и видовой слой]] и подключите к программному комплексу [[http://​www.topomatic.ru|Топоматик Робур]].
 +
 +Изменим модель таким образом,​ чтобы она хранила внутри несколько списков точек. ​
 +Для этого создадим класс Points.cs описывающий список точек:
 +<code csharp>
 +    //​Класс для хранения точек в нашей модели
 +    //​поддерживаем интерфесы 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 "​Точки модели";​
 +        }
 +    }
 +</​code>​
 +
 +Поскольку экземпляры этого класса в дальнейшем будут выделятся на слое, то все свойства мы декорируем необходимыми атрибутами и дополнительно перекрываем метод [[developers:​references:​system.object.tostring|ToString()]].
 +
 +Реализуем класс модели и поместим его в файл Model.cs:
 +<code csharp>
 +    //​Класс реализующий структуру данных нашей модели
 +    //для поддержки интерфейса IStateController наследуем от StateControllerObject
 +    class Model : StateControllerObject,​ IStgSerializable
 +    {
 +        private bool m_ReadOnly = false;
 +
 +        private List<​Points>​ m_Points = new List<​Points>​();​
 +
 +        //​Метод для добавления списка точек в модель
 +        public Points Add()
 +        {
 +            var p = new Points(this);​
 +            m_Points.Add(p);​
 +            return p;
 +        }
 +
 +        //​Метод для получения списка точек из модели
 +        public Points this[int index]
 +        {
 +            get
 +            {
 +                return m_Points[index];​
 +            }
 +        }
 +
 +        //​Метод для удаления списка точек из модели
 +        public bool Remove(Points points)
 +        {
 +            return m_Points.Remove(points);​
 +        }
 +
 +        //​Количество списков в модели
 +        public int Count
 +        {
 +            get
 +            {
 +                return m_Points.Count;​
 +            }
 +        }
 +
 +        //флаг только для чтения
 +        public override bool ReadOnly
 +        {
 +            get
 +            {
 +                return m_ReadOnly;
 +            }
 +
 +            set
 +            {
 +                m_ReadOnly = value;
 +            }
 +        }
 +
 +        //​Загрузка из узла
 +        public void LoadFromStg(StgNode node)
 +        {
 +            m_Points.Clear();​
 +            //При загрузке массива указывается тип составляющих массив значений
 +            var array = node.GetArray("​Points",​ StgType.Node);​
 +            for (int i = 0; i < array.Count;​ i++)
 +            {
 +                var p = new Points(this);​
 +                p.LoadFromStg(array.GetNode(i));​
 +                m_Points.Add(p);​
 +            }
 +        }
 +
 +        //​Сохранение в узел
 +        public void SaveToStg(StgNode node)
 +        {
 +            //​Сохраняем значения в узел
 +            //​Сохраняем массив с указанием типа значений
 +            var array = node.AddArray("​Points",​ StgType.Node);​
 +            for (int i = 0; i < m_Points.Count;​ i++)
 +            {
 +                m_Points[i].SaveToStg(array.AddNode());​
 +            }
 +        }
 +    }
 +</​code>​
 +
 +Дополнительно создадим сервисный класс, реализующий отображение списка точек и поместим его в файл PointsDrawer.cs:​
 +<code csharp>
 +    //​Сервисный класс для отрисовки точек
 +    static class PointsDrawer
 +    {
 +        //​Функция рисующая список точек при помощи pen
 +        public static void PaintPoints(CadPen pen, Points points, bool enabled)
 +        {
 +            //​рисуем нашу линию жёлтым цветом
 +            pen.Color = Color.Yellow;​
 +            //​Начинаем рисовать
 +            pen.BeginDraw();​
 +            try
 +            {
 +                //для отрисовки используем возможность нарисовать массив нескольких точек
 +                //Для этого вызываем начало отрисовки массива
 +                pen.BeginArray();​
 +                for (int i = 0; i < points.Count;​ i++)
 +                {
 +                    //​Добавляем точки
 +                    pen.Vertex(points[i]);​
 +                }
 +                //​Заканчиваем отрисовку массива,​ в виде линии
 +                pen.EndArray(ArrayMode.Polyline);​
 +            }
 +            finally
 +            {
 +                //​заканчиваем рисовать
 +                pen.EndDraw();​
 +            }
 +            //в каждой точке пишем номер оранжевым цветом
 +            pen.Color = Color.Orange;​
 +            //​начинаем рисовать
 +            pen.BeginDraw();​
 +            try
 +            {
 +                var font = FontManager.Current.DefaultFont;​
 +                for (int i = 0; i < points.Count;​ i++)
 +                {
 +                    //​пишем номер точки, высотой в 2 еденицы чертежа
 +                    font.DrawString(i.ToString(),​ pen, points[i], 0.0, 2.0);
 +                }
 +            }
 +            finally
 +            {
 +                //​заканчиваем рисовать
 +                pen.EndDraw();​
 +            }
 +        }
 +    }
 +</​code>​
 +
 +Реализуем нашего наследника от [[developers:​references:​topomatic.cad.view.selectionset|SelectionSet]] и разместим его в файле ModelLayerSelectionSet.cs:​
 +
 +<code csharp>
 +    class ModelLayerSelectionSet : SelectionSet
 +    {
 +        //​Список выделенных объектов
 +        private List<​object>​ m_Selected = new List<​object>​();​
 +
 +        public ModelLayerSelectionSet(ModelLayer layer) ​
 +            : base(layer)
 +        {
 +        }
 +
 +        //​Количество выделенных объектов
 +        public override int Count
 +        {
 +            get
 +            {
 +                return m_Selected.Count;​
 +            }
 +        }
 +
 +        //​Метод очищает выделенные объекты
 +        public override void Clear()
 +        {
 +            m_Selected.Clear();​
 +        }
 +
 +        //​Метод удалет выделенные объекты из модели
 +        public override void Erase()
 +        {
 +            var model_layer = (ModelLayer)Layer;​
 +            for (int i = 0; i < m_Selected.Count;​ i++)
 +            {
 +                model_layer.Model.Remove((Points)m_Selected[i]);​
 +            }
 +            Clear();
 +        }
 +        ​
 +        //​Возвращаем выделенные объекты
 +        public override IEnumerator GetEnumerator()
 +        {
 +            return m_Selected.GetEnumerator();​
 +        }
 +
 +        //​Последний опрошенный элемент списка,​ необходим для работы GetObjectsAtPoint
 +        private int m_LastSearchIndex = 0;
 +
 +        //​Метод возвращает список объектов находящихся в выделенной точке и расстояние до них
 +        //В данном примере функция реализована с поддержкой таймаута
 +        public override IEnumerable<​KeyValuePair<​double,​ object>>​ GetObjectsAtPoint(Vector3D point, Predicate<​object>​ match, int waitTimeOut)
 +        {
 +            //​Создаем список объектов
 +            var list = new List<​KeyValuePair<​double,​ object>>​();​
 +            var model_layer = (ModelLayer)Layer;​
 +            //​Проверяем видимый ли слой и есть ли у него модель
 +            if (model_layer.ResolveVisible() && (model_layer.Model != null))
 +            {
 +                //​Запоминаем время начала работы функции
 +                var t = Environment.TickCount;​
 +                int result = -1;
 +                var model = model_layer.Model;​
 +                //​Формируем вокруг точки прямоугольник зависящий от текущего масштаба видового экрана
 +                var rect = Layer.CadView.MakeSearchRectangle(point);​
 +                //​Создаем контекст отрисовки,​ для проверки попадания объекта в рамку
 +                var dc = new NullDeviceContext(Layer.CadView,​ true);
 +                dc.BeginRender();​
 +                try
 +                {
 +                    //​Назначаем в качестве рамки полученный ранее прямоугольник
 +                    dc.SetClipRect(rect);​
 +                    var count = model.Count;​
 +                    //​Поиск начинаем не с начала списка,​ а с последнего опрошенного элемента
 +                    var lastSearch = m_LastSearchIndex;​
 +                    for (int i = count - 1; i >= 0; i--)
 +                    {
 +                        var index = (i + lastSearch) % count;
 +                        if (result == -1)
 +                        {
 +                            //Если пока элемены не найдены,​ то запоминаем текущий элемент списка в качестве последнего опрошенного
 +                            m_LastSearchIndex = index;
 +                        }
 +                        var obj = model[index];​
 +                        //​Проверяем объект на соответствие нашему предикату
 +                        if ((match == null) || (match(obj)))
 +                        {
 +                            //​Рисуем точки
 +                            PointsDrawer.PaintPoints(dc.Pen,​ obj, true);
 +                            //Если нарисованные точки пересекают рамку или находятся в ней
 +                            if (dc.Found)
 +                            {
 +                                //То запоминаем расстояние и текущий индекс элемента
 +                                var distance = Math.Sqrt(dc.DistanceSquared);​
 +                                result = index;
 +                                //В качестве последнего опрошенного ставим следующий элемент
 +                                m_LastSearchIndex = index + 1;
 +                                //​Добавляем расстояние и объект в список
 +                                list.Add(new KeyValuePair<​double,​ object>​(distance,​ obj));
 +                            }
 +                            //​Выставляем флаг обратно
 +                            dc.Found = false;
 +                        }
 +                        //Если наш таймаут не 0 и время выполнения функции превышено - выходим из функции
 +                        if ((waitTimeOut != 0) && (Environment.TickCount - t > waitTimeOut))
 +                        {
 +                            break;
 +                        }
 +                    }
 +                }
 +                finally
 +                {
 +                    dc.EndRender();​
 +                }
 +            }
 +            //​Возвращаем список объектов
 +            return list;
 +        }
 +
 +        //​Метод возвращает список объектов внутри рамки выделения
 +        //​Возможны два типа рамки:
 +        //  Topomatic.Cad.View.Hints.FrameSelectType.Contains - объект должен целиком находится внтури рамки
 +        //  Topomatic.Cad.View.Hints.FrameSelectType.Intersects - объект либо нахдится целиком внутри рамки, либо пересекает её
 +        public override void GetObjectsByFrame(FrameSelectType mode, RectangleD rect, Predicate<​object>​ match, Action<​object>​ action)
 +        {
 +            var model_layer = (ModelLayer)Layer;​
 +            //​Проверяем видимый ли слой и есть ли у него модель
 +            if (model_layer.ResolveVisible() && (model_layer.Model != null))
 +            {
 +                var model = model_layer.Model;​
 +                //​Проверяем тип рамки
 +                if (mode == Topomatic.Cad.View.Hints.FrameSelectType.Contains)
 +                {
 +                    //​используем FullDeviceContext для проверки попадания объекта в рамку целиком
 +                    var dc = new FullDeviceContext(Layer.CadView);​
 +                    dc.BeginRender();​
 +                    try
 +                    {
 +                        //​устанавливаем рамку
 +                        dc.SetClipRect(rect);​
 +                        for (int i = 0; i < model.Count;​ i++)
 +                        {
 +                            var obj = model[i];
 +                            //​Проверяем объект на соответствие нашему предикату
 +                            if ((match == null) || (match(model)))
 +                            {
 +                                //​Устанавливаем флаг полностью нарисован
 +                                dc.FullDrawn = true;
 +                                //​Рисуем объект
 +                                PointsDrawer.PaintPoints(dc.Pen,​ obj, true);
 +                                //Если объект полностью нарисован и нарисован полностью
 +                                if ((dc.FullDrawn) && (dc.Drawn))
 +                                {
 +                                    if (action != null)
 +                                    {
 +                                        //То выполняем метод для этого объекта
 +                                        action(obj);​
 +                                    }
 +                                }
 +                                //​Сбрасываем флаг отрисовки
 +                                dc.Drawn = false;
 +                            }
 +                        }
 +                    }
 +                    finally
 +                    {
 +                        dc.EndRender();​
 +                    }
 +                }
 +                if (mode == Topomatic.Cad.View.Hints.FrameSelectType.Intersects)
 +                {
 +                    //​используем NullDeviceContext для проверки попадания объекта в рамку или пересечения с ней
 +                    var dc = new NullDeviceContext(Layer.CadView,​ false);
 +                    dc.BeginRender();​
 +                    try
 +                    {
 +                        //​устанавливаем рамку
 +                        dc.SetClipRect(rect);​
 +                        for (int i = 0; i < model.Count;​ i++)
 +                        {
 +                            var obj = model[i];
 +                            //​Проверяем объект на соответствие нашему предикату
 +                            if ((match == null) || (match(model)))
 +                            {
 +                                //​Рисуем объект
 +                                PointsDrawer.PaintPoints(dc.Pen,​ obj, true);
 +                                //Если нарисованные точки пересекают рамку или находятся в ней
 +                                if (dc.Found)
 +                                {
 +                                    if (action != null)
 +                                    {
 +                                        //То выполняем метод для этого объекта
 +                                        action(obj);​
 +                                    }
 +                                }
 +                                //​Сбрасываем флаг отрисовки
 +                                dc.Found = false;
 +                            }
 +                        }
 +                    }
 +                    finally
 +                    {
 +                        dc.EndRender();​
 +                    }
 +                }
 +            }
 +        }
 +
 +        //​Метод зарезервирован для будущего использования и пока не поддерживается. Реализация не требуется.
 +        public override void GetObjectsByPolygon(FrameSelectType mode, List<​Vector2D>​ pointsList, Predicate<​object>​ match, Action<​object>​ action)
 +        {
 +            throw new NotSupportedException();​
 +        }
 +
 +        //​Возвращаем список всех элементов,​ которые можно выделить
 +        public override IEnumerable GetSelectable()
 +        {
 +            var model_layer = (ModelLayer)Layer;​
 +            for (int i = 0; i < model_layer.Model.Count;​ i++)
 +            {
 +                yield return model_layer.Model[i];​
 +            }
 +        }
 +
 +        //​Проверяем включен ли наш объект. В нашем случае всегда включен если включен слой
 +        public override bool IsEnable(object obj)
 +        {
 +            if (IsOwned(obj))
 +                return true;
 +            return Layer.ResolveEnable();​
 +        }
 +
 +        //​Проверям принадлежит ли объект нашему SelectionSet
 +        public override bool IsOwned(object obj)
 +        {
 +            //​Приводим объект к типу
 +            var points = obj as Points;
 +            if (points != null)
 +            {
 +                //И проверяем что модель равна модели нашего слоя
 +                return ((ModelLayer)Layer).Model == points.Owner;​
 +            }
 +            return false;
 +        }
 +
 +        //​Проверяем,​ выделен ли объект
 +        public override bool IsSelected(object obj)
 +        {
 +            return m_Selected.Contains(obj);​
 +        }
 +
 +        //​Выделяем или снимаем выделение с объекта
 +        public override void Select(object item, bool bFlag)
 +        {
 +            //​Провеяем выделен ли наш объект
 +            var selected = IsSelected(item);​
 +            if (bFlag)
 +            {
 +                //Если нужно выделить и он не выделен - выделяем
 +                if (!selected)
 +                    m_Selected.Add(item);​
 +            }
 +            else
 +            {
 +                //Если нужно убрать выделение и он выделен - убираем выделение
 +                if (selected)
 +                    m_Selected.Remove(item);​
 +            }
 +        }
 +    }
 +</​code>​
 +
 +В реализацию слоя модели,​ расположенного в файле ModelLayer.cs,​ необходимо внести следующие изменения.
 +На конструкторе создаем экземпляра класса,​ наследника от [[developers:​references:​topomatic.cad.view.selectionset|SelectionSet]],​ меняем реализации функций **OnPaint** и **OnGetLimits**. Также перекрываем функции **OnHilightObject** и **OnDynamicDraw** - для реализации подсветки и отображения выделенных элементов.
 +
 +<code csharp>
 +        ...
 +        public ModelLayer()
 +        {
 +            //в качестве класса,​ отвечающего за выделение объектов мы используем ModelLayerSelectionSet
 +            m_SelectionSet = new ModelLayerSelectionSet(this);​
 +        }
 +        ...
 +        ​
 +        protected override bool OnGetLimits(out BoundingBox2D limits)
 +        {
 +            bool init = false;
 +            limits = BoundingBox2D.Empty;​
 +            for (int i = 0; i < m_Model.Count;​ i++)
 +            {
 +                var points = m_Model[i];
 +                for (int j = 0; j < points.Count;​ j++)
 +                {
 +                    var v = points[j];
 +                    if (init)
 +                    {
 +                        limits.AddPoint(v);​
 +                    }
 +                    else
 +                    {
 +                        limits = new BoundingBox2D(v,​ v);
 +                        init = true;
 +                    }
 +                }
 +            }
 +            return init;
 +        }
 +        ...
 +        //​Отрисовка модели
 +        protected override void OnPaint(CadPen pen)
 +        {
 +            for (int i = 0; i < m_Model.Count;​ i++)
 +            {
 +                PointsDrawer.PaintPoints(pen,​ m_Model[i], ResolveEnable());​
 +            }
 +        }
 +        ...
 +        //​Отрисовка подсвеченных объектов
 +        protected override void OnHilightObject(CadPen pen, object obj)
 +        {
 +            base.OnHilightObject(pen,​ obj);
 +            //Если объект это наши точки
 +            var points = obj as Points;
 +            if (points != null)
 +            {
 +                //То включаем режим подсветки
 +                pen.DrawingMode = DrawingMode.Highlight;​
 +                pen.HighlightMode = HighlightMode.DoubleBlack;​
 +                //​Рисуем точки
 +                PointsDrawer.PaintPoints(pen,​ points, ResolveEnable());​
 +                pen.Reset();​
 +            }
 +        }
 +        ...
 +        //​Динамическая отрисовка слоя
 +        protected override void OnDynamicDraw(CadPen pen, Vector3D location)
 +        {
 +            base.OnDynamicDraw(pen,​ location);
 +            //Если есть выбранные элементы
 +            if (m_SelectionSet.Count > 0)
 +            {
 +                //​Необходимо нарисовать все выбранные элементы
 +                foreach (var obj in m_SelectionSet)
 +                {
 +                    var points = obj as Points;
 +                    if (points != null)
 +                    {
 +                        //​Рисуем элементы подсвеченными
 +                        pen.HighlightMode = HighlightMode.Black;​
 +                        PointsDrawer.PaintPoints(pen,​ points, ResolveEnable());​
 +                        pen.Reset();​
 +                    }
 +                }
 +            }
 +        }                ​
 +        ...
 +</​code>​
 +
 +В результате мы получим возможность по команде «Редактировать активную модель» добавлять новые полилинии с точками, ​ а также выделять и подсвечивать их на видовом экране.
 +
 +{{ :​developers:​tutorial:​selectionset:​selectionset_result.png?​direct&​600 |}}
 +
 +<​note>​[[developers:​tutorial:​tutorialcode|Исходный код]] примера расположен в проекте **"​tutorial8"​**.</​note>​
developers/tutorial/selectionset.1552229972.txt.gz · Последние изменения: 2021/07/22 14:28 (внешнее изменение)