把所有路径设置的功能移到对应子模块
This commit is contained in:
parent
ede5ac68c9
commit
9928dda6e3
@ -46,7 +46,9 @@
|
||||
"Bash(grep:*)",
|
||||
"Bash(find:*)",
|
||||
"mcp__context7__get-library-docs",
|
||||
"Bash(powershell:*)"
|
||||
"Bash(powershell:*)",
|
||||
"mcp__serena__insert_before_symbol",
|
||||
"Bash(\"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\MSBuild.exe\" NavisworksTransportPlugin.csproj /p:Configuration=Debug /p:Platform=AnyCPU /verbosity:normal)"
|
||||
],
|
||||
"deny": [],
|
||||
"additionalDirectories": [
|
||||
|
||||
Binary file not shown.
@ -192,6 +192,7 @@
|
||||
<Compile Include="src\UI\WPF\ViewModels\LayerManagementViewModel.cs" />
|
||||
<Compile Include="src\UI\WPF\ViewModels\ModelSettingsViewModel.cs" />
|
||||
<Compile Include="src\UI\WPF\ViewModels\AnimationControlViewModel.cs" />
|
||||
<Compile Include="src\UI\WPF\ViewModels\PathEditingViewModel.cs" />
|
||||
|
||||
<!-- UI - WPF Simplified Controls -->
|
||||
<Compile Include="src\UI\WPF\SimpleLogisticsControlPanel.cs" />
|
||||
|
||||
665
doc/working/LogisticsControlViewModel.cs.backup
Normal file
665
doc/working/LogisticsControlViewModel.cs.backup
Normal file
@ -0,0 +1,665 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Autodesk.Navisworks.Api;
|
||||
using NavisApplication = Autodesk.Navisworks.Api.Application;
|
||||
using NavisworksTransport.Core;
|
||||
using NavisworksTransport.Commands;
|
||||
using NavisworksTransport.UI.WPF.Collections;
|
||||
using NavisworksTransport.UI.WPF.Models;
|
||||
using NavisworksTransport.Utils;
|
||||
|
||||
namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// 物流控制面板主ViewModel
|
||||
/// </summary>
|
||||
public class LogisticsControlViewModel : ViewModelBase
|
||||
{
|
||||
#region 私有字段
|
||||
|
||||
private string _selectedModelsText;
|
||||
private string _instructionText;
|
||||
private string _statusText;
|
||||
private ObservableCollection<LogisticsModel> _logisticsModels;
|
||||
private LogisticsModel _selectedLogisticsModel;
|
||||
private ObservableCollection<PathRouteViewModel> _pathRoutes;
|
||||
private PathRouteViewModel _selectedPathRoute;
|
||||
private bool _isPathEditMode;
|
||||
private string _animationStatus;
|
||||
private double _animationProgress;
|
||||
private ObservableCollection<string> _availableCategories;
|
||||
private string _selectedCategory;
|
||||
private double _widthLimit;
|
||||
private string _pathFileStatus;
|
||||
private PathPlanningManager _pathPlanningManager;
|
||||
private bool _isLogisticsOnlyMode = false;
|
||||
|
||||
// UI状态管理和命令框架
|
||||
private readonly UIStateManager _uiStateManager;
|
||||
private readonly NavisworksTransport.Commands.CommandManager _commandManager;
|
||||
|
||||
// 动画参数相关字段
|
||||
private double _animationSpeed = 1.0;
|
||||
private ObservableCollection<int> _availableFrameRates;
|
||||
private int _selectedFrameRate = 30;
|
||||
private double _animationDuration = 10.0;
|
||||
private bool _isLoopEnabled = false;
|
||||
private bool _isSmoothTransition = true;
|
||||
private double _currentAnimationTime = 0.0;
|
||||
private bool _canStartAnimation = true;
|
||||
private bool _canPauseAnimation = false;
|
||||
private bool _canStopAnimation = false;
|
||||
|
||||
// 碰撞检测相关字段
|
||||
private bool _canRunCollisionDetection = true;
|
||||
private bool _hasCollisionResults = false;
|
||||
private string _collisionStatus = "就绪";
|
||||
private string _collisionSummary = "尚未运行碰撞检测";
|
||||
|
||||
// 系统管理相关字段
|
||||
private string _modelSplitterStatus = "就绪";
|
||||
private ObservableCollection<string> _logLevels;
|
||||
private string _selectedLogLevel = "Info";
|
||||
private string _logStatus = "日志系统正常";
|
||||
private bool _isAutoSaveEnabled = true;
|
||||
private bool _isDebugModeEnabled = false;
|
||||
private string _settingsStatus = "设置已加载";
|
||||
private string _pluginVersion = "v1.0";
|
||||
private string _navisworksVersion = "2026";
|
||||
private string _systemStatus = "正常";
|
||||
private string _systemStatusColor = "Green";
|
||||
private string _memoryUsage = "0 MB";
|
||||
private string _runningTime = "00:00:00";
|
||||
private string _performanceInfo = "性能监控就绪";
|
||||
|
||||
// 自动路径规划相关字段
|
||||
private string _autoPathStartPoint = "未选择";
|
||||
private string _autoPathEndPoint = "未选择";
|
||||
private double _autoPathVehicleSize = 1.0;
|
||||
private double _autoPathSafetyMargin = 0.5;
|
||||
private string _autoPathStatus = "就绪";
|
||||
private Point3D _startPoint3D;
|
||||
private Point3D _endPoint3D;
|
||||
private bool _hasStartPoint = false;
|
||||
private bool _hasEndPoint = false;
|
||||
private bool _isSelectingStartPoint = false;
|
||||
private bool _isSelectingEndPoint = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 公共属性
|
||||
|
||||
/// <summary>
|
||||
/// 选中模型文本
|
||||
/// </summary>
|
||||
public string SelectedModelsText
|
||||
{
|
||||
get => _selectedModelsText;
|
||||
set => SetProperty(ref _selectedModelsText, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 指令文本
|
||||
/// </summary>
|
||||
public string InstructionText
|
||||
{
|
||||
get => _instructionText;
|
||||
set => SetProperty(ref _instructionText, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 状态文本
|
||||
/// </summary>
|
||||
public string StatusText
|
||||
{
|
||||
get => _statusText;
|
||||
set => SetProperty(ref _statusText, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 物流模型集合
|
||||
/// </summary>
|
||||
public ObservableCollection<LogisticsModel> LogisticsModels
|
||||
{
|
||||
get => _logisticsModels;
|
||||
set => SetProperty(ref _logisticsModels, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选中的物流模型
|
||||
/// </summary>
|
||||
public LogisticsModel SelectedLogisticsModel
|
||||
{
|
||||
get => _selectedLogisticsModel;
|
||||
set => SetProperty(ref _selectedLogisticsModel, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 路径集合
|
||||
/// </summary>
|
||||
public ObservableCollection<PathRouteViewModel> PathRoutes
|
||||
{
|
||||
get => _pathRoutes;
|
||||
set => SetProperty(ref _pathRoutes, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选中的路径
|
||||
/// </summary>
|
||||
public PathRouteViewModel SelectedPathRoute
|
||||
{
|
||||
get => _selectedPathRoute;
|
||||
set => SetProperty(ref _selectedPathRoute, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否处于路径编辑模式
|
||||
/// </summary>
|
||||
public bool IsPathEditMode
|
||||
{
|
||||
get => _isPathEditMode;
|
||||
set => SetProperty(ref _isPathEditMode, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动画状态
|
||||
/// </summary>
|
||||
public string AnimationStatus
|
||||
{
|
||||
get => _animationStatus;
|
||||
set => SetProperty(ref _animationStatus, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动画进度
|
||||
/// </summary>
|
||||
public double AnimationProgress
|
||||
{
|
||||
get => _animationProgress;
|
||||
set => SetProperty(ref _animationProgress, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 可用类别集合
|
||||
/// </summary>
|
||||
public ObservableCollection<string> AvailableCategories
|
||||
{
|
||||
get => _availableCategories;
|
||||
set => SetProperty(ref _availableCategories, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选中的类别
|
||||
/// </summary>
|
||||
public string SelectedCategory
|
||||
{
|
||||
get => _selectedCategory;
|
||||
set => SetProperty(ref _selectedCategory, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 宽度限制(米)
|
||||
/// </summary>
|
||||
public double WidthLimit
|
||||
{
|
||||
get => _widthLimit;
|
||||
set => SetProperty(ref _widthLimit, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 路径文件状态
|
||||
/// </summary>
|
||||
public string PathFileStatus
|
||||
{
|
||||
get => _pathFileStatus;
|
||||
set => SetProperty(ref _pathFileStatus, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否处于仅显示物流模式
|
||||
/// </summary>
|
||||
public bool IsLogisticsOnlyMode
|
||||
{
|
||||
get => _isLogisticsOnlyMode;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _isLogisticsOnlyMode, value))
|
||||
{
|
||||
// 当开关状态改变时,自动应用可见性设置
|
||||
ApplyVisibilityMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region 动画控制属性
|
||||
|
||||
/// <summary>
|
||||
/// 动画速度
|
||||
/// </summary>
|
||||
public double AnimationSpeed
|
||||
{
|
||||
get => _animationSpeed;
|
||||
set => SetProperty(ref _animationSpeed, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 可用帧率集合
|
||||
/// </summary>
|
||||
public ObservableCollection<int> AvailableFrameRates
|
||||
{
|
||||
get => _availableFrameRates;
|
||||
set => SetProperty(ref _availableFrameRates, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选中的帧率
|
||||
/// </summary>
|
||||
public int SelectedFrameRate
|
||||
{
|
||||
get => _selectedFrameRate;
|
||||
set => SetProperty(ref _selectedFrameRate, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动画持续时间(秒)
|
||||
/// </summary>
|
||||
public double AnimationDuration
|
||||
{
|
||||
get => _animationDuration;
|
||||
set => SetProperty(ref _animationDuration, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用循环播放
|
||||
/// </summary>
|
||||
public bool IsLoopEnabled
|
||||
{
|
||||
get => _isLoopEnabled;
|
||||
set => SetProperty(ref _isLoopEnabled, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用平滑过渡
|
||||
/// </summary>
|
||||
public bool IsSmoothTransition
|
||||
{
|
||||
get => _isSmoothTransition;
|
||||
set => SetProperty(ref _isSmoothTransition, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前动画时间
|
||||
/// </summary>
|
||||
public double CurrentAnimationTime
|
||||
{
|
||||
get => _currentAnimationTime;
|
||||
set => SetProperty(ref _currentAnimationTime, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否可以开始动画
|
||||
/// </summary>
|
||||
public bool CanStartAnimation
|
||||
{
|
||||
get => _canStartAnimation;
|
||||
set => SetProperty(ref _canStartAnimation, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否可以暂停动画
|
||||
/// </summary>
|
||||
public bool CanPauseAnimation
|
||||
{
|
||||
get => _canPauseAnimation;
|
||||
set => SetProperty(ref _canPauseAnimation, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否可以停止动画
|
||||
/// </summary>
|
||||
public bool CanStopAnimation
|
||||
{
|
||||
get => _canStopAnimation;
|
||||
set => SetProperty(ref _canStopAnimation, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 碰撞检测属性
|
||||
|
||||
/// <summary>
|
||||
/// 是否可以运行碰撞检测
|
||||
/// </summary>
|
||||
public bool CanRunCollisionDetection
|
||||
{
|
||||
get => _canRunCollisionDetection;
|
||||
set => SetProperty(ref _canRunCollisionDetection, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否有碰撞检测结果
|
||||
/// </summary>
|
||||
public bool HasCollisionResults
|
||||
{
|
||||
get => _hasCollisionResults;
|
||||
set => SetProperty(ref _hasCollisionResults, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 碰撞检测状态
|
||||
/// </summary>
|
||||
public string CollisionStatus
|
||||
{
|
||||
get => _collisionStatus;
|
||||
set => SetProperty(ref _collisionStatus, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 碰撞检测摘要
|
||||
/// </summary>
|
||||
public string CollisionSummary
|
||||
{
|
||||
get => _collisionSummary;
|
||||
set => SetProperty(ref _collisionSummary, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 系统管理属性
|
||||
|
||||
/// <summary>
|
||||
/// 模型分层拆分状态
|
||||
/// </summary>
|
||||
public string ModelSplitterStatus
|
||||
{
|
||||
get => _modelSplitterStatus;
|
||||
set => SetProperty(ref _modelSplitterStatus, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 日志级别集合
|
||||
/// </summary>
|
||||
public ObservableCollection<string> LogLevels
|
||||
{
|
||||
get => _logLevels;
|
||||
set => SetProperty(ref _logLevels, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选中的日志级别
|
||||
/// </summary>
|
||||
public string SelectedLogLevel
|
||||
{
|
||||
get => _selectedLogLevel;
|
||||
set => SetProperty(ref _selectedLogLevel, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 日志状态
|
||||
/// </summary>
|
||||
public string LogStatus
|
||||
{
|
||||
get => _logStatus;
|
||||
set => SetProperty(ref _logStatus, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用自动保存
|
||||
/// </summary>
|
||||
public bool IsAutoSaveEnabled
|
||||
{
|
||||
get => _isAutoSaveEnabled;
|
||||
set => SetProperty(ref _isAutoSaveEnabled, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用调试模式
|
||||
/// </summary>
|
||||
public bool IsDebugModeEnabled
|
||||
{
|
||||
get => _isDebugModeEnabled;
|
||||
set => SetProperty(ref _isDebugModeEnabled, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置状态
|
||||
/// </summary>
|
||||
public string SettingsStatus
|
||||
{
|
||||
get => _settingsStatus;
|
||||
set => SetProperty(ref _settingsStatus, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 插件版本
|
||||
/// </summary>
|
||||
public string PluginVersion
|
||||
{
|
||||
get => _pluginVersion;
|
||||
set => SetProperty(ref _pluginVersion, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navisworks版本
|
||||
/// </summary>
|
||||
public string NavisworksVersion
|
||||
{
|
||||
get => _navisworksVersion;
|
||||
set => SetProperty(ref _navisworksVersion, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 系统状态
|
||||
/// </summary>
|
||||
public string SystemStatus
|
||||
{
|
||||
get => _systemStatus;
|
||||
set => SetProperty(ref _systemStatus, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 系统状态颜色
|
||||
/// </summary>
|
||||
public string SystemStatusColor
|
||||
{
|
||||
get => _systemStatusColor;
|
||||
set => SetProperty(ref _systemStatusColor, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 内存使用情况
|
||||
/// </summary>
|
||||
public string MemoryUsage
|
||||
{
|
||||
get => _memoryUsage;
|
||||
set => SetProperty(ref _memoryUsage, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 运行时间
|
||||
/// </summary>
|
||||
public string RunningTime
|
||||
{
|
||||
get => _runningTime;
|
||||
set => SetProperty(ref _runningTime, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 性能信息
|
||||
/// </summary>
|
||||
public string PerformanceInfo
|
||||
{
|
||||
get => _performanceInfo;
|
||||
set => SetProperty(ref _performanceInfo, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 自动路径规划属性
|
||||
|
||||
/// <summary>
|
||||
/// 自动路径规划起点文本
|
||||
/// </summary>
|
||||
public string AutoPathStartPoint
|
||||
{
|
||||
get => _autoPathStartPoint;
|
||||
set => SetProperty(ref _autoPathStartPoint, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动路径规划终点文本
|
||||
/// </summary>
|
||||
public string AutoPathEndPoint
|
||||
{
|
||||
get => _autoPathEndPoint;
|
||||
set => SetProperty(ref _autoPathEndPoint, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动路径规划车辆尺寸
|
||||
/// </summary>
|
||||
public double AutoPathVehicleSize
|
||||
{
|
||||
get => _autoPathVehicleSize;
|
||||
set => SetProperty(ref _autoPathVehicleSize, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动路径规划安全间隙(车辆膨胀间隙)
|
||||
/// </summary>
|
||||
public double AutoPathSafetyMargin
|
||||
{
|
||||
get => _autoPathSafetyMargin;
|
||||
set => SetProperty(ref _autoPathSafetyMargin, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动路径规划状态
|
||||
/// </summary>
|
||||
public string AutoPathStatus
|
||||
{
|
||||
get => _autoPathStatus;
|
||||
set => SetProperty(ref _autoPathStatus, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否正在选择起点
|
||||
/// </summary>
|
||||
public bool IsSelectingStartPoint
|
||||
{
|
||||
get => _isSelectingStartPoint;
|
||||
set => SetProperty(ref _isSelectingStartPoint, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否正在选择终点
|
||||
/// </summary>
|
||||
public bool IsSelectingEndPoint
|
||||
{
|
||||
get => _isSelectingEndPoint;
|
||||
set => SetProperty(ref _isSelectingEndPoint, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region 命令
|
||||
|
||||
|
||||
public ICommand NewPathCommand { get; private set; }
|
||||
public ICommand DeletePathCommand { get; private set; }
|
||||
public ICommand RenamePathCommand { get; private set; }
|
||||
public ICommand StartEditCommand { get; private set; }
|
||||
public ICommand EndEditCommand { get; private set; }
|
||||
public ICommand ClearPathCommand { get; private set; }
|
||||
public ICommand DeletePointCommand { get; private set; }
|
||||
public ICommand ImportPathCommand { get; private set; }
|
||||
public ICommand ExportPathCommand { get; private set; }
|
||||
public ICommand SaveAsPathCommand { get; private set; }
|
||||
public ICommand StartAnimationCommand { get; private set; }
|
||||
public ICommand PauseAnimationCommand { get; private set; }
|
||||
public ICommand StopAnimationCommand { get; private set; }
|
||||
public ICommand RunCollisionDetectionCommand { get; private set; }
|
||||
public ICommand ViewCollisionReportCommand { get; private set; }
|
||||
public ICommand ModelSplitterCommand { get; private set; }
|
||||
public ICommand SetLogisticsAttributeCommand { get; private set; }
|
||||
public ICommand ViewLogCommand { get; private set; }
|
||||
public ICommand ClearLogCommand { get; private set; }
|
||||
public ICommand ExportLogCommand { get; private set; }
|
||||
public ICommand OpenSettingsCommand { get; private set; }
|
||||
public ICommand ResetSettingsCommand { get; private set; }
|
||||
public ICommand ImportConfigCommand { get; private set; }
|
||||
public ICommand CheckUpdateCommand { get; private set; }
|
||||
public ICommand GeneratePerformanceReportCommand { get; private set; }
|
||||
public ICommand SelectStartPointCommand { get; private set; }
|
||||
public ICommand SelectEndPointCommand { get; private set; }
|
||||
public ICommand AutoPlanPathCommand { get; private set; }
|
||||
public ICommand ClearAutoPathCommand { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region 构造函数
|
||||
|
||||
public LogisticsControlViewModel() : base()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 获取UI状态管理器和命令管理器实例
|
||||
_uiStateManager = UIStateManager.Instance;
|
||||
_commandManager = NavisworksTransport.Commands.CommandManager.Instance;
|
||||
|
||||
// 验证关键组件是否正常初始化
|
||||
if (_uiStateManager == null)
|
||||
{
|
||||
LogManager.Error("UIStateManager初始化失败");
|
||||
throw new InvalidOperationException("UIStateManager初始化失败");
|
||||
}
|
||||
|
||||
if (_commandManager == null)
|
||||
{
|
||||
LogManager.Error("CommandManager初始化失败");
|
||||
throw new InvalidOperationException("CommandManager初始化失败");
|
||||
}
|
||||
|
||||
// 初始化线程安全的集合
|
||||
LogisticsModels = new ThreadSafeObservableCollection<LogisticsModel>();
|
||||
PathRoutes = new ThreadSafeObservableCollection<PathRouteViewModel>();
|
||||
AvailableCategories = new ThreadSafeObservableCollection<string>();
|
||||
AvailableFrameRates = new ThreadSafeObservableCollection<int>();
|
||||
LogLevels = new ThreadSafeObservableCollection<string>();
|
||||
|
||||
// 初始化路径规划管理器
|
||||
InitializePathPlanningManager();
|
||||
|
||||
// 初始化命令(使用新的Command Pattern框架)
|
||||
InitializeCommandsAsync();
|
||||
|
||||
// 初始化状态
|
||||
InitializeViewModelAsync();
|
||||
|
||||
LogManager.Info("LogisticsControlViewModel构造函数执行完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"LogisticsControlViewModel构造函数异常: {ex.Message}", ex);
|
||||
|
||||
// 在构造函数中尽量保证对象处于可用状态
|
||||
StatusText = "初始化失败,请检查日志";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// ... [由于文件太长,我省略了中间的大部分实现代码,包含所有的方法实现] ...
|
||||
// 备份文件中包含原始的3816行完整代码
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -91,16 +91,18 @@ namespace NavisworksTransport
|
||||
_renderPlugin = PathPointRenderPlugin.Instance;
|
||||
if (_renderPlugin != null)
|
||||
{
|
||||
LogManager.WriteLog("[路径管理] PathPointRenderPlugin实例获取成功");
|
||||
LogManager.WriteLog("[路径管理] ✅ PathPointRenderPlugin实例获取成功");
|
||||
LogManager.WriteLog($"[路径管理] 渲染插件状态 - 启用: {_renderPlugin.IsEnabled}, 标记数量: {_renderPlugin.MarkerCount}");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog("[路径管理] PathPointRenderPlugin实例尚未就绪,将在后续尝试获取");
|
||||
LogManager.WriteLog("[路径管理] ❌ PathPointRenderPlugin实例尚未就绪,将在后续尝试获取");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.WriteLog($"[路径管理] PathPointRenderPlugin实例获取失败: {ex.Message}");
|
||||
LogManager.WriteLog($"[路径管理] 异常堆栈: {ex.StackTrace}");
|
||||
_renderPlugin = null;
|
||||
}
|
||||
|
||||
@ -550,22 +552,29 @@ namespace NavisworksTransport
|
||||
{
|
||||
try
|
||||
{
|
||||
if (point != null && _pathPointMarkers != null)
|
||||
if (point != null)
|
||||
{
|
||||
// 找到对应的PathPointMarker
|
||||
var marker = _pathPointMarkers.FirstOrDefault(m => m.PathPoint?.Id == point.Id);
|
||||
if (marker != null)
|
||||
if (_pathPointMarkers != null)
|
||||
{
|
||||
_pathPointMarkers.Remove(marker);
|
||||
_renderPlugin?.RemovePathPointMarker(marker);
|
||||
LogManager.Info($"已从3D中移除路径点: {point.Name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果找不到marker,直接调用RemovePathPointMarker的PathPoint重载
|
||||
_renderPlugin?.RemovePathPointMarker(point);
|
||||
// 找到对应的PathPointMarker
|
||||
var marker = _pathPointMarkers.FirstOrDefault(m => m.PathPoint?.Id == point.Id);
|
||||
if (marker != null)
|
||||
{
|
||||
_pathPointMarkers.Remove(marker);
|
||||
_renderPlugin?.RemovePathPointMarker(marker);
|
||||
LogManager.Info($"已从3D中移除路径点标记: {point.Name}");
|
||||
}
|
||||
}
|
||||
|
||||
// 同时尝试通过坐标移除3D标记
|
||||
if (_renderPlugin != null)
|
||||
{
|
||||
_renderPlugin.RemoveMarkerAt(point.Position, 2.0);
|
||||
LogManager.Info($"已从3D中移除路径点: {point.Name}");
|
||||
}
|
||||
|
||||
// 触发路径点移除事件
|
||||
RaisePathPointOperation(PathPointOperationType.Removed, point, CurrentRoute);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -1034,6 +1043,15 @@ namespace NavisworksTransport
|
||||
lastPoint.Type = PathPointType.EndPoint;
|
||||
lastPoint.Name = GeneratePointName(PathPointType.EndPoint);
|
||||
|
||||
// 更新3D标记类型
|
||||
if (_renderPlugin != null)
|
||||
{
|
||||
// 移除旧标记
|
||||
_renderPlugin.RemoveMarkerAt(lastPoint.Position, 2.0);
|
||||
// 添加终点标记
|
||||
_renderPlugin.AddCircleMarker(lastPoint.Position, PathPointType.EndPoint, CurrentRoute.Points.Count);
|
||||
}
|
||||
|
||||
LogManager.Info($"已自动设置最后一个点为终点: {lastPoint.Name}");
|
||||
}
|
||||
}
|
||||
@ -1168,6 +1186,17 @@ namespace NavisworksTransport
|
||||
CurrentRoute.Points.Add(pathPoint);
|
||||
LogManager.Info($"路径点已添加: {pathPoint.Name}, 位置: ({worldPoint.X:F2}, {worldPoint.Y:F2}, {worldPoint.Z:F2})");
|
||||
|
||||
// 绘制3D路径可视化(使用与自动路径规划相同的方法)
|
||||
try
|
||||
{
|
||||
DrawRouteVisualization(CurrentRoute, isAutoPath: false);
|
||||
LogManager.Info($"手工路径3D可视化已更新: {pathPoint.Name}");
|
||||
}
|
||||
catch (Exception renderEx)
|
||||
{
|
||||
LogManager.Error($"绘制手工路径3D可视化失败: {renderEx.Message}");
|
||||
}
|
||||
|
||||
// 触发路径点添加事件
|
||||
RaisePathPointOperation(PathPointOperationType.Added, pathPoint, CurrentRoute);
|
||||
|
||||
@ -1616,7 +1645,6 @@ namespace NavisworksTransport
|
||||
LogManager.WriteLog("[ToolPlugin事件-V2] ===== 收到精确点击坐标 =====");
|
||||
LogManager.WriteLog($"[ToolPlugin事件-V2] 精确坐标: ({pickResult.Point.X:F3}, {pickResult.Point.Y:F3}, {pickResult.Point.Z:F3})");
|
||||
LogManager.WriteLog($"[ToolPlugin事件-V2] 选中对象: {pickResult.ModelItem?.DisplayName ?? "NULL"}");
|
||||
LogManager.WriteLog($"[ToolPlugin事件-V2] 🔍 代码版本检查: 新版本代码正在运行");
|
||||
|
||||
// 检查当前选中的通道状态
|
||||
LogManager.WriteLog($"[ToolPlugin事件-V2] 当前_selectedChannels状态: {(_selectedChannels == null ? "NULL" : $"包含{_selectedChannels.Count}个项目")}");
|
||||
@ -2067,6 +2095,7 @@ namespace NavisworksTransport
|
||||
return PathPointType.WayPoint;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 绘制路径可视化
|
||||
/// </summary>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -51,6 +51,10 @@ namespace NavisworksTransport.PathPlanning
|
||||
// 验证输入参数
|
||||
ValidateInputs(start, end, gridMap);
|
||||
|
||||
// 保存原始起点和终点,用于最终路径修正
|
||||
var originalStart = start;
|
||||
var originalEnd = end;
|
||||
|
||||
// 设置路径规划的起点和终点,用于Z坐标插值
|
||||
gridMap.PlanningStartPoint = start;
|
||||
gridMap.PlanningEndPoint = end;
|
||||
@ -71,35 +75,15 @@ namespace NavisworksTransport.PathPlanning
|
||||
throw new AutoPathPlanningException($"终点({end.X:F2}, {end.Y:F2})超出网格范围");
|
||||
}
|
||||
|
||||
// 智能修正起点和终点位置
|
||||
var correctedStartGrid = FindNearestWalkablePosition(gridMap, startGrid, "起点");
|
||||
var correctedEndGrid = FindNearestWalkablePosition(gridMap, endGrid, "终点");
|
||||
|
||||
if (correctedStartGrid == null)
|
||||
// 🔥 移除权宜性措施:直接验证起点和终点是否可通行
|
||||
if (!gridMap.IsWalkable(startGrid))
|
||||
{
|
||||
throw new AutoPathPlanningException($"起点({start.X:F2}, {start.Y:F2})附近没有可通行区域");
|
||||
throw new AutoPathPlanningException($"起点({start.X:F2}, {start.Y:F2})位于障碍物上,请检查起点位置或确认是否在通道内");
|
||||
}
|
||||
|
||||
if (correctedEndGrid == null)
|
||||
if (!gridMap.IsWalkable(endGrid))
|
||||
{
|
||||
throw new AutoPathPlanningException($"终点({end.X:F2}, {end.Y:F2})附近没有可通行区域");
|
||||
}
|
||||
|
||||
// 如果位置被修正,记录日志
|
||||
if (correctedStartGrid.Value != startGrid)
|
||||
{
|
||||
var correctedWorldStart = gridMap.GridToWorld(correctedStartGrid.Value);
|
||||
LogManager.Info($"起点已自动修正: ({start.X:F2}, {start.Y:F2}) -> ({correctedWorldStart.X:F2}, {correctedWorldStart.Y:F2})");
|
||||
start = correctedWorldStart; // 更新起点
|
||||
startGrid = correctedStartGrid.Value;
|
||||
}
|
||||
|
||||
if (correctedEndGrid.Value != endGrid)
|
||||
{
|
||||
var correctedWorldEnd = gridMap.GridToWorld(correctedEndGrid.Value);
|
||||
LogManager.Info($"终点已自动修正: ({end.X:F2}, {end.Y:F2}) -> ({correctedWorldEnd.X:F2}, {correctedWorldEnd.Y:F2})");
|
||||
end = correctedWorldEnd; // 更新终点
|
||||
endGrid = correctedEndGrid.Value;
|
||||
throw new AutoPathPlanningException($"终点({end.X:F2}, {end.Y:F2})位于障碍物上,请检查起点位置或确认是否在通道内");
|
||||
}
|
||||
|
||||
// 转换为RoyT.AStar网格格式并执行A*算法
|
||||
@ -123,8 +107,14 @@ namespace NavisworksTransport.PathPlanning
|
||||
var optimizedPath = OptimizePath(worldPath, gridMap);
|
||||
var heightCorrectedPath = ApplyPreciseHeightCorrection(optimizedPath, gridMap);
|
||||
|
||||
LogManager.Info($"路径查找完成,最终包含 {heightCorrectedPath.Count} 个点");
|
||||
return heightCorrectedPath;
|
||||
// 🔥 关键修复:替换起点和终点为原始用户指定的坐标
|
||||
var correctedPath = CorrectStartEndPoints(heightCorrectedPath, originalStart, originalEnd);
|
||||
|
||||
LogManager.Info($"路径查找完成,最终包含 {correctedPath.Count} 个点");
|
||||
LogManager.Info($"起点坐标修正: 网格转换({heightCorrectedPath[0].X:F2}, {heightCorrectedPath[0].Y:F2}) -> 原始坐标({originalStart.X:F2}, {originalStart.Y:F2})");
|
||||
LogManager.Info($"终点坐标修正: 网格转换({heightCorrectedPath[heightCorrectedPath.Count-1].X:F2}, {heightCorrectedPath[heightCorrectedPath.Count-1].Y:F2}) -> 原始坐标({originalEnd.X:F2}, {originalEnd.Y:F2})");
|
||||
|
||||
return correctedPath;
|
||||
}
|
||||
catch (AutoPathPlanningException)
|
||||
{
|
||||
@ -653,95 +643,48 @@ namespace NavisworksTransport.PathPlanning
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找最近的可通行位置
|
||||
/// 修正路径的起点和终点为原始用户指定的坐标,避免网格转换造成的错位
|
||||
/// </summary>
|
||||
/// <param name="gridMap">网格地图</param>
|
||||
/// <param name="originalPos">原始位置</param>
|
||||
/// <param name="positionName">位置名称(用于日志)</param>
|
||||
/// <param name="maxDistance">最大搜索距离(网格单位)</param>
|
||||
/// <returns>最近的可通行位置,如果找不到返回null</returns>
|
||||
private Point2D? FindNearestWalkablePosition(GridMap gridMap, Point2D originalPos, string positionName, int maxDistance = 10)
|
||||
/// <param name="path">原始路径</param>
|
||||
/// <param name="originalStart">原始起点坐标</param>
|
||||
/// <param name="originalEnd">原始终点坐标</param>
|
||||
/// <returns>修正后的路径</returns>
|
||||
private List<Point3D> CorrectStartEndPoints(List<Point3D> path, Point3D originalStart, Point3D originalEnd)
|
||||
{
|
||||
if (path == null || path.Count == 0)
|
||||
return path;
|
||||
|
||||
try
|
||||
{
|
||||
// 如果原始位置已经可通行,直接返回
|
||||
if (gridMap.IsWalkable(originalPos))
|
||||
LogManager.Info($"[坐标修正] 开始修正路径起终点坐标");
|
||||
var correctedPath = new List<Point3D>(path);
|
||||
|
||||
// 修正起点:保持原始XY坐标,使用路径的Z坐标
|
||||
if (correctedPath.Count > 0)
|
||||
{
|
||||
return originalPos;
|
||||
var originalStartWithZ = new Point3D(originalStart.X, originalStart.Y, correctedPath[0].Z);
|
||||
LogManager.Info($"[坐标修正] 起点: ({correctedPath[0].X:F3}, {correctedPath[0].Y:F3}, {correctedPath[0].Z:F3}) -> ({originalStartWithZ.X:F3}, {originalStartWithZ.Y:F3}, {originalStartWithZ.Z:F3})");
|
||||
correctedPath[0] = originalStartWithZ;
|
||||
}
|
||||
|
||||
LogManager.Info($"[位置修正] {positionName}({originalPos.X}, {originalPos.Y})不可通行,搜索附近可通行区域...");
|
||||
|
||||
// 使用BFS搜索最近的可通行位置
|
||||
var visited = new HashSet<Point2D>();
|
||||
var queue = new Queue<(Point2D pos, int distance)>();
|
||||
|
||||
queue.Enqueue((originalPos, 0));
|
||||
visited.Add(originalPos);
|
||||
|
||||
// 8个方向的偏移量
|
||||
var directions = new[]
|
||||
// 修正终点:保持原始XY坐标,使用路径的Z坐标
|
||||
if (correctedPath.Count > 1)
|
||||
{
|
||||
new Point2D(0, 1), // 上
|
||||
new Point2D(0, -1), // 下
|
||||
new Point2D(1, 0), // 右
|
||||
new Point2D(-1, 0), // 左
|
||||
new Point2D(1, 1), // 右上
|
||||
new Point2D(1, -1), // 右下
|
||||
new Point2D(-1, 1), // 左上
|
||||
new Point2D(-1, -1) // 左下
|
||||
};
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var (currentPos, distance) = queue.Dequeue();
|
||||
|
||||
// 超出最大搜索距离,停止搜索
|
||||
if (distance > maxDistance)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// 检查8个方向的邻居
|
||||
foreach (var dir in directions)
|
||||
{
|
||||
var neighborPos = new Point2D(currentPos.X + dir.X, currentPos.Y + dir.Y);
|
||||
|
||||
// 跳过已访问的位置
|
||||
if (visited.Contains(neighborPos))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
visited.Add(neighborPos);
|
||||
|
||||
// 检查是否在有效范围内
|
||||
if (!gridMap.IsValidGridPosition(neighborPos))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 找到可通行位置
|
||||
if (gridMap.IsWalkable(neighborPos))
|
||||
{
|
||||
var worldPos = gridMap.GridToWorld(neighborPos);
|
||||
LogManager.Info($"[位置修正] {positionName}已修正到距离{distance + 1}格的位置: 网格({neighborPos.X}, {neighborPos.Y}) 世界({worldPos.X:F2}, {worldPos.Y:F2})");
|
||||
return neighborPos;
|
||||
}
|
||||
|
||||
// 添加到搜索队列
|
||||
queue.Enqueue((neighborPos, distance + 1));
|
||||
}
|
||||
var lastIndex = correctedPath.Count - 1;
|
||||
var originalEndWithZ = new Point3D(originalEnd.X, originalEnd.Y, correctedPath[lastIndex].Z);
|
||||
LogManager.Info($"[坐标修正] 终点: ({correctedPath[lastIndex].X:F3}, {correctedPath[lastIndex].Y:F3}, {correctedPath[lastIndex].Z:F3}) -> ({originalEndWithZ.X:F3}, {originalEndWithZ.Y:F3}, {originalEndWithZ.Z:F3})");
|
||||
correctedPath[lastIndex] = originalEndWithZ;
|
||||
}
|
||||
|
||||
LogManager.Warning($"[位置修正] {positionName}在{maxDistance}格范围内未找到可通行区域");
|
||||
return null;
|
||||
LogManager.Info($"[坐标修正] 路径起终点坐标修正完成");
|
||||
return correctedPath;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[位置修正] {positionName}位置修正失败: {ex.Message}");
|
||||
return null;
|
||||
LogManager.Error($"[坐标修正] 修正路径起终点坐标失败: {ex.Message},使用原始路径");
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,11 @@ namespace NavisworksTransport.UI.WPF.Converters
|
||||
/// </summary>
|
||||
public class BoolToVisibilityConverter : IValueConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// 静态实例:将非空对象转换为true
|
||||
/// </summary>
|
||||
public static readonly IValueConverter IsNotNullToBoolConverter = new IsNotNullToBoolConverter();
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
@ -38,4 +43,20 @@ namespace NavisworksTransport.UI.WPF.Converters
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对象非空到布尔值的转换器
|
||||
/// </summary>
|
||||
public class IsNotNullToBoolConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value != null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException("IsNotNullToBoolConverter不支持反向转换");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -23,99 +23,7 @@
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="路径编辑" Name="PathEditingTab">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Margin="10">
|
||||
<GroupBox Header="路径列表管理" Margin="0,10" Height="160">
|
||||
<StackPanel Margin="10">
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,10">
|
||||
<Button Content="新建" Command="{Binding NewPathCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="删除" Command="{Binding DeletePathCommand}" Margin="0,0,10,0"/>
|
||||
</StackPanel>
|
||||
<ListView ItemsSource="{Binding PathRoutes}"
|
||||
SelectedItem="{Binding SelectedPathRoute}"
|
||||
Height="100">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="路径名称" DisplayMemberBinding="{Binding Name}" Width="120"/>
|
||||
<GridViewColumn Header="点数" DisplayMemberBinding="{Binding PointCount}" Width="50"/>
|
||||
<GridViewColumn Header="状态" DisplayMemberBinding="{Binding StatusString}" Width="60"/>
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="自动路径规划" Margin="0,10" Height="180">
|
||||
<StackPanel Margin="10">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="0" Content="起点:" VerticalAlignment="Center"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding AutoPathStartPoint}" Margin="5,2" IsReadOnly="True" Background="LightGray"/>
|
||||
<Button Grid.Row="0" Grid.Column="2" Content="选择" Command="{Binding SelectStartPointCommand}" Margin="5,2" Padding="5,2"/>
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="终点:" VerticalAlignment="Center"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding AutoPathEndPoint}" Margin="5,2" IsReadOnly="True" Background="LightGray"/>
|
||||
<Button Grid.Row="1" Grid.Column="2" Content="选择" Command="{Binding SelectEndPointCommand}" Margin="5,2" Padding="5,2"/>
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="0" Content="车辆尺寸:" VerticalAlignment="Center"/>
|
||||
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding AutoPathVehicleSize}" Margin="5,2"/>
|
||||
<Label Grid.Row="2" Grid.Column="2" Content="米" VerticalAlignment="Center" Margin="5,2"/>
|
||||
|
||||
<StackPanel Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3" Orientation="Horizontal" Margin="0,10,0,0">
|
||||
<Button Content="自动规划路径" Command="{Binding AutoPlanPathCommand}" Margin="0,0,10,0" Padding="10,5" Background="LightBlue"/>
|
||||
<Button Content="重置" Command="{Binding ClearAutoPathCommand}" Margin="0,0,10,0" Padding="10,5"/>
|
||||
<TextBlock Text="{Binding AutoPathStatus}" VerticalAlignment="Center" Foreground="Blue" FontSize="10"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="当前路径编辑" Margin="0,10" Height="250">
|
||||
<StackPanel Margin="10">
|
||||
<Label Content="{Binding SelectedPathRoute.Name, StringFormat='当前路径: {0}'}"/>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,10">
|
||||
<Button Content="开始编辑" Command="{Binding StartEditCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="结束编辑" Command="{Binding EndEditCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="清空路径" Command="{Binding ClearPathCommand}"/>
|
||||
</StackPanel>
|
||||
<ListView ItemsSource="{Binding SelectedPathRoute.Points}" Height="150">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="点名称" DisplayMemberBinding="{Binding Name}" Width="80"/>
|
||||
<GridViewColumn Header="坐标" DisplayMemberBinding="{Binding CoordinateString}" Width="150"/>
|
||||
<GridViewColumn Header="操作" Width="60">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Button Content="删除" Command="{Binding DataContext.DeletePointCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
CommandParameter="{Binding}" FontSize="10" Padding="2"/>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="路径文件管理" Margin="0,10">
|
||||
<StackPanel Orientation="Horizontal" Margin="10">
|
||||
<Button Content="导入路径" Name="ImportPathButton" Margin="0,0,10,0"/>
|
||||
<Button Content="导出路径" Name="ExportPathButton"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
<views:PathEditingView x:Name="PathEditingView"/>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="检测动画" Name="AnimationControlTab">
|
||||
|
||||
@ -66,6 +66,9 @@ namespace NavisworksTransport.UI.WPF
|
||||
// 确保AnimationControlView能够接收当前选中的路径
|
||||
InitializeAnimationControlView();
|
||||
|
||||
// 初始化PathEditingView
|
||||
InitializePathEditingView();
|
||||
|
||||
LogManager.Info("子视图初始化完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -106,8 +109,17 @@ namespace NavisworksTransport.UI.WPF
|
||||
{
|
||||
LogManager.Info("开始初始化PathPlanningManager");
|
||||
|
||||
// 创建或获取PathPlanningManager实例
|
||||
_pathPlanningManager = PathPlanningManager.GetActivePathManager() ?? new PathPlanningManager();
|
||||
// 获取或创建唯一的PathPlanningManager实例
|
||||
_pathPlanningManager = PathPlanningManager.GetActivePathManager();
|
||||
if (_pathPlanningManager == null)
|
||||
{
|
||||
_pathPlanningManager = new PathPlanningManager();
|
||||
LogManager.Info("创建了新的PathPlanningManager实例");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Info("使用已存在的PathPlanningManager实例");
|
||||
}
|
||||
|
||||
// TODO: 后续任务中将重新实现事件订阅
|
||||
// 暂时注释掉事件订阅,避免编译错误
|
||||
@ -138,12 +150,7 @@ namespace NavisworksTransport.UI.WPF
|
||||
{
|
||||
if (AnimationControlView?.ViewModel != null)
|
||||
{
|
||||
// 如果已有选中的路径,同步到AnimationControlView
|
||||
if (ViewModel?.SelectedPathRoute != null)
|
||||
{
|
||||
AnimationControlView.ViewModel.SetCurrentPath(ViewModel.SelectedPathRoute);
|
||||
}
|
||||
|
||||
// 动画控制视图现在通过PathEditingView获取路径信息
|
||||
LogManager.Info("AnimationControlView初始化完成");
|
||||
}
|
||||
}
|
||||
@ -153,6 +160,27 @@ namespace NavisworksTransport.UI.WPF
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化PathEditingView
|
||||
/// </summary>
|
||||
private void InitializePathEditingView()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (PathEditingView?.ViewModel != null)
|
||||
{
|
||||
// 将PathPlanningManager传递给PathEditingView
|
||||
PathEditingView.ViewModel.PathPlanningManager = _pathPlanningManager;
|
||||
|
||||
LogManager.Info("PathEditingView初始化完成");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"初始化PathEditingView失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化事件处理器
|
||||
/// </summary>
|
||||
@ -178,6 +206,12 @@ namespace NavisworksTransport.UI.WPF
|
||||
ViewModel.PropertyChanged += OnMainViewModelPropertyChanged;
|
||||
}
|
||||
|
||||
// 订阅PathEditingView的路径选择变化事件
|
||||
if (PathEditingView?.ViewModel != null)
|
||||
{
|
||||
PathEditingView.ViewModel.PropertyChanged += OnPathEditingViewModelPropertyChanged;
|
||||
}
|
||||
|
||||
LogManager.Info("事件处理器初始化完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -237,9 +271,18 @@ namespace NavisworksTransport.UI.WPF
|
||||
ViewModel.PropertyChanged -= OnMainViewModelPropertyChanged;
|
||||
}
|
||||
|
||||
// 取消PathEditingView事件订阅
|
||||
if (PathEditingView?.ViewModel != null)
|
||||
{
|
||||
PathEditingView.ViewModel.PropertyChanged -= OnPathEditingViewModelPropertyChanged;
|
||||
}
|
||||
|
||||
// 清理AnimationControlView
|
||||
AnimationControlView?.Cleanup();
|
||||
|
||||
// 清理PathEditingView
|
||||
PathEditingView?.Cleanup();
|
||||
|
||||
// TODO: 清理路径规划管理器事件订阅
|
||||
// 暂时注释掉,避免编译错误
|
||||
/*
|
||||
@ -298,11 +341,8 @@ namespace NavisworksTransport.UI.WPF
|
||||
{
|
||||
try
|
||||
{
|
||||
if (e.PropertyName == nameof(LogisticsControlViewModel.SelectedPathRoute))
|
||||
{
|
||||
// 当主ViewModel的选中路径变化时,同步到AnimationControlView
|
||||
SyncCurrentPathToAnimationView();
|
||||
}
|
||||
// 主ViewModel已不再包含路径相关属性,路径管理由PathEditingViewModel负责
|
||||
// 这里可以处理其他属性变化事件
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -310,6 +350,26 @@ namespace NavisworksTransport.UI.WPF
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PathEditingViewModel属性变化事件处理
|
||||
/// </summary>
|
||||
private void OnPathEditingViewModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (e.PropertyName == nameof(PathEditingViewModel.SelectedPathRoute))
|
||||
{
|
||||
// 当PathEditingViewModel的选中路径变化时,同步到AnimationControlView
|
||||
SyncCurrentPathToAnimationView();
|
||||
LogManager.Info("PathEditingView路径选择已变化,同步到动画控制视图");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"PathEditingViewModel属性变化处理失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步当前路径到动画控制视图
|
||||
/// </summary>
|
||||
@ -317,10 +377,29 @@ namespace NavisworksTransport.UI.WPF
|
||||
{
|
||||
try
|
||||
{
|
||||
if (AnimationControlView?.ViewModel != null && ViewModel?.SelectedPathRoute != null)
|
||||
if (AnimationControlView?.ViewModel != null)
|
||||
{
|
||||
AnimationControlView.ViewModel.SetCurrentPath(ViewModel.SelectedPathRoute);
|
||||
LogManager.Info($"路径已同步到动画控制视图: {ViewModel.SelectedPathRoute.Name}");
|
||||
// 优先从PathEditingView获取选中的路径
|
||||
PathRouteViewModel selectedPath = null;
|
||||
|
||||
if (PathEditingView?.ViewModel?.SelectedPathRoute != null)
|
||||
{
|
||||
selectedPath = PathEditingView.ViewModel.SelectedPathRoute;
|
||||
LogManager.Info($"从PathEditingView同步路径: {selectedPath.Name}");
|
||||
}
|
||||
// 主ViewModel不再包含SelectedPathRoute,仅从PathEditingView获取路径
|
||||
|
||||
if (selectedPath != null)
|
||||
{
|
||||
AnimationControlView.ViewModel.SetCurrentPath(selectedPath);
|
||||
LogManager.Info($"路径已同步到动画控制视图: {selectedPath.Name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 清空动画控制视图的路径
|
||||
AnimationControlView.ViewModel.SetCurrentPath(null);
|
||||
LogManager.Info("已清空动画控制视图的路径");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
3817
src/UI/WPF/ViewModels/LogisticsControlViewModelcopy.cs
Normal file
3817
src/UI/WPF/ViewModels/LogisticsControlViewModelcopy.cs
Normal file
File diff suppressed because it is too large
Load Diff
1327
src/UI/WPF/ViewModels/PathEditingViewModel.cs
Normal file
1327
src/UI/WPF/ViewModels/PathEditingViewModel.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,119 +1,386 @@
|
||||
<!--
|
||||
NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管理一致的Navisworks 2026风格
|
||||
|
||||
功能说明:
|
||||
1. 自动路径规划:起终点选择、车辆尺寸参数(长宽高)、安全间隙设置
|
||||
2. 路径列表管理:新建、删除、重命名路径,显示路径状态
|
||||
3. 手动路径编辑:开始编辑、结束编辑、清空路径、路径点管理
|
||||
4. 路径文件管理:导入、导出、另存为操作和状态显示
|
||||
|
||||
设计原则:与Navisworks 2026风格一致,480像素宽度,现代化UI布局,采用GroupBox分组
|
||||
-->
|
||||
<UserControl x:Class="NavisworksTransport.UI.WPF.Views.PathEditingView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:converters="clr-namespace:NavisworksTransport.UI.WPF.Converters"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="400">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Margin="10">
|
||||
<GroupBox Header="路径列表管理" Margin="0,10" Height="160">
|
||||
<StackPanel Margin="10">
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,10">
|
||||
<Button Content="新建" Command="{Binding NewPathCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="删除" Command="{Binding DeletePathCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="重命名" Command="{Binding RenamePathCommand}"/>
|
||||
</StackPanel>
|
||||
<ListView ItemsSource="{Binding PathRoutes}"
|
||||
SelectedItem="{Binding SelectedPathRoute}"
|
||||
Height="100">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="路径名称" DisplayMemberBinding="{Binding Name}" Width="120"/>
|
||||
<GridViewColumn Header="点数" DisplayMemberBinding="{Binding PointCount}" Width="50"/>
|
||||
<GridViewColumn Header="状态" DisplayMemberBinding="{Binding StatusString}" Width="60"/>
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
d:DesignHeight="800" d:DesignWidth="480">
|
||||
|
||||
<UserControl.Resources>
|
||||
<!-- 转换器资源 -->
|
||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisConverter"/>
|
||||
|
||||
<!-- Navisworks 2026 风格样式定义 -->
|
||||
<Style x:Key="SectionHeaderStyle" TargetType="Label">
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="Foreground" Value="#FF2B579A"/>
|
||||
<Setter Property="Padding" Value="0,5,0,2"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ActionButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#FF4472C4"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="#FF2B579A"/>
|
||||
<Setter Property="Padding" Value="10,5"/>
|
||||
<Setter Property="Margin" Value="0,0,10,0"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SecondaryButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#FFE7F1FF"/>
|
||||
<Setter Property="Foreground" Value="#FF2B579A"/>
|
||||
<Setter Property="BorderBrush" Value="#FF4472C4"/>
|
||||
<Setter Property="Padding" Value="8,4"/>
|
||||
<Setter Property="Margin" Value="0,0,8,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="StatusTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="#FF666666"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ParameterLabelStyle" TargetType="Label">
|
||||
<Setter Property="Width" Value="80"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="0,0,5,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ParameterInputStyle" TargetType="TextBox">
|
||||
<Setter Property="Width" Value="80"/>
|
||||
<Setter Property="Margin" Value="5,2"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="UnitLabelStyle" TargetType="Label">
|
||||
<Setter Property="Width" Value="30"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="2,0,0,0"/>
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="Foreground" Value="#FF666666"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ReadOnlyTextBoxStyle" TargetType="TextBox">
|
||||
<Setter Property="IsReadOnly" Value="True"/>
|
||||
<Setter Property="Background" Value="#FFF5F5F5"/>
|
||||
<Setter Property="BorderBrush" Value="#FFCCCCCC"/>
|
||||
<Setter Property="Padding" Value="5,3"/>
|
||||
<Setter Property="Margin" Value="5,2"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
|
||||
<StackPanel>
|
||||
|
||||
<GroupBox Header="自动路径规划" Margin="0,10" Height="210">
|
||||
<StackPanel Margin="10">
|
||||
<Grid>
|
||||
<!-- 区域1: 自动路径规划 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="自动路径规划" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
<!-- 起点和终点设置 -->
|
||||
<StackPanel Margin="0,10,0,10">
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
|
||||
<Button Content="选择起点"
|
||||
Command="{Binding SelectStartPointCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
Width="80"
|
||||
Margin="0,0,10,0"/>
|
||||
<TextBox Text="{Binding AutoPathStartPoint}"
|
||||
Style="{StaticResource ReadOnlyTextBoxStyle}"
|
||||
Width="280"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="选择终点"
|
||||
Command="{Binding SelectEndPointCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
Width="80"
|
||||
Margin="0,0,10,0"/>
|
||||
<TextBox Text="{Binding AutoPathEndPoint}"
|
||||
Style="{StaticResource ReadOnlyTextBoxStyle}"
|
||||
Width="280"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 车辆参数设置 - 改为三个独立参数 -->
|
||||
<Grid Margin="0,5,0,10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="0" Content="起点:" VerticalAlignment="Center"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding AutoPathStartPoint}" Margin="5,2" IsReadOnly="True" Background="LightGray"/>
|
||||
<Button Grid.Row="0" Grid.Column="2" Content="选择" Command="{Binding SelectStartPointCommand}" Margin="5,2" Padding="5,2"/>
|
||||
<!-- 车辆长度 -->
|
||||
<Label Grid.Row="0" Grid.Column="0" Content="车辆长度:" Style="{StaticResource ParameterLabelStyle}"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="1"
|
||||
Text="{Binding VehicleLength}"
|
||||
Style="{StaticResource ParameterInputStyle}"
|
||||
Width="60"/>
|
||||
<Label Grid.Row="0" Grid.Column="2" Content="米" Style="{StaticResource UnitLabelStyle}" Margin="0,0,15,0"/>
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="终点:" VerticalAlignment="Center"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding AutoPathEndPoint}" Margin="5,2" IsReadOnly="True" Background="LightGray"/>
|
||||
<Button Grid.Row="1" Grid.Column="2" Content="选择" Command="{Binding SelectEndPointCommand}" Margin="5,2" Padding="5,2"/>
|
||||
<!-- 车辆宽度 -->
|
||||
<Label Grid.Row="0" Grid.Column="3" Content="车辆宽度:" Style="{StaticResource ParameterLabelStyle}"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="4"
|
||||
Text="{Binding VehicleWidth}"
|
||||
Style="{StaticResource ParameterInputStyle}"
|
||||
Width="60"/>
|
||||
<Label Grid.Row="0" Grid.Column="5" Content="米" Style="{StaticResource UnitLabelStyle}"/>
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="0" Content="车辆尺寸:" VerticalAlignment="Center"/>
|
||||
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding AutoPathVehicleSize}" Margin="5,2"/>
|
||||
<Label Grid.Row="2" Grid.Column="2" Content="米" VerticalAlignment="Center" Margin="5,2"/>
|
||||
<!-- 车辆高度 -->
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="车辆高度:" Style="{StaticResource ParameterLabelStyle}"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="1"
|
||||
Text="{Binding VehicleHeight}"
|
||||
Style="{StaticResource ParameterInputStyle}"
|
||||
Width="60"/>
|
||||
<Label Grid.Row="1" Grid.Column="2" Content="米" Style="{StaticResource UnitLabelStyle}" Margin="0,0,15,0"/>
|
||||
|
||||
<Label Grid.Row="3" Grid.Column="0" Content="安全间隙:" VerticalAlignment="Center"/>
|
||||
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding AutoPathSafetyMargin}" Margin="5,2"/>
|
||||
<Label Grid.Row="3" Grid.Column="2" Content="米" VerticalAlignment="Center" Margin="5,2"/>
|
||||
|
||||
<StackPanel Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="3" Orientation="Horizontal" Margin="0,10,0,0">
|
||||
<Button Content="自动规划路径" Command="{Binding AutoPlanPathCommand}" Margin="0,0,10,0" Padding="10,5" Background="LightBlue"/>
|
||||
<Button Content="重置" Command="{Binding ClearAutoPathCommand}" Margin="0,0,10,0" Padding="10,5"/>
|
||||
<TextBlock Text="{Binding AutoPathStatus}" VerticalAlignment="Center" Foreground="Blue" FontSize="10"/>
|
||||
</StackPanel>
|
||||
<!-- 安全间隙 -->
|
||||
<Label Grid.Row="1" Grid.Column="3" Content="安全间隙:" Style="{StaticResource ParameterLabelStyle}"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="4"
|
||||
Text="{Binding SafetyMargin}"
|
||||
Style="{StaticResource ParameterInputStyle}"
|
||||
Width="60"/>
|
||||
<Label Grid.Row="1" Grid.Column="5" Content="米" Style="{StaticResource UnitLabelStyle}"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="当前路径编辑" Margin="0,10" Height="250">
|
||||
<StackPanel Margin="10">
|
||||
<Label Content="{Binding SelectedPathRoute.Name, StringFormat='当前路径: {0}'}"/>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,10">
|
||||
<Button Content="开始编辑" Command="{Binding StartEditCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="结束编辑" Command="{Binding EndEditCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="清空路径" Command="{Binding ClearPathCommand}"/>
|
||||
|
||||
<!-- 规划操作按钮 -->
|
||||
<StackPanel Orientation="Horizontal" Margin="0,10,0,5">
|
||||
<Button Content="自动规划路径"
|
||||
Command="{Binding AutoPlanPathCommand}"
|
||||
Style="{StaticResource ActionButtonStyle}"
|
||||
IsEnabled="{Binding CanExecuteAutoPlanPath}"/>
|
||||
<Button Content="重置参数"
|
||||
Command="{Binding ClearAutoPathCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"/>
|
||||
</StackPanel>
|
||||
<ListView ItemsSource="{Binding SelectedPathRoute.Points}" Height="150">
|
||||
|
||||
<!-- 状态显示 -->
|
||||
<TextBlock Text="{Binding AutoPathStatus}"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="#FF2B579A"
|
||||
Margin="0,5,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 区域2: 路径列表管理 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="路径列表管理" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
<!-- 路径管理按钮 -->
|
||||
<StackPanel Orientation="Horizontal" Margin="0,10,0,10">
|
||||
<Button Content="新建路径"
|
||||
Command="{Binding NewPathCommand}"
|
||||
Style="{StaticResource ActionButtonStyle}"/>
|
||||
<Button Content="删除路径"
|
||||
Command="{Binding DeletePathCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
IsEnabled="{Binding SelectedPathRoute, Converter={x:Static converters:BoolToVisibilityConverter.IsNotNullToBoolConverter}}"/>
|
||||
<Button Content="重命名"
|
||||
Command="{Binding RenamePathCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
IsEnabled="{Binding SelectedPathRoute, Converter={x:Static converters:BoolToVisibilityConverter.IsNotNullToBoolConverter}}"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 路径列表 -->
|
||||
<ListView ItemsSource="{Binding PathRoutes}"
|
||||
SelectedItem="{Binding SelectedPathRoute}"
|
||||
Height="120"
|
||||
BorderBrush="#FFCCCCCC"
|
||||
BorderThickness="1">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="路径名称" DisplayMemberBinding="{Binding Name}" Width="160"/>
|
||||
<GridViewColumn Header="点数" DisplayMemberBinding="{Binding PointCount}" Width="50"/>
|
||||
<GridViewColumn Header="状态" DisplayMemberBinding="{Binding StatusString}" Width="60"/>
|
||||
<GridViewColumn Header="创建时间" DisplayMemberBinding="{Binding CreatedTime, StringFormat='MM-dd HH:mm'}" Width="90"/>
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
|
||||
<!-- 当前路径信息 -->
|
||||
<TextBlock Text="{Binding SelectedPathRoute.Name, StringFormat='当前选择: {0}', TargetNullValue='当前选择: 无'}"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="#FF2B579A"
|
||||
Margin="0,5,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 区域3: 手动路径编辑 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="手动路径编辑" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
<!-- 编辑控制按钮 -->
|
||||
<StackPanel Orientation="Horizontal" Margin="0,10,0,10">
|
||||
<Button Content="开始编辑"
|
||||
Command="{Binding StartEditCommand}"
|
||||
Style="{StaticResource ActionButtonStyle}"
|
||||
IsEnabled="{Binding CanExecuteStartEdit}"/>
|
||||
<Button Content="结束编辑"
|
||||
Command="{Binding EndEditCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
IsEnabled="{Binding CanExecuteEndEdit}"/>
|
||||
<Button Content="清空路径"
|
||||
Command="{Binding ClearPathCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
Background="#FFFFE6E6"
|
||||
Foreground="#FF8B0000"
|
||||
IsEnabled="{Binding CanExecuteClearPath}"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 当前路径信息 -->
|
||||
<Grid Margin="0,5,0,10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Grid.Column="0" Content="编辑路径:" Style="{StaticResource ParameterLabelStyle}"/>
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding SelectedPathRoute.Name, TargetNullValue='未选择路径'}"
|
||||
VerticalAlignment="Center"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{Binding SelectedPathRoute, Converter={x:Null}, TargetNullValue='#FF999999'}"
|
||||
Background="#FFF5F5F5"
|
||||
Padding="5,3"
|
||||
Margin="5,0"/>
|
||||
</Grid>
|
||||
|
||||
<!-- 路径点列表 -->
|
||||
<ListView ItemsSource="{Binding SelectedPathRoute.Points}"
|
||||
Height="150"
|
||||
BorderBrush="#FFCCCCCC"
|
||||
BorderThickness="1">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="点名称" DisplayMemberBinding="{Binding Name}" Width="80"/>
|
||||
<GridViewColumn Header="坐标" DisplayMemberBinding="{Binding CoordinateString}" Width="150"/>
|
||||
<GridViewColumn Header="坐标" DisplayMemberBinding="{Binding CoordinateString}" Width="140"/>
|
||||
<GridViewColumn Header="类型" DisplayMemberBinding="{Binding TypeDisplayString}" Width="60"/>
|
||||
<GridViewColumn Header="操作" Width="60">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Button Content="删除" Command="{Binding DataContext.DeletePointCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
CommandParameter="{Binding}" FontSize="10" Padding="2"/>
|
||||
<Button Content="删除"
|
||||
Command="{Binding DataContext.DeletePointCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
CommandParameter="{Binding}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
Background="#FFFFE6E6"
|
||||
Foreground="#FF8B0000"
|
||||
FontSize="9"
|
||||
Padding="2"
|
||||
Margin="0"/>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
|
||||
<!-- 编辑提示 -->
|
||||
<TextBlock Text="提示:开始编辑后,在3D视图中点击可通行的物流模型来添加路径点"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Foreground="#FF666666"
|
||||
Margin="0,5,0,0"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</Border>
|
||||
|
||||
<GroupBox Header="路径文件管理" Margin="0,10">
|
||||
<StackPanel Margin="10">
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,10">
|
||||
<Button Content="导入路径" Command="{Binding ImportPathCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="导出路径" Command="{Binding ExportPathCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="另存为" Command="{Binding SaveAsPathCommand}"/>
|
||||
<!-- 区域4: 路径文件管理 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="路径文件管理" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
<!-- 文件操作按钮 -->
|
||||
<StackPanel Orientation="Horizontal" Margin="0,10,0,10">
|
||||
<Button Content="导入路径"
|
||||
Command="{Binding ImportPathCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"/>
|
||||
<Button Content="导出路径"
|
||||
Command="{Binding ExportPathCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
IsEnabled="{Binding CanExecuteExportPath}"/>
|
||||
<Button Content="另存为"
|
||||
Command="{Binding SaveAsPathCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
IsEnabled="{Binding CanExecuteSaveAsPath}"/>
|
||||
</StackPanel>
|
||||
<Label Content="{Binding PathFileStatus}" Foreground="DarkBlue" FontSize="10"/>
|
||||
|
||||
<!-- 文件状态显示 -->
|
||||
<Grid Margin="0,5,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Grid.Column="0" Content="文件状态:" Style="{StaticResource ParameterLabelStyle}"/>
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding PathFileStatus}"
|
||||
VerticalAlignment="Center"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="#FF2B579A"
|
||||
Margin="5,0"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</Border>
|
||||
|
||||
<GroupBox Header="3D交互提示" Margin="0,10">
|
||||
<StackPanel Margin="10">
|
||||
<Label Content="• 开始编辑后,在3D视图中点击添加路径点" FontSize="10"/>
|
||||
<Label Content="• 右键点击路径点可删除" FontSize="10"/>
|
||||
<Label Content="• 拖拽路径点可调整位置" FontSize="10"/>
|
||||
<!-- 区域5: 3D交互指南 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="4" Margin="0,0,0,0" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="3D交互操作指南" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
<!-- 操作说明 -->
|
||||
<StackPanel Margin="0,5,0,0">
|
||||
<TextBlock Text="自动路径规划:"
|
||||
FontWeight="SemiBold"
|
||||
Margin="0,2"/>
|
||||
<TextBlock Text="• 点击"选择"按钮后在3D视图中点击设置起点和终点"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="10,2"/>
|
||||
<TextBlock Text="• 调整车辆尺寸和安全间隙参数后点击"自动规划路径""
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="10,2"/>
|
||||
|
||||
<TextBlock Text="手动路径编辑:"
|
||||
FontWeight="SemiBold"
|
||||
Margin="0,8,0,2"/>
|
||||
<TextBlock Text="• 选择路径后点击"开始编辑"进入编辑模式"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="10,2"/>
|
||||
<TextBlock Text="• 在3D视图中点击可通行的物流模型添加路径点"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="10,2"/>
|
||||
<TextBlock Text="• 使用列表中的"删除"按钮移除不需要的路径点"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="10,2"/>
|
||||
<TextBlock Text="• 编辑完成后点击"结束编辑"保存修改"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Margin="10,2"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</Border>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
@ -1,15 +1,48 @@
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using NavisworksTransport.UI.WPF.ViewModels;
|
||||
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; }
|
||||
|
||||
public PathEditingView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// 创建并设置ViewModel
|
||||
ViewModel = new PathEditingViewModel();
|
||||
DataContext = ViewModel;
|
||||
|
||||
LogManager.Info("PathEditingView初始化完成");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理资源
|
||||
/// </summary>
|
||||
public void Cleanup()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 清理ViewModel
|
||||
ViewModel?.Cleanup();
|
||||
|
||||
LogManager.Info("PathEditingView资源清理完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"PathEditingView清理失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user