Всем привет. Пытаюсь обрабатывать элементы в группах по схеме:
- разгруппировать
- обработать
- создать группы
Но Ревит себя как-то странно ведет или я ничего не понимаю.
Вот так выглядит метод:
private void NumerateInGroups(List<ElInGroup> elementsInGroups, Document doc)
{
var transactionName = Language.GetFunctionLocalName(LangItem, new ModPlusConnector().LName);
if (string.IsNullOrEmpty(transactionName))
transactionName = LangItem;
using (TransactionGroup transactionGroup = new TransactionGroup(doc))
{
transactionGroup.Start($"{transactionName}: Groups");
foreach (IGrouping<string, ElInGroup> grouping in elementsInGroups.GroupBy(e => e.GroupName))
{
List<List<ElementId>> elements = new List<List<ElementId>>();
// ungroup and delete
Transaction transaction = new Transaction(doc);
transaction.Start("Ungroup");
foreach (ElInGroup elInGroup in grouping)
{
var group = (Group)doc.GetElement(new ElementId(elInGroup.GroupId));
var grpElements = group.UngroupMembers().ToList();
elements.Add(grpElements);
}
transaction.Commit();
transaction.Start("Numerate");
foreach (ElInGroup elInGroup in grouping)
{
foreach (var pair in elInGroup.Elements)
{
if (pair.Key.LookupParameter(_parameterName) is Parameter parameter)
{
parameter.Set(pair.Value);
}
}
}
transaction.Commit();
transaction.Start("Create new group");
foreach (List<ElementId> elementIds in elements)
{
Group newGroup = doc.Create.NewGroup(elementIds);
newGroup.GroupType.Name = grouping.Key;
}
transaction.Commit();
//foreach (List<ElementId> elementIds in elements)
//{
// transaction.Start("Create new group");
// Group newGroup = doc.Create.NewGroup(elementIds);
// var groupType = new FilteredElementCollector(doc)
// .OfClass(typeof(GroupType))
// .Cast<GroupType>()
// .FirstOrDefault(g => g.Name == grouping.Key);
// if (groupType != null)
// newGroup.GroupType = groupType;
// else newGroup.GroupType.Name = grouping.Key;
// transaction.Commit();
//}
transaction.Dispose();
}
transactionGroup.Assimilate();
}
}
Вспомогательный класс:
internal class ElInGroup
{
public ElInGroup(Group group)
{
GroupId = group.Id.IntegerValue;
GroupName = group.Name;
}
public int GroupId { get; }
public string GroupName { get; set; }
public Dictionary<Element, string> Elements { get; } = new Dictionary<Element, string>();
}
Сначала список своих объектов я группирую по имени группы. Это я делаю для того, чтобы в рамках одной транзакции обрабатывать все экземпляры групп одного типа.
Потом разгруппировываю. Затем меняю нужный мне параметр, а затем создаю новые группы.
Так вот если я использую первый вариант:
transaction.Start("Create new group");
foreach (List<ElementId> elementIds in elements)
{
Group newGroup = doc.Create.NewGroup(elementIds);
newGroup.GroupType.Name = grouping.Key;
}
transaction.Commit();
то все хорошо за исключением одного но: Ревит создает несколько типов групп с одинаковым именем
![](https://i.postimg.cc/z3X7fP1M/Screenshot-16.png)
Если я использую второй вариант:
foreach (List<ElementId> elementIds in elements)
{
transaction.Start("Create new group");
Group newGroup = doc.Create.NewGroup(elementIds);
var groupType = new FilteredElementCollector(doc)
.OfClass(typeof(GroupType))
.Cast<GroupType>()
.FirstOrDefault(g => g.Name == grouping.Key);
if (groupType != null)
newGroup.GroupType = groupType;
else newGroup.GroupType.Name = grouping.Key;
transaction.Commit();
}
то во-первых я начинаю ловить непонятные warning'ы, а во-вторых Ревит создает группы с другим именем:
![](https://i.postimg.cc/Xr3pVmRB/Screenshot-17.png)
При этом вишенка на торте - эти типы групп не имеют экземпляров групп! Т.е. свойство GroupSet пустое. А нужный мне тип группы (Группа массива 1) имеет все нужные мне 5 экземпляров.
Конечно можно попробовать перед вызовом метода запомнить какие были группы, а после работы метода получить новые группы и удалить пустые, но хотелось бы разобраться что не так.
Что я упускаю?