using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Linq;
using NavisworksTransport.Core;
namespace NavisworksTransport.UI.WPF.ViewModels
{
///
/// 路径点数据类 (UI ViewModel)
/// 已重构为线程安全的ViewModel,继承自ViewModelBase
///
public class PathPointViewModel : ViewModelBase
{
private string _id;
private double _x;
private double _y;
private double _z;
private string _name;
private NavisworksTransport.PathPointType _type; // 使用完全限定名
private int _index; // 路径点在列表中的索引
///
/// 路径点ID
///
public string Id
{
get => _id;
set => SetProperty(ref _id, value);
}
///
/// X坐标
///
public double X
{
get => _x;
set
{
if (SetProperty(ref _x, value))
{
OnPropertyChanged(nameof(CoordinateString));
}
}
}
///
/// Y坐标
///
public double Y
{
get => _y;
set
{
if (SetProperty(ref _y, value))
{
OnPropertyChanged(nameof(CoordinateString));
}
}
}
///
/// Z坐标
///
public double Z
{
get => _z;
set
{
if (SetProperty(ref _z, value))
{
OnPropertyChanged(nameof(CoordinateString));
}
}
}
///
/// 点名称
///
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
///
/// 点类型
///
public NavisworksTransport.PathPointType Type // 使用完全限定名
{
get => _type;
set
{
if (SetProperty(ref _type, value))
{
// 当Type变更时,自动触发TypeDisplayString的更新
OnPropertyChanged(nameof(TypeDisplayString));
}
}
}
///
/// 点类型的显示字符串
///
public string TypeDisplayString
{
get
{
switch (Type)
{
case NavisworksTransport.PathPointType.StartPoint:
return "起点";
case NavisworksTransport.PathPointType.EndPoint:
return "终点";
default:
return "途经点";
}
}
}
///
/// 路径点在列表中的索引
///
public int Index
{
get => _index;
set => SetProperty(ref _index, value);
}
///
/// 坐标字符串表示
///
public string CoordinateString => $"({X:F2}, {Y:F2}, {Z:F2})";
#region 构造函数
///
/// 初始化PathPointViewModel
///
public PathPointViewModel() : base()
{
// 设置默认值
_id = Guid.NewGuid().ToString();
_name = "路径点";
_type = NavisworksTransport.PathPointType.WayPoint;
_x = 0.0;
_y = 0.0;
_z = 0.0;
}
///
/// 使用指定参数初始化PathPointViewModel
///
/// 点名称
/// X坐标
/// Y坐标
/// Z坐标
/// 点类型
public PathPointViewModel(string name, double x, double y, double z, NavisworksTransport.PathPointType type = NavisworksTransport.PathPointType.WayPoint) : base()
{
_id = Guid.NewGuid().ToString();
_name = name ?? "路径点";
_x = x;
_y = y;
_z = z;
_type = type;
}
#endregion
}
///
/// 路径视图模型类 - 用于WPF数据绑定
/// 已重构为线程安全的ViewModel,集成UIStateManager和ThreadSafeObservableCollection
///
public class PathRouteViewModel : ViewModelBase
{
#region 私有字段
private PathRoute _route; // 核心路径对象引用
private string _id;
private string _name;
private ObservableCollection _points;
private bool _isActive;
private string _description;
private DateTime _createdTime;
private DateTime _lastModifiedTime;
private bool _isValidated;
private string _validationStatus;
private PathType _pathType;
// UI状态管理
private readonly UIStateManager _uiStateManager;
private bool _isInitialized = false;
#endregion
#region 公共属性
///
/// 核心路径对象(直接引用,避免数据重复)
///
public PathRoute Route
{
get => _route;
set
{
if (SetProperty(ref _route, value))
{
// Route变化时,通知所有从Route读取的属性更新
OnPropertyChanged(nameof(Id));
OnPropertyChanged(nameof(Name));
OnPropertyChanged(nameof(Description));
OnPropertyChanged(nameof(PathType));
OnPropertyChanged(nameof(TotalLength));
OnPropertyChanged(nameof(CreatedTime));
OnPropertyChanged(nameof(LastModifiedTime));
}
}
}
///
/// 路径ID
///
public string Id
{
get => Route?.Id ?? _id;
set => SetProperty(ref _id, value);
}
///
/// 路径名称
///
public string Name
{
get => Route?.Name ?? _name;
set
{
if (SetProperty(ref _name, value))
{
_lastModifiedTime = DateTime.Now;
OnPropertyChanged(nameof(LastModifiedTime));
}
}
}
///
/// 路径点集合
///
public ObservableCollection Points
{
get => _points;
private set => SetProperty(ref _points, value);
}
///
/// 是否为活动路径
///
public bool IsActive
{
get => _isActive;
set
{
if (SetProperty(ref _isActive, value))
{
_lastModifiedTime = DateTime.Now;
OnPropertyChanged(nameof(LastModifiedTime));
OnPropertyChanged(nameof(StatusString));
}
}
}
///
/// 路径描述
///
public string Description
{
get => Route?.Description ?? _description;
set
{
if (SetProperty(ref _description, value))
{
_lastModifiedTime = DateTime.Now;
OnPropertyChanged(nameof(LastModifiedTime));
}
}
}
///
/// 路径点数量
///
public int PointCount => Points?.Count ?? 0;
///
/// 路径类型
///
public NavisworksTransport.PathType PathType
{
get => Route?.PathType ?? _pathType;
set => SetProperty(ref _pathType, value);
}
///
/// 空中路径子类型(仅当 PathType == Aerial 时有效)
///
public NavisworksTransport.AerialSubType AerialSubType { get; set; } = NavisworksTransport.AerialSubType.Rail;
///
/// 创建时间
///
public DateTime CreatedTime
{
get => Route?.CreatedTime ?? _createdTime;
private set => SetProperty(ref _createdTime, value);
}
///
/// 最后修改时间
///
public DateTime LastModifiedTime
{
get => Route?.LastModified ?? _lastModifiedTime;
private set => SetProperty(ref _lastModifiedTime, value);
}
///
/// 设置时间信息(用于从数据库加载)
///
public void SetTimeInfo(DateTime createdTime, DateTime lastModifiedTime)
{
_createdTime = createdTime;
_lastModifiedTime = lastModifiedTime;
OnPropertyChanged(nameof(CreatedTime));
OnPropertyChanged(nameof(LastModifiedTime));
}
///
/// 路径总长度(米)
///
public double TotalLength
{
get => Route?.TotalLength ?? 0.0;
}
///
/// 是否已验证
///
public bool IsValidated
{
get => _isValidated;
private set => SetProperty(ref _isValidated, value);
}
///
/// 验证状态描述
///
public string ValidationStatus
{
get => _validationStatus;
private set => SetProperty(ref _validationStatus, value);
}
///
/// 路径状态字符串
///
public string StatusString => IsActive ? "活动" : "非活动";
///
/// 路径摘要信息
///
public string SummaryInfo => $"{Name} - {PointCount}个点 - {TotalLength:F2}m - {StatusString}";
///
/// 是否已初始化
///
public bool IsInitialized => _isInitialized;
#endregion
#region 构造函数和初始化
///
/// 默认构造函数(用于新建路径)
///
public PathRouteViewModel() : this(isFromDatabase: false)
{
}
///
/// 构造函数,控制是否从数据库加载
///
/// 是否从数据库/内存加载(false表示新建路径)
public PathRouteViewModel(bool isFromDatabase)
{
try
{
// 获取UI状态管理器实例
_uiStateManager = UIStateManager.Instance;
// 验证关键组件
if (_uiStateManager == null)
{
LogManager.Error("UIStateManager初始化失败");
throw new InvalidOperationException("UIStateManager初始化失败");
}
// 根据场景选择初始化方式
if (!isFromDatabase)
{
InitializeDefaultsForNewRoute();
}
else
{
InitializeMinimal();
}
// 直接完成初始化,不需要异步
CompleteInitialization();
LogManager.Debug($"PathRouteViewModel构造函数完成:{_name}");
}
catch (Exception ex)
{
LogManager.Error($"PathRouteViewModel构造函数异常: {ex.Message}", ex);
throw;
}
}
///
/// 使用指定名称构造(用于新建路径)
///
/// 路径名称
public PathRouteViewModel(string name) : this()
{
_name = name ?? "新路径";
}
///
/// 使用完整参数构造(用于新建路径)
///
/// 路径名称
/// 路径描述
public PathRouteViewModel(string name, string description) : this()
{
_name = name ?? "新路径";
_description = description ?? "";
}
///
/// 最小化初始化(用于从数据库/内存加载路径)
///
private void InitializeMinimal()
{
_id = string.Empty;
_name = string.Empty;
_description = string.Empty;
_isActive = false;
_createdTime = DateTime.MinValue;
_lastModifiedTime = DateTime.MinValue;
_isValidated = false;
_validationStatus = "未验证";
// 初始化点集合
Points = new ObservableCollection();
}
///
/// 初始化默认值(用于新建路径)
///
private void InitializeDefaultsForNewRoute()
{
_id = Guid.NewGuid().ToString();
_name = "新路径";
_description = "";
_isActive = false;
_createdTime = DateTime.Now;
_lastModifiedTime = DateTime.Now;
_isValidated = false;
_validationStatus = "未验证";
// 初始化点集合
Points = new ObservableCollection();
}
///
/// 完成初始化
///
private void CompleteInitialization()
{
try
{
// 订阅Points集合变更事件
if (Points != null)
{
Points.CollectionChanged += OnPointsCollectionChanged;
}
// 设置初始化完成标志
_isInitialized = true;
OnPropertyChanged(nameof(IsInitialized));
LogManager.Debug($"PathRouteViewModel初始化完成:{_name}");
}
catch (Exception ex)
{
LogManager.Error($"PathRouteViewModel初始化异常: {ex.Message}", ex);
}
}
///
/// 异步初始化方法(保留用于向后兼容)
///
/// 异步任务
[Obsolete("已改为同步初始化,此方法保留用于向后兼容")]
public async Task InitializeAsync()
{
await Task.CompletedTask; // 现在初始化已经在构造函数中同步完成
}
///
/// 处理Points集合变更事件
///
private void OnPointsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
SafeExecute(() =>
{
// 通知相关属性变更
OnPropertyChanged(nameof(PointCount));
OnPropertyChanged(nameof(SummaryInfo));
// TotalLength直接从Route读取,不需要手动通知
// 更新最后修改时间
_lastModifiedTime = DateTime.Now;
OnPropertyChanged(nameof(LastModifiedTime));
// 标记为未验证
if (_isValidated)
{
_isValidated = false;
_validationStatus = "需要重新验证";
OnPropertyChanged(nameof(IsValidated));
OnPropertyChanged(nameof(ValidationStatus));
}
}, "处理Points集合变更");
}
#endregion
#region 业务方法
///
/// 异步添加路径点
///
/// 要添加的路径点
/// 异步任务
public async Task AddPointAsync(PathPointViewModel point)
{
if (point == null)
{
throw new ArgumentNullException(nameof(point));
}
await SafeExecuteAsync(async () =>
{
await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
Points.Add(point);
LogManager.Debug($"添加路径点:{point.Name} 到路径 {_name}");
});
}, "添加路径点");
}
///
/// 异步批量添加路径点
///
/// 要添加的路径点集合
/// 异步任务
public async Task AddPointsAsync(IEnumerable points)
{
if (points == null)
{
throw new ArgumentNullException(nameof(points));
}
var pointList = points.ToList();
if (pointList.Count == 0)
{
return;
}
await SafeExecuteAsync(async () =>
{
await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
foreach (var point in pointList)
{
Points.Add(point);
}
LogManager.Debug($"批量添加{pointList.Count}个路径点到路径 {_name}");
});
}, "批量添加路径点");
}
///
/// 异步移除路径点
///
/// 要移除的路径点
/// 是否成功移除
public async Task RemovePointAsync(PathPointViewModel point)
{
if (point == null)
{
return false;
}
try
{
return await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
bool removed = Points.Remove(point);
if (removed)
{
LogManager.Debug($"移除路径点:{point.Name} 从路径 {_name}");
}
return removed;
});
}
catch (Exception ex)
{
LogManager.Error($"移除路径点失败: {ex.Message}");
return false;
}
}
///
/// 异步清空所有路径点
///
/// 异步任务
public async Task ClearPointsAsync()
{
await SafeExecuteAsync(async () =>
{
await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
var count = Points.Count;
Points.Clear();
LogManager.Debug($"清空路径 {_name} 的所有路径点,共{count}个");
});
}, "清空路径点");
}
///
/// 异步验证路径有效性
///
/// 验证结果
public async Task ValidateAsync()
{
try
{
// 先在UI线程上创建快照,确保线程安全
var pointsSnapshot = await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
return Points?.ToList() ?? new List();
});
var nameSnapshot = await _uiStateManager.ExecuteUIUpdateAsync(() => _name);
// 然后在后台线程验证
return await Task.Run(() =>
{
bool isValid = true;
var validationMessages = new List();
// 检查路径点数量
if (pointsSnapshot.Count < 2)
{
isValid = false;
validationMessages.Add("路径至少需要2个点");
}
// 检查路径名称
if (string.IsNullOrWhiteSpace(nameSnapshot))
{
isValid = false;
validationMessages.Add("路径名称不能为空");
}
// 检查重复点
var duplicatePoints = pointsSnapshot
.GroupBy(p => new { p.X, p.Y, p.Z })
.Where(g => g.Count() > 1)
.ToList();
if (duplicatePoints.Any())
{
isValid = false;
validationMessages.Add($"发现{duplicatePoints.Count}组重复坐标的点");
}
// 在UI线程上更新验证状态
_uiStateManager.QueueUIUpdate(() =>
{
_isValidated = true;
_validationStatus = isValid ? "验证通过" : string.Join("; ", validationMessages);
OnPropertyChanged(nameof(IsValidated));
OnPropertyChanged(nameof(ValidationStatus));
});
LogManager.Debug($"路径验证完成:{nameSnapshot},结果:{(isValid ? "通过" : "失败")}");
return isValid;
});
}
catch (Exception ex)
{
LogManager.Error($"验证路径失败: {ex.Message}");
return false;
}
}
///
/// 获取指定索引的路径点
///
/// 索引
/// 路径点,如果索引无效返回null
public PathPointViewModel GetPointAt(int index)
{
return SafeExecute(() =>
{
if (index >= 0 && index < Points.Count)
{
return Points[index];
}
return null;
}, null, "获取指定索引路径点");
}
///
/// 查找指定名称的路径点
///
/// 点名称
/// 匹配的路径点,如果未找到返回null
public PathPointViewModel FindPoint(string name)
{
if (string.IsNullOrEmpty(name))
{
return null;
}
return SafeExecute(() =>
{
return Points.FirstOrDefault(p => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
}, null, "查找路径点");
}
#endregion
#region 向后兼容性接口
///
/// 向后兼容:同步版本的添加点方法
///
/// 要添加的路径点
[Obsolete("请使用AddPointAsync方法以获得更好的性能", false)]
public void AddPoint(PathPointViewModel point)
{
_ = AddPointAsync(point);
}
///
/// 向后兼容:同步版本的移除点方法
///
/// 要移除的路径点
/// 是否成功移除
[Obsolete("请使用RemovePointAsync方法以获得更好的性能", false)]
public bool RemovePoint(PathPointViewModel point)
{
return RemovePointAsync(point).Result;
}
///
/// 向后兼容:同步版本的清空方法
///
[Obsolete("请使用ClearPointsAsync方法以获得更好的性能", false)]
public void ClearPoints()
{
_ = ClearPointsAsync();
}
///
/// 向后兼容:提供ObservableCollection接口
///
[Obsolete("直接使用Points属性,它已经是线程安全的ThreadSafeObservableCollection", false)]
public ObservableCollection GetPointsAsObservableCollection()
{
// 返回原始的ThreadSafeObservableCollection,它继承自ObservableCollection
return Points;
}
///
/// 验证ViewModel状态是否正常
///
/// 是否处于有效状态
public bool IsValidState()
{
return _uiStateManager != null &&
Points != null &&
_isInitialized;
}
///
/// 获取ViewModel状态信息
///
/// 状态描述字符串
public string GetStateInfo()
{
return $"名称: {_name}, " +
$"点数量: {Points?.Count ?? 0}, " +
$"活动状态: {_isActive}, " +
$"已初始化: {_isInitialized}, " +
$"验证状态: {_validationStatus}";
}
#endregion
}
}