Files
ShrlAlgoToolkit/ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersViewModel.cs
2026-02-24 11:34:18 +08:00

358 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using Autodesk.Revit.DB;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Win32;
using MiniExcelLibs.Attributes;
using Nice3point.Revit.Toolkit.External.Handlers;
using ShrlAlgoToolkit.RevitAddins.Common.Assists;
using ShrlAlgoToolkit.RevitAddins.Common.Extensions;
namespace ShrlAlgoToolkit.RevitAddins.Standardizer;
public partial class WriteParametersViewModel : ObservableObject
{
public WriteParametersViewModel(UIDocument uIDocument)
{
this.uiDocument = uIDocument;
}
private readonly ActionEventHandler handler = new();
[ObservableProperty]
private bool isSelectedItems;
[ObservableProperty]
private bool isOverride;
//record class ParameterModel(string Name, object Value);
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(ExportExcelCommand))]
[NotifyCanExecuteChangedFor(nameof(WriteParamsCommand))]
private List<ParameterModel> items;
[ObservableProperty]
private string excelPath;
private readonly UIDocument uiDocument;
private bool HasItems => Items?.Any() == true;
[RelayCommand]
private void GetParams()
{
Items = null;
List<ParameterModel> models = [];
Document doc = uiDocument.Document;
try
{
Reference reference = uiDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "请选择提取参数的元素");
Element elem = doc.GetElement(reference);
foreach (Parameter param in elem.Parameters)
{
if (!param.HasValue || string.IsNullOrEmpty(param.AsString()))
{
models.Add(new ParameterModel() { Name = param.Definition.Name });
}
}
Items = models.OrderBy(m => m.Name).ToList();
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException) { }
}
[RelayCommand]
private void OpenExcel()
{
if (ExcelPath.StartsWith("\""))
{
ExcelPath = ExcelPath.TrimStart('\"');
}
if (ExcelPath.EndsWith("\""))
{
ExcelPath = ExcelPath.TrimEnd('\"');
}
if (File.Exists(ExcelPath))
{
FileInfo file = new(ExcelPath);
if (file.Extension != ".xlsx")
{
MessageBox.Show("请选择xlsx格式的Excel文件");
}
else
{
ReadExcel(ExcelPath);
}
}
else
{
MessageBox.Show("文件路径有误");
}
}
[RelayCommand(CanExecute = nameof(HasItems))]
private void ExportExcel()
{
SaveFileDialog dialog =
new()
{
Filter = "Excel文件(xlsx)|*.xlsx",
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
};
if (dialog.ShowDialog() != true)
{
return;
}
string excel = dialog.FileName;
FileInfo fi = new(excel);
Dictionary<string, object> data = new() { { "参数表", Items } };
data.SaveAsExcel(excel);
MessageBoxResult result = MessageBox.Show("是否打开Excel表", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
Process.Start(excel);
}
}
[RelayCommand(CanExecute = nameof(HasItems))]
private void WriteParams()
{
Document doc = uiDocument.Document;
List<Element> elements = IsSelectedItems
? uiDocument.Selection.GetElementIds().Select(id => doc.GetElement(id)).ToList()
: new FilteredElementCollector(doc, doc.ActiveView.Id)
.WhereElementIsNotElementType()
.ToElements()
.Where(
e =>
e.CanHaveTypeAssigned()
&& e.HasPhases()
&& e.get_BoundingBox(doc.ActiveView) != null
&& e.Category is { Parent: null, CategoryType: CategoryType.Model }
)
.ToList();
StringBuilder sb = new();
handler.Raise(_ =>
{
using (TransactionGroup transG = new(doc, "填写属性值"))
{
transG.Start();
foreach (Element elem in elements)
{
if (!elem.IsValidObject)
{
continue;
}
using Transaction trans = new(doc, "填写属性值");
//FailureHandlingOptions options = trans.GetFailureHandlingOptions();
//FailuresPreProcessor failuresProcessor = new();
//options.SetFailuresPreprocessor(failuresProcessor);
//trans.SetFailureHandlingOptions(options);
trans.Start();
Regex regex = new(@"^\D{2}-\d00");
//将“”空值填写“/”
foreach (Parameter parameter in elem.Parameters)
{
//if (parameter.Definition.Name == "ID-100-编号")
//{
// continue;
//}
//不为空时,跳过设置“/”
if (!(string.IsNullOrEmpty(parameter.AsString()) && string.IsNullOrEmpty(parameter.AsValueString())))
{
continue;
}
if (regex.IsMatch(parameter.Definition.Name) && !parameter.IsReadOnly)
{
if (parameter.StorageType is StorageType.Integer or StorageType.Double)
{
parameter.Set(0);
}
if (parameter.StorageType == StorageType.String)
{
parameter.Set("/");
}
}
}
doc.Regenerate();
//填写表单中的数据
foreach (ParameterModel item in Items)
{
Parameter p1 = elem.GetParameters(item.Name).FirstOrDefault();
if (p1 == null)
{
sb.AppendLine($"构件类别:{elem.Category};构件名:{elem.Name}构件ID{elem.Id};参数名:{item.Name};异常原因:参数不存在");
continue;
}
//if (p1.Definition.Name == "ID-100-编号")
//{
// continue;
//}
try
{
if (
IsOverride
|| (p1.AsString() == "/" || p1.AsValueString() == "/")
|| (p1.AsString() == "0" || p1.AsValueString() == "0")
) //如果覆盖则填写,否则不操作
{
if (p1?.IsReadOnly == false)
{
switch (p1.StorageType)
{
case StorageType.None:
break;
case StorageType.Integer:
p1.Set(Convert.ToInt16(item.Value));
break;
case StorageType.Double:
p1.Set(Convert.ToDouble(item.Value));
break;
case StorageType.String:
p1.Set(Convert.ToString(item.Value));
break;
case StorageType.ElementId:
break;
}
}
}
//if (p1?.IsReadOnly == false)
//{
// switch (p1.StorageType)
// {
// case StorageType.None:
// break;
// case StorageType.Integer:
// p1.Set(Convert.ToInt16(item.Value));
// break;
// case StorageType.Double:
// p1.Set(Convert.ToDouble(item.Value));
// break;
// case StorageType.String:
// p1.Set(Convert.ToString(item.Value));
// break;
// case StorageType.ElementId:
// break;
// }
//}
}
catch (Exception exception)
{
sb.AppendLine(
$"构件类别:{elem.Category};构件名:{elem.Name}构件ID{elem.Id};参数名:{p1.Definition.Name};异常原因:{exception.Message}"
);
}
}
trans.Commit();
}
transG.Assimilate();
}
if (sb.Length > 0)
{
LogAssist.WriteTextFile( sb.ToString(), "修改异常问题");
}
MessageBox.Show("修改参数完成!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
});
}
[RelayCommand]
private void BrowserExcelFile()
{
OpenFileDialog dialog =
new()
{
CheckFileExists = true,
Filter = "Excel文件(*.xlsx)|*.xlsx",
Multiselect = false,
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
};
if (dialog.ShowDialog() != true)
{
return;
}
//Items?.Clear();
ExcelPath = dialog.FileName;
ReadExcel(dialog.FileName);
}
private void ReadExcel(string path)
{
Items= [.. path.ReadExcel<ParameterModel>()];
}
private static Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args)
{
if (!args.Name.Contains("ComponentModel.Annotations"))
{
return null;
}
string assemblyFile = Path.Combine(Variables.DirAssembly, "System.ComponentModel.Annotations.dll");
return File.Exists(assemblyFile) ? Assembly.LoadFrom(assemblyFile) : null;
}
[RelayCommand]
private void Init(int index)
{
if (index == 0)
{
Items = GetInitCivilParameterList();
}
else
{
Items = index == 1 ? GetInitMEPParameterList() : null;
}
}
private List<ParameterModel> GetInitCivilParameterList()
{
return
[
new() { Name = "AM-200-模型权属单位", Value = "深圳市地铁集团有限公司" },
new() { Name = "AM-200-资产权属单位", Value = "深圳市地铁集团有限公司" },
new() { Name = "CM-100-创建单位", Value = "深圳市市政设计研究院有限公司" },
new() { Name = "ID-200-BIM对象分类编码执行标准", Value = "《城市轨道交通工程信息模型分类和编码标准》SJG102" },
new() { Name = "CM-100-校审单位", Value = "数云科际(深圳)技术有限公司" },
new() { Name = "FM-200-产品寿命", Value = "100" },
new() { Name = "FM-200-使用年限", Value = "100" },
new() { Name = "TC-400-设计使用年限", Value = "100" }
];
}
private List<ParameterModel> GetInitMEPParameterList()
{
return
[
new() { Name = "AM-200-模型权属单位", Value = "深圳市地铁集团有限公司" },
new() { Name = "AM-200-资产权属单位", Value = "深圳市地铁集团有限公司" },
new() { Name = "CM-100-创建单位", Value = "深圳市市政设计研究院有限公司" },
new() { Name = "CM-100-校审单位", Value = "深圳市市政设计研究院有限公司" },
new() { Name = "CM-100-创建人及联系方式", Value = "/" },
];
}
}
public class ParameterModel
{
[ExcelColumn(Name="参数名")]
public string Name { get; set; }
[ExcelColumn(Name ="参数值")]
public string Value { get; set; }
}