大量更新
This commit is contained in:
287
Szmedi.CADkits/ReviewAndMatchWindow.xaml.cs
Normal file
287
Szmedi.CADkits/ReviewAndMatchWindow.xaml.cs
Normal file
@@ -0,0 +1,287 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
using Autodesk.AutoCAD.ApplicationServices;
|
||||
using Autodesk.AutoCAD.DatabaseServices;
|
||||
using Autodesk.AutoCAD.EditorInput;
|
||||
using Autodesk.AutoCAD.Geometry;
|
||||
using Autodesk.AutoCAD.Windows;
|
||||
|
||||
using Application = Autodesk.AutoCAD.ApplicationServices.Application;
|
||||
|
||||
|
||||
namespace Szmedi.CADkits
|
||||
{
|
||||
public partial class ReviewAndMatchWindow : UserControl
|
||||
{
|
||||
public ObservableCollection<BlockReviewItem> ReviewItems { get; set; }
|
||||
private readonly string _checkLineLayer;
|
||||
private bool _isListeningToSelection = true;
|
||||
private readonly PaletteSet _parentPalette;
|
||||
private readonly Dictionary<ObjectId, TextWithPosition> _textDataMap;
|
||||
public ReviewAndMatchWindow(
|
||||
List<BlockRefWithPosition> allBlocks,
|
||||
Dictionary<ObjectId, ObjectId> autoPairs,
|
||||
List<TextWithPosition> allTexts,
|
||||
string checkLineLayer,
|
||||
PaletteSet parentPalette)
|
||||
{
|
||||
InitializeComponent();
|
||||
_checkLineLayer = checkLineLayer;
|
||||
_parentPalette = parentPalette;
|
||||
_textDataMap = allTexts.ToDictionary(t => t.ObjectId, t => t);
|
||||
|
||||
ReviewItems = new ObservableCollection<BlockReviewItem>();
|
||||
ReviewListView.ItemsSource = ReviewItems;
|
||||
|
||||
PopulateList(allBlocks, autoPairs);
|
||||
}
|
||||
private void PopulateList(List<BlockRefWithPosition> allBlocks, Dictionary<ObjectId, ObjectId> autoPairs)
|
||||
{
|
||||
foreach (var blockData in allBlocks)
|
||||
{
|
||||
var item = new BlockReviewItem
|
||||
{
|
||||
BlockId = blockData.ObjectId,
|
||||
Handle = blockData.ObjectId.Handle.Value.ToString(),
|
||||
Position = $"{blockData.Position.X:F2}, {blockData.Position.Y:F2}"
|
||||
};
|
||||
|
||||
if (autoPairs.TryGetValue(blockData.ObjectId, out ObjectId textId))
|
||||
{
|
||||
// 自动匹配成功
|
||||
item.Status = _textDataMap[textId].TextContent;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 未匹配
|
||||
item.Status = "--- 未匹配 ---";
|
||||
}
|
||||
ReviewItems.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
//private void LocateButton_Click(object sender, RoutedEventArgs e)
|
||||
//{
|
||||
// if (UnmatchedBlocksListView.SelectedItem is UnmatchedBlockItem selected)
|
||||
// {
|
||||
// ZoomToEntity(selected.BlockId);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// MessageBox.Show("请先在列表中选择一个块。", "提示");
|
||||
// }
|
||||
//}
|
||||
private void MatchButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!(ReviewListView.SelectedItem is BlockReviewItem selected))
|
||||
{
|
||||
MessageBox.Show("请先在列表中选择一个要匹配的块。", "提示");
|
||||
return;
|
||||
}
|
||||
|
||||
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
|
||||
Editor ed = doc.Editor;
|
||||
|
||||
// 通过控制父面板来隐藏
|
||||
_parentPalette.Visible = false;
|
||||
|
||||
try
|
||||
{
|
||||
PromptEntityOptions peo = new PromptEntityOptions("\n请点选此块对应的标高文字: ");
|
||||
peo.SetRejectMessage("\n选择的不是文字对象。");
|
||||
peo.AddAllowedClass(typeof(DBText), true);
|
||||
peo.AddAllowedClass(typeof(MText), true);
|
||||
|
||||
PromptEntityResult per = ed.GetEntity(peo);
|
||||
|
||||
if (per.Status == PromptStatus.OK)
|
||||
{
|
||||
UpdateBlockWithSelectedText(selected, per.ObjectId);
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
MessageBox.Show($"发生错误: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 操作结束后,重新显示父面板
|
||||
_parentPalette.Visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBlockWithSelectedText(BlockReviewItem itemToUpdate, ObjectId textId)
|
||||
{
|
||||
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
|
||||
Database db = doc.Database;
|
||||
using (DocumentLock docLock = doc.LockDocument())
|
||||
{
|
||||
using (Transaction tr = db.TransactionManager.StartTransaction())
|
||||
{
|
||||
// 1. 获取文字内容和中心点
|
||||
Entity textEnt = (Entity)tr.GetObject(textId, OpenMode.ForRead);
|
||||
string textContent = "";
|
||||
if (textEnt is MText mtext) textContent = mtext.Contents;
|
||||
else if (textEnt is DBText dbtext) textContent = dbtext.TextString;
|
||||
|
||||
// 验证文字内容
|
||||
if (!double.TryParse(textContent, NumberStyles.Float, CultureInfo.InvariantCulture, out double elevationZ))
|
||||
{
|
||||
MessageBox.Show($"文字内容 '{textContent}' 不是有效的数字。", "匹配失败");
|
||||
tr.Abort();
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 更新块
|
||||
BlockReference blockRef = (BlockReference)tr.GetObject(itemToUpdate.BlockId, OpenMode.ForWrite);
|
||||
blockRef.Position = new Point3d(blockRef.Position.X, blockRef.Position.Y, elevationZ);
|
||||
|
||||
// 3. 创建校对线
|
||||
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
|
||||
Extents3d textExtents = textEnt.GeometricExtents;
|
||||
Point3d textCenter = textExtents.MinPoint + (textExtents.MaxPoint - textExtents.MinPoint) * 0.5;
|
||||
|
||||
Line checkLine = new Line(blockRef.Position, textCenter);
|
||||
checkLine.Layer = _checkLineLayer;
|
||||
checkLine.ColorIndex = 256; // ByLayer
|
||||
btr.AppendEntity(checkLine);
|
||||
tr.AddNewlyCreatedDBObject(checkLine, true);
|
||||
itemToUpdate.Status = $"手动: {elevationZ}";
|
||||
|
||||
tr.Commit();
|
||||
//Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog($"块 {itemToUpdate.Handle} 已手动更新为 {elevationZ}。");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_parentPalette.Visible = false;
|
||||
}
|
||||
|
||||
// 辅助方法:缩放到实体
|
||||
private void ZoomToEntity(ObjectId entId)
|
||||
{
|
||||
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
|
||||
if (doc == null) return;
|
||||
Editor ed = doc.Editor;
|
||||
Database db = doc.Database;
|
||||
|
||||
using (Transaction tr = db.TransactionManager.StartTransaction())
|
||||
{
|
||||
if (entId.IsErased) return;
|
||||
Entity ent = tr.GetObject(entId, OpenMode.ForRead) as Entity;
|
||||
if (ent != null)
|
||||
{
|
||||
// 创建一个基于实体包围盒的视图
|
||||
Extents3d extents = ent.GeometricExtents;
|
||||
Matrix3d ucs = ed.CurrentUserCoordinateSystem;
|
||||
double viewSize = Math.Max(extents.MaxPoint.X - extents.MinPoint.X, extents.MaxPoint.Y - extents.MinPoint.Y) * 5.0;
|
||||
// 扩大一点包围盒,使其不至于占满全屏
|
||||
extents.TransformBy(ucs.Inverse());
|
||||
ViewTableRecord view = new ViewTableRecord
|
||||
{
|
||||
CenterPoint = new Point2d(
|
||||
(extents.MinPoint.X + extents.MaxPoint.X) / 2.0,
|
||||
(extents.MinPoint.Y + extents.MaxPoint.Y) / 2.0),
|
||||
Height = viewSize,
|
||||
Width = viewSize
|
||||
};
|
||||
ed.SetCurrentView(view);
|
||||
ed.SetImpliedSelection(new ObjectId[] { entId });
|
||||
}
|
||||
tr.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
private void ListView_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
if (ReviewListView.SelectedItem is BlockReviewItem selected)
|
||||
{
|
||||
ZoomToEntity(selected.BlockId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void SelectAndScrollToItem(ObjectId blockId)
|
||||
{
|
||||
var itemToSelect = ReviewItems.FirstOrDefault(item => item.BlockId == blockId);
|
||||
if (itemToSelect != null)
|
||||
{
|
||||
ReviewListView.SelectedItem = itemToSelect;
|
||||
ReviewListView.ScrollIntoView(itemToSelect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void CleanLinesButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
MessageBoxResult result = MessageBox.Show(
|
||||
"确定要删除所有由本工具创建的校对线吗?\n此操作不可撤销。",
|
||||
"确认清理",
|
||||
MessageBoxButton.YesNo,
|
||||
MessageBoxImage.Warning);
|
||||
|
||||
if (result == MessageBoxResult.Yes)
|
||||
{
|
||||
// 调用主类中的公共静态方法来执行清理
|
||||
TerrainTools.CleanAllCheckLines();
|
||||
}
|
||||
}
|
||||
|
||||
private void LocateInListButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Document doc = Application.DocumentManager.MdiActiveDocument;
|
||||
Editor ed = doc.Editor;
|
||||
ObjectId targetId = ObjectId.Null;
|
||||
|
||||
_isListeningToSelection = false; // 暂时关闭自动监听,避免冲突
|
||||
|
||||
try
|
||||
{
|
||||
// 1. 检查是否已经有选中的对象
|
||||
PromptSelectionResult psr = ed.GetSelection();
|
||||
if (psr.Status == PromptStatus.OK && psr.Value.Count > 0)
|
||||
{
|
||||
// 如果有,直接使用第一个
|
||||
targetId = psr.Value.GetObjectIds()[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2. 如果没有选中,则提示用户去选择
|
||||
_parentPalette.Visible = false; // 隐藏面板方便用户选择
|
||||
|
||||
PromptEntityOptions peo = new PromptEntityOptions("\n请在图中选择一个地形点块进行定位: ");
|
||||
peo.SetRejectMessage("\n选择的不是块参照。");
|
||||
peo.AddAllowedClass(typeof(BlockReference), true);
|
||||
|
||||
PromptEntityResult per = ed.GetEntity(peo);
|
||||
if (per.Status == PromptStatus.OK)
|
||||
{
|
||||
targetId = per.ObjectId;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 如果成功获取到ID,则在列表中定位
|
||||
if (!targetId.IsNull)
|
||||
{
|
||||
SelectAndScrollToItem(targetId);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 4. 无论如何都恢复UI状态
|
||||
_isListeningToSelection = true; // 重新开启监听
|
||||
_parentPalette.Visible = true;
|
||||
this.Focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user