308 lines
12 KiB
C#
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;
|
|
}
|
|
}
|