NavisworksTransport/src/UI/WPF/Views/PathEditingView.xaml.cs

308 lines
12 KiB
C#

using System;
using System.Drawing.Imaging;
using System.Windows;
using System.Windows.Controls;
using NavisworksTransport.UI.WPF.ViewModels;
using NavisworksTransport.UI.WPF.Views;
using NavisworksTransport.Core.Services;
using NavisworksTransport.Core.Models;
using NavisworksTransport.Utils;
namespace NavisworksTransport.UI.WPF.Views
{
/// <summary>
/// PathEditingView.xaml 的交互逻辑
/// 路径编辑页面视图 - 支持自动路径规划和手动路径编辑
/// </summary>
public partial class PathEditingView : UserControl
{
/// <summary>
/// ViewModel属性,用于外部访问
/// </summary>
public PathEditingViewModel ViewModel { get; private set; }
/// <summary>
/// 时标服务实例
/// </summary>
private TimeTagService _timeTagService;
/// <summary>
/// 构造函数,需要传入主ViewModel以支持统一状态栏
/// </summary>
/// <param name="mainViewModel">主ViewModel,用于统一状态栏</param>
public PathEditingView(LogisticsControlViewModel mainViewModel)
{
InitializeComponent();
// 创建ViewModel,传入主ViewModel引用
ViewModel = new PathEditingViewModel(mainViewModel);
DataContext = ViewModel;
PathRoutesGrid.SelectionChanged += OnPathRoutesSelectionChanged;
LogManager.Info("PathEditingView初始化完成 - 支持统一状态栏");
}
/// <summary>
/// 同步 DataGrid 多选状态到 ViewModel 的 IsSelected
/// </summary>
private void OnPathRoutesSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ViewModel?.PathRoutes == null) return;
foreach (PathRouteViewModel item in e.RemovedItems)
item.IsSelected = false;
foreach (PathRouteViewModel item in e.AddedItems)
item.IsSelected = true;
}
/// <summary>
/// 清理资源
/// </summary>
public void Cleanup()
{
try
{
// 清理ViewModel
ViewModel?.Cleanup();
LogManager.Info("PathEditingView资源清理完成");
}
catch (Exception ex)
{
LogManager.Error($"PathEditingView清理失败: {ex.Message}");
}
}
/// <summary>
/// 路径列表中"时标"按钮点击,打开时间标签窗口
/// </summary>
private void OnTimeTagButtonClick(object sender, RoutedEventArgs e)
{
try
{
LogManager.Info("时标按钮被点击");
// 从按钮的DataContext获取当前路径ViewModel
if (!(sender is Button button) || !(button.DataContext is PathRouteViewModel routeVm))
{
LogManager.Warning("无法获取当前路径信息");
return;
}
// 获取底层的PathRoute
var route = routeVm.Route;
if (route == null)
{
LogManager.Warning("PathRouteViewModel中的Route为空");
return;
}
// 确保服务已初始化
if (_timeTagService == null)
{
var pathManager = PathPlanningManager.Instance;
pathManager.DatabaseInitialize(createIfMissing: true);
var db = pathManager.GetPathDatabase();
if (db == null)
{
throw new InvalidOperationException("时标服务初始化失败:无法获取数据库实例");
}
_timeTagService = new TimeTagService(db);
LogManager.Info("时标服务已初始化");
}
// 创建并显示时标对话框
var dlg = new TimeTagDialog(_timeTagService, route);
DialogHelper.SetOwnerFromUserControl(dlg, this);
dlg.ShowDialog();
LogManager.Info($"时标对话框关闭: {route.Name}");
}
catch (Exception ex)
{
LogManager.Error($"打开时间标签窗口失败: {ex.Message}");
LogManager.Error($"异常详情: {ex}");
MessageBox.Show($"打开时标窗口失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
MessageBox.Show($"打开时标窗口失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// 路径分析按钮点击事件,打开路径规划分析对话框(非模态)
/// </summary>
private void OnPathAnalysisButtonClick(object sender, RoutedEventArgs e)
{
try
{
LogManager.Info("路径分析按钮被点击,准备打开PathAnalysisDialog窗口");
// 使用静态方法显示(单例模式,非模态)
var parentWindow = Window.GetWindow(this);
PathAnalysisDialog.ShowAnalysis(parentWindow);
}
catch (Exception ex)
{
LogManager.Error($"打开路径分析窗口失败: {ex.Message}");
LogManager.Error($"异常详情: {ex}");
}
}
/// <summary>
/// 生成导航地图按钮点击事件,打开生成导航地图对话框
/// </summary>
private void OnGenerateNavigationMapButtonClick(object sender, RoutedEventArgs e)
{
try
{
LogManager.Info("生成导航地图按钮被点击,准备打开GenerateNavigationMapDialog窗口");
// 检查前置条件
if (ViewModel?.SelectedPathRoute == null || ViewModel.SelectedPathRoute.Points.Count == 0)
{
LogManager.Warning("无法生成导航地图:未选择路径或路径为空");
return;
}
var dialog = new GenerateNavigationMapDialog();
// 设置父窗口
DialogHelper.SetOwnerFromUserControl(dialog, this);
if (dialog.ShowDialog() == true && dialog.IsConfirmed)
{
LogManager.Info($"用户确认生成导航地图参数: 格式={dialog.ImageFormat}, 尺寸={dialog.ImageWidth}x{dialog.ImageHeight}, 样式={dialog.RenderStyle}");
// 调用ViewModel的业务逻辑方法生成图像
using (var bitmap = ViewModel.GenerateNavigationMap(
dialog.RenderStyle,
dialog.ImageWidth,
dialog.ImageHeight,
dialog.ImageFormat))
{
// 打开文件保存对话框
var saveFileDialog = new Microsoft.Win32.SaveFileDialog
{
Title = "保存导航地图",
Filter = GetImageFormatFilter(dialog.ImageFormat),
DefaultExt = GetDefaultExtension(dialog.ImageFormat),
FileName = $"导航地图_{DateTime.Now:yyyyMMdd_HHmmss}",
AddExtension = true
};
if (saveFileDialog.ShowDialog() == true)
{
// 保存图像
var generator = new NavisworksTransport.Core.NavigationMapGenerator();
generator.SaveNavigationMapImage(bitmap, saveFileDialog.FileName, dialog.ImageFormat);
LogManager.Info($"导航地图保存成功: {saveFileDialog.FileName}, 尺寸: {dialog.ImageWidth}x{dialog.ImageHeight}, 格式: {dialog.ImageFormat}");
}
else
{
LogManager.Info("用户取消了导航地图保存");
}
}
}
else
{
LogManager.Info("用户取消了导航地图生成");
}
LogManager.Info("GenerateNavigationMapDialog窗口处理完成");
}
catch (Exception ex)
{
LogManager.Error($"生成导航地图失败: {ex.Message}");
LogManager.Error($"异常详情: {ex}");
}
}
/// <summary>
/// 获取图像格式的文件过滤器
/// </summary>
private string GetImageFormatFilter(ImageFormat format)
{
if (format.Equals(ImageFormat.Jpeg))
{
return "JPEG图像 (*.jpg)|*.jpg|所有文件 (*.*)|*.*";
}
else if (format.Equals(ImageFormat.Png))
{
return "PNG图像 (*.png)|*.png|所有文件 (*.*)|*.*";
}
else if (format.Equals(ImageFormat.Bmp))
{
return "位图文件 (*.bmp)|*.bmp|所有文件 (*.*)|*.*";
}
return "图像文件 (*.png)|*.png|所有文件 (*.*)|*.*";
}
/// <summary>
/// 获取图像格式的默认扩展名
/// </summary>
private string GetDefaultExtension(ImageFormat format)
{
if (format.Equals(ImageFormat.Jpeg)) return "jpg";
if (format.Equals(ImageFormat.Png)) return "png";
if (format.Equals(ImageFormat.Bmp)) return "bmp";
return "png";
}
/// <summary>
/// 测量包围盒按钮点击事件,打开元素包围盒信息窗口
/// </summary>
private void OnMeasureBoundsButtonClick(object sender, RoutedEventArgs e)
{
try
{
LogManager.Info("测量包围盒按钮被点击,准备打开ModelItemBoundsWindow窗口");
// 创建或复用窗口实例
if (_boundsWindow == null || !_boundsWindow.IsVisible)
{
_boundsWindow = new ModelItemBoundsWindow();
// 设置父窗口(非模态窗口)
DialogHelper.SetOwnerFromUserControl(_boundsWindow, this);
// 使用 Show() 而非 ShowDialog(),允许窗口一直开着
_boundsWindow.Show();
LogManager.Info("ModelItemBoundsWindow窗口已显示(非模态)");
}
else
{
// 窗口已存在,刷新信息并激活
_boundsWindow.RefreshBoundsInfo();
_boundsWindow.Activate();
LogManager.Info("ModelItemBoundsWindow窗口已存在,已刷新并激活");
}
}
catch (Exception ex)
{
LogManager.Error($"打开包围盒信息窗口失败: {ex.Message}");
LogManager.Error($"异常详情: {ex}");
}
}
private void OnCornerTurnCheckClick(object sender, RoutedEventArgs e)
{
try
{
var dialog = new CornerTurnCheckDialog();
dialog.ShowDialog();
}
catch (Exception ex)
{
LogManager.Error($"打开过弯检测对话框失败: {ex.Message}");
}
}
/// <summary>
/// 包围盒信息窗口实例(保持引用以防止被GC回收)
/// </summary>
private ModelItemBoundsWindow _boundsWindow;
}
}