Files
SzmediTools/Szmedi.RvKits/InfoManager/PropEditor/RemoveParametersViewModel.cs
2025-09-16 16:06:41 +08:00

265 lines
14 KiB
C#

using System.Linq;
using System.Text;
using System.Windows;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Nice3point.Revit.Toolkit.External.Handlers;
namespace Szmedi.RvKits.InfoManager
{
public partial class RemoveParametersViewModel : ObservableObject
{
public partial class ParamToRemoveModel : ObservableObject
{
[ObservableProperty]
private bool isSelected;
[ObservableProperty]
private string propertyName;
public bool IsType { get; set; } = false;
}
[ObservableProperty]
private bool isSelectedItems;
readonly ActionEventHandler handler;
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(RemoveParamsCommand))]
private List<ParamToRemoveModel> items;
private readonly UIDocument uiDocument;
private bool CanRemove => Items?.Count > 0;
public RemoveParametersViewModel(UIDocument uiDocument)
{
this.uiDocument = uiDocument;
handler = new ActionEventHandler();
}
[RelayCommand(CanExecute = nameof(CanRemove))]
private void RemoveParams()
{
handler.Raise(
uiapp =>
{
var uidoc = uiapp.ActiveUIDocument;
var doc = uidoc.Document;
List<Element> elements = null;
StringBuilder sb = new();
if (IsSelectedItems)
{
elements = [.. uidoc.GetSelectedElems()
.Where(e => e.GetTypeId() != ElementId.InvalidElementId)
.GroupBy(e => e.GetTypeId())
.Select(e => e.FirstOrDefault())];
}
else
{
elements = [.. doc.OfAllModelCollector()?
.GroupBy(e => e.GetTypeId())
.Select(e => e.FirstOrDefault())];
}
if (elements == null || elements.Count == 0)
{
MessageBox.Show("没有找到模型元素", "错误");
return;
}
doc.InvokeGroup(
_ =>
{
foreach (var element in elements)
{
var paramNames = Items.Where(m => m.IsSelected).Select(m => m.PropertyName);
var dict = SharedParameterAssists.GetParameterElementBindings(doc);
var bindings = doc.ParameterBindings;
var parameterElements = doc.OfClass<ParameterElement>().Cast<ParameterElement>();
StringBuilder sb = new StringBuilder();
Element type = null;
var hasTypeId = element.GetTypeId() != ElementId.InvalidElementId;
if (hasTypeId)
{
type = doc.GetElement(element.GetTypeId());
}
doc.Invoke(
ts =>
{
//实例参数
foreach (Parameter param in element.ParametersMap)
{
if (paramNames.Contains(param.Definition.Name))
{
var ds = dict.Where(
e => e.Key.GetDefinition().Id == (param.Definition as InternalDefinition)?.Id);
if (ds.Any())//说明是项目参数
{
var d = ds.FirstOrDefault();
var parameter = d.Key;
var binding = d.Value;
if (binding.Categories.Size == 1)//如果只剩下一个类别,则直接移除
{
if (parameter is SharedParameterElement)//共享参数
{
bindings.Remove(param.Definition);
}
else//项目参数
{
dict.Remove(parameter);
doc.Delete(parameter.Id);
}
}
else//否则只移除一个类别
{
binding.Categories.Erase(element.Category);
doc.ParameterBindings.ReInsert(parameter.GetDefinition(), binding);
}
}
}
}
//类型参数
if (hasTypeId)
{
foreach (Parameter param in type.ParametersMap)
{
if (paramNames.Contains(param.Definition.Name))
{
//var name = param.Definition.Name;
//var defs = dict.Keys.Select(e => e.GetDefinition());
var ds = dict.Where(
e => e.Key.GetDefinition().Id == (param.Definition as InternalDefinition)?.Id);
if (ds.Any())//说明是项目参数
{
var d = ds.FirstOrDefault();
var parameter = d.Key;
var binding = d.Value;
if (binding.Categories.Size == 1)//如果只剩下一个类别,则直接移除
{
if (parameter is SharedParameterElement)//共享参数
{
bindings.Remove(param.Definition);
}
else//项目参数
{
dict.Remove(parameter);
doc.Delete(parameter.Id);
}
}
else
{
binding.Categories.Erase(element.Category);
doc.ParameterBindings.ReInsert(parameter.GetDefinition(), binding);
}
}
}
}
}
}, "清理项目参数");
bool instanceFlag = element.ParametersMap
.OfType<Parameter>()
.Any(param => paramNames.Contains(param.Definition.Name));
bool typeFlag = false;
if (hasTypeId)
{
typeFlag = type.ParametersMap.OfType<Parameter>()
.Any(param => paramNames.Contains(param.Definition.Name));
}
var NeedToEditFamily = instanceFlag || typeFlag;
if (NeedToEditFamily && element is FamilyInstance instance)
{
Document famdoc = null;
try
{
Family family = instance.Symbol.Family;
if (family.IsEditable)
{
famdoc = doc.EditFamily(family);
}
else
{
sb.AppendLine($"{family.Name} 不可编辑。");
}
if (famdoc != null)
{
using (Transaction ts = new(famdoc, "删除参数"))
{
ts.Start();
var parametersToRemove = famdoc.FamilyManager
.GetParameters()
.Where(fp => paramNames.Contains(fp.Definition.Name));
foreach (FamilyParameter fp in parametersToRemove)
{
famdoc.FamilyManager.RemoveParameter(fp);
}
ts.Commit();
}
famdoc.LoadFamily(doc, new FamilyLoadOption());
famdoc.Close(false);
}
}
catch (Exception)
{
sb.AppendLine($"{famdoc.Title} 发生错误!");
}
}
if (sb.Length > 0)
{
MessageBox.Show(sb.ToString());
}
}
}, "参数移除");
if (sb.Length > 0)
{
MessageBox.Show(sb.ToString(), "错误", MessageBoxButton.OK, MessageBoxImage.Warning);
}
});
}
[RelayCommand]
private void GetParams()
{
Items = null;
List<ParamToRemoveModel> models = [];
var doc = uiDocument.Document;
try
{
var reference = uiDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "请选择提取参数的元素");
var elem = doc.GetElement(reference);
if (elem == null)
{
return;
}
foreach (Parameter param in elem.Parameters)
{
var definition = param.Definition as InternalDefinition;
if (param.IsShared || definition.BuiltInParameter == BuiltInParameter.INVALID)
{
models.Add(new ParamToRemoveModel() { IsSelected = true, PropertyName = param.Definition.Name });
}
}
if (elem.GetTypeId() != ElementId.InvalidElementId)
{
var type = doc.GetElement(elem.GetTypeId());
foreach (Parameter param in type.Parameters)
{
var definition = param.Definition as InternalDefinition;
if (param.IsShared || definition.BuiltInParameter == BuiltInParameter.INVALID)
{
models.Add(new ParamToRemoveModel() { IsSelected = true, PropertyName = param.Definition.Name, IsType = true });
}
}
}
Items = [.. models.OrderBy(m => m.PropertyName)];
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException) { }
}
}
}