using System.Data; using System.IO; using System.Net; using System.Windows; using System.Windows.Controls; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using HtmlAgilityPack; using Microsoft.Win32; using Nice3point.Revit.Toolkit.External.Handlers; namespace ShrlAlgoToolkit.RevitAddins.RvMEP; public partial class ClashReportViewModel(UIApplication uiapp) : ObservableObject { [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(RevitAddins.RvMEP.ClashReportViewModel.RefreshCommand))] public partial string FilePathName { get; set; } public UIApplication UiApp { get; set; } = uiapp; [ObservableProperty] public partial bool InCurrentView { get; set; } = true; [ObservableProperty] public partial bool IsSetSectionBox { get; set; } public DataTable DataSource { get; set; } = new DataTable(); [ObservableProperty] public partial DataTable CurrentViewItems { get; set; } = new(); [RelayCommand] private void LvScroll(ScrollViewer scrollViewer) { // ReSharper disable once CompareOfFloatsByEqualityOperator if (!isLoadingData && scrollViewer.VerticalOffset + scrollViewer.ViewportHeight == scrollViewer.ExtentHeight)//必须等于 { LoadMoreData(); } } private const int VbBatchSize = 20; private bool isLoadingData; private void LoadInitialData() { isLoadingData = true; CurrentViewItems.Clear(); var size = VbBatchSize; if (DataSource.Rows.Count < VbBatchSize) { size = DataSource.Rows.Count; } for (var i = 0; i < size; i++) { CurrentViewItems.ImportRow(DataSource.Rows[i]); } //CurrentViewItems = CurrentViewItems; isLoadingData = false; } private void LoadMoreData() { isLoadingData = true; var startIndex = CurrentViewItems.Rows.Count; var end = startIndex + VbBatchSize; if (end > DataSource.Rows.Count) { end = DataSource.Rows.Count; } if (startIndex < end + 1) { for (var i = startIndex; i < end; i++) { CurrentViewItems.ImportRow(DataSource.Rows[i]); } } isLoadingData = false; } private void LoadHtmlTableData(string filePath) { var htmlContent = ReadLocalHtmlFile(filePath); DataSource = ParseHtmlToPairs(htmlContent); LoadInitialData(); } //private async Task GetHtmlContent(string url) //{ // try // { // using (HttpClient httpClient = new HttpClient()) // { // HttpResponseMessage response = await httpClient.GetAsync(url); // response.EnsureSuccessStatusCode(); // return await response.Content.ReadAsStringAsync(); // } // } // catch (Exception ex) // { // MessageBox.Show("Error while fetching HTML content: " + ex.ViewMessage); // return null; // } //} private DataTable ParseHtmlToPairs(string html) { DataTable dataTable = new(); try { HtmlDocument doc = new(); doc.LoadHtml(html); var tableNode = doc.DocumentNode.SelectSingleNode("//table"); if (tableNode != null) { var rows = tableNode.SelectNodes("tr"); for (var i = 0; i < rows.Count; i++) { if (i == 0) { var row = rows[i].SelectNodes("td"); foreach (var cell in row) { dataTable.Columns.Add(cell.InnerText == string.Empty ? WebUtility.HtmlDecode("序号") : WebUtility.HtmlDecode(cell.InnerText.Trim())); CurrentViewItems = dataTable.Copy(); } } else { var dataRow = dataTable.NewRow(); var columnIndex = 0; foreach (var cell in rows[i].SelectNodes("td")) { dataRow[columnIndex] = WebUtility.HtmlDecode(cell.InnerText.Trim()); columnIndex++; } dataTable.Rows.Add(dataRow); } } } else { MessageBox.Show("html中未发现表格。"); } } catch (Exception ex) { MessageBox.Show("解析html表格数据时出错:" + ex.Message); return null; } return dataTable; } private string ReadLocalHtmlFile(string filePath) { try { return File.ReadAllText(filePath); } catch (Exception ex) { MessageBox.Show("读取本地html文件时出错:" + ex.Message); return null; } } private readonly ActionEventHandler handler = new(); [RelayCommand] private void Location(object obj) { var rowView = obj as DataRowView; var dr = rowView?.Row; var uidoc = UiApp.ActiveUIDocument; var doc = uidoc.Document; var ids = GetElementIds(dr); uidoc.Selection.SetElementIds(ids); var view = doc.ActiveView; if (!ids.Any()) { return; } if (view is View3D view3D) { handler.Raise(_ => doc.Invoke(ts => { if (IsSetSectionBox) { view = view3D.SectionBoxElements(ids, InCurrentView); ts.Commit(); if (UiApp.ActiveUIDocument.ActiveView.Id != view.Id) { UiApp.ActiveUIDocument.ActiveView = view; } //var box = elem.get_BoundingBox(UiDocument.ActiveGraphicalView); var box = view3D.GetSectionBox(); var uiView = uidoc.GetOpenUIViews().FirstOrDefault(v => v.ViewId == uidoc.ActiveGraphicalView.Id); uiView.ZoomAndCenterRectangle(box.Min, box.Max); } else { view.ZoomElement(uidoc, ids.FirstOrDefault()); } }, "定位碰撞元素")); } //RevitCommandId revitCommandId = RevitCommandId.LookupPostableCommandId(PostableCommand.SelectionBox); //try //{ // uiapp.PostCommand(revitCommandId); //} //catch (Exception) //{ // throw; //} //RevitCommandId.LookupCommandId() //List ids = GetElementIds(dr); //ElementId id = null; //if (uiapp.ActiveUIDocument.Document.GetElement(ids[0]).IsValidObject) //{ // id = ids[0]; //} //else //{ // ids.Remove(ids[0]); // if (uiapp.ActiveUIDocument.Document.GetElement(ids[1]).IsValidObject) // { // id = ids[1]; // } // else // { // ids.Remove(ids[1]); // } //} //if (id != null) //{ // uiapp.ActiveUIDocument.ShowElements(id); //} //var index = str.IndexOf("ID "); //var elementId1 = str.Substring(index,) } /// /// 获取当前文档的有效元素ID /// /// /// private List GetElementIds(DataRow dr) { var list = new List(); var str = dr[1].ToString(); var idStr = str.Split(' ').Last(); #if REVIT2018 || REVIT2020 var id = new ElementId(int.Parse(idStr)); #elif REVIT2025 var id = new ElementId(long.Parse(idStr)); #endif var str1 = dr[2].ToString(); var idStr1 = str1.Split(' ').Last(); #if REVIT2018 || REVIT2020 var id1 = new ElementId(int.Parse(idStr1)); #elif REVIT2025 var id1 = new ElementId(long.Parse(idStr1)); #endif var e = UiApp.ActiveUIDocument.Document.GetElement(id); var e1 = UiApp.ActiveUIDocument.Document.GetElement(id1); if (e is { IsValidObject: true } && !e.Document.IsLinked) { list.Add(id); } if (e1 is { IsValidObject: true } && !e1.Document.IsLinked) { list.Add(id1); } return list; } [RelayCommand(CanExecute = nameof(CanRefresh))] private void Refresh() { CurrentViewItems.Clear(); LoadHtmlTableData(FilePathName); } private bool CanRefresh => !string.IsNullOrEmpty(FilePathName); [RelayCommand] private void OpenFile() { var fileOpenDialog = new OpenFileDialog() { Filter = "Html文件 (*.html)|*.html", Multiselect = false, }; if (fileOpenDialog.ShowDialog() == true) { FilePathName = fileOpenDialog.FileName; LoadHtmlTableData(FilePathName); } } }