using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
namespace CustomCADSupport
{
public class CustomSelectionClass
{
[CommandMethod("TestSelectPlines", CommandFlags.UsePickSet | CommandFlags.Redraw | CommandFlags.Modal)]
public void SelectPlinesRun()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
PromptSelectionOptions selOpt = new PromptSelectionOptions();
selOpt.MessageForAdding = "\nВыберите полилинии: ";
// Производим выбор объектов собственным методом
PromptSelectionResult selRes = ed.SelectObjectsWithFilter(selOpt, ObjectIsPline);
if (selRes.Status != PromptStatus.OK)
ed.WriteMessage("\nНичего не выбрано!");
else
{
ed.WriteMessage("\nВыбрано полилиний: {0} шт.", selRes.Value.Count);
ed.SetImpliedSelection(selRes.Value.GetObjectIds());
}
}
/// <summary>
/// Метод проверки, является ли объект полилинией
/// </summary>
/// <param name="objId">Id объекта</param>
/// <returns>True - объект является полилинией, false - не является</returns>
bool ObjectIsPline(ObjectId objId)
{
bool retVal;
Database db = objId.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
DBObject obj = tr.GetObject(objId, OpenMode.ForRead);
retVal = obj is Polyline || obj is Polyline2d || obj is Polyline3d;
tr.Commit();
}
return retVal;
}
}
public static class SelectionMethods
{
/// <summary>
/// переменная для передачи метода проверки в метод отклика на выбор объектов
/// </summary>
static Func<ObjectId, bool> _filterObjectMethod;
/// <summary>
/// Выбор объектов на чертеже с учетом предварительного выбора и с использованием фильтра
/// </summary>
/// <param name="ed">Редактор документа</param>
/// <param name="selOpt">Опции выбора</param>
/// <param name="filterObjectMethod">
/// Метод фильтрации.
/// Принимает один аргумент - ID объекта чертежа.
/// Возвращает true если объект прошел проверку и false - если не прошел
/// </param>
/// <returns>Результат выбора - объект PromptSelectionResult</returns>
public static PromptSelectionResult SelectObjectsWithFilter(this Editor ed, PromptSelectionOptions selOpt, Func<ObjectId, bool> filterObjectMethod)
{
_filterObjectMethod = filterObjectMethod;
Database db = ed.Document.Database;
// Обработка предварительного выбора
PromptSelectionResult selRes = ed.SelectImplied();
List<ObjectId> trueObjIds = new List<ObjectId>();
if (selRes.Status == PromptStatus.OK)
{
foreach (ObjectId objId in selRes.Value.GetObjectIds())
{
if (_filterObjectMethod(objId)) trueObjIds.Add(objId);
}
}
if (trueObjIds.Count > 0)
{
ed.SetImpliedSelection(trueObjIds.ToArray());
selRes = ed.SelectImplied();
// Обнуляем предвыбор
ed.SetImpliedSelection(new ObjectId[0]);
}
else
{
SelectionAddedEventHandler selHandler = new SelectionAddedEventHandler(ed_SelectionAdded);
ed.SelectionAdded += selHandler;
selRes = ed.GetSelection(selOpt);
ed.SelectionAdded -= selHandler;
}
return selRes;
}
/// <summary>
/// Метод фильтрации выбираемых с помощью GetSelection объектов в режиме реального времени
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void ed_SelectionAdded(object sender, SelectionAddedEventArgs e)
{
ObjectId[] selIds = e.AddedObjects.GetObjectIds();
for (int i = 0; i < selIds.Length; i++)
{
if (!_filterObjectMethod(selIds[i])) e.Remove(i);
}
}
}
}