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 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 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().Cast(); 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() .Any(param => paramNames.Contains(param.Definition.Name)); bool typeFlag = false; if (hasTypeId) { typeFlag = type.ParametersMap.OfType() .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 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) { } } } }