Files
SzmediTools/Szmedi.RvKits/MEPTools/ClashReportViewModel.cs
2025-09-16 16:06:41 +08:00

341 lines
10 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.Data;
using System.Linq;
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 Szmedi.RvKits.MEPTools;
public partial class ClashReportViewModel : ObservableObject
{
public string FilePathName { get; set; }
public UIApplication UiApp { get; set; }
[ObservableProperty]
private bool inCurrentView = true;
public DataTable DataSource { get; set; } = new DataTable();
/// <summary>
/// 单页显示的源
/// </summary>
public DataTable CurrentViewItems { get; set; } = new();
[RelayCommand]
private void LvScroll(ScrollViewer scrollViewer)
{
if (!isLoadingData && scrollViewer.VerticalOffset + scrollViewer.ViewportHeight == scrollViewer.ExtentHeight)
{
LoadMoreData();
}
}
private const int VbBatchSize = 20;
private bool isLoadingData;
private void LoadInitialData(DataGrid dataGrid)
{
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]);
}
dataGrid.ItemsSource = CurrentViewItems.DefaultView;
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, DataGrid dataGrid)
{
var htmlContent = ReadLocalHtmlFile(filePath);
DataSource = ParseHtmlToPairs(htmlContent);
LoadInitialData(dataGrid);
}
//private async Task<string> 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.Message);
// 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)
{
// Extract column headers
//foreach (HtmlNode header in tableNode.SelectNodes("tr/th"))
//{
// dataTable.Columns.Add(WebUtility.HtmlDecode(header.InnerText.Trim()));
//}
// Extract rows and data
//foreach (HtmlNode row in tableNode.SelectNodes("tr"))
//{
// DataRow dataRow = dataTable.NewRow();
// int columnIndex = 0;
// foreach (HtmlNode cell in row.SelectNodes("td"))
// {
// dataRow[columnIndex] = WebUtility.HtmlDecode(cell.InnerText.Trim());
// columnIndex++;
// }
// dataTable.Rows.Add(dataRow);
//}
var rows = tableNode.SelectNodes("tr");
for (var i = 0; i < rows.Count; i++)
{
//var collection = rows[i].SelectNodes("td");
//var pair = new ClashPair(collection[0].InnerText.Trim(), collection[1].InnerText.Trim(), collection[2].InnerText.Trim());
//pairs.Add(pair);
if (i == 0)
{
var row = rows[i].SelectNodes("td");
for (var j = 0; j < row.Count; j++)
{
var cell = row[j];
if (cell.InnerText == string.Empty)
{
dataTable.Columns.Add(WebUtility.HtmlDecode("序号"));
}
else
{
dataTable.Columns.Add(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)
{
if (obj is not DataGrid dataGrid)
{
return;
}
var rowView = dataGrid.SelectedItem as DataRowView;
var dr = rowView.Row;
var ids = GetElementIds(dr);
UiApp.ActiveUIDocument.Selection.SetElementIds(ids);
var doc = UiApp.ActiveUIDocument.Document;
var view = doc.ActiveView;
if (view is View3D view3D)
{
handler.Raise(
_ =>
doc.Invoke(
ts =>
{
view = view3D.CreateSectionBox(ids, InCurrentView);
ts.Commit();
if (UiApp.ActiveUIDocument.ActiveView.Id != view.Id)
{
UiApp.ActiveUIDocument.ActiveView = view;
}
},
"创建剖切框"
)
);
}
//RevitCommandId revitCommandId = RevitCommandId.LookupPostableCommandId(PostableCommand.SelectionBox);
//try
//{
// uiapp.PostCommand(revitCommandId);
//}
//catch (Exception)
//{
// throw;
//}
//RevitCommandId.LookupCommandId()
//List<ElementId> ids = GetElementIds(dr);
//ElementId id = null;
//if (uiapp.ActiveUIDocument.doc.GetElement(ids[0]).IsValidObject)
//{
// id = ids[0];
//}
//else
//{
// ids.Remove(ids[0]);
// if (uiapp.ActiveUIDocument.doc.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,)
}
//public void RunCommand(UIApplication uiapp)
//{
// var commandId = RevitCommandId.LookupPostableCommandId(PostableCommand.SelectionBox);
// var commandMonitor = new RevitCommandEndedMonitor(uiapp);
// commandMonitor.CommandEnded += OnCommandEnded;
// uiapp.PostCommand(commandId);
//}
//private void OnCommandEnded(object sender, EventArgs eventArgs)
//{
// //continue processing after the commandId has ended
//}
private List<ElementId> GetElementIds(DataRow dr)
{
var list = new List<ElementId>();
var str = dr[1].ToString();
var idStr = str.Split(' ').Last();
var id = new ElementId(int.Parse(idStr));
var str1 = dr[2].ToString();
var idStr1 = str1.Split(' ').Last();
var id1 = new ElementId(int.Parse(idStr1));
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]
private void Refresh(object obj)
{
if (obj is not DataGrid dataGrid)
{
return;
}
dataGrid.ItemsSource = null;
LoadHtmlTableData(FilePathName, dataGrid);
}
[RelayCommand]
private void Open(object obj)
{
if (obj is not DataGrid dataGrid)
{
return;
}
var fileOpenDialog = new OpenFileDialog() { Filter = "Html文件 (*.html)|*.html", Multiselect = false, };
if (fileOpenDialog.ShowDialog() == true)
{
FilePathName = fileOpenDialog.FileName;
LoadHtmlTableData(FilePathName, dataGrid);
}
}
}