Files
ShrlAlgoToolkit/ShrlAlgo.RvKits/RvMEP/ClashReportViewModel.cs

312 lines
9.0 KiB
C#
Raw Normal View History

2024-09-22 11:05:41 +08:00
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 ShrlAlgo.RvKits.RvMEP;
2024-09-22 11:05:41 +08:00
public partial class ClashReportViewModel(UIApplication uiapp) : ObservableObject
{
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(RefreshCommand))]
private string filePathName;
public UIApplication UiApp { get; set; } = uiapp;
[ObservableProperty]
private bool inCurrentView = true;
[ObservableProperty]
private bool isSetSectionBox;
public DataTable DataSource { get; set; } = new DataTable();
[ObservableProperty]
private DataTable currentViewItems = 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<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.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<ElementId> 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,)
}
/// <summary>
/// 获取当前文档的有效元素ID
/// </summary>
/// <param name="dr"></param>
/// <returns></returns>
private List<ElementId> GetElementIds(DataRow dr)
{
var list = new List<ElementId>();
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);
}
}
}