using System; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using NavisworksTransport.Core; using NavisworksTransport.UI.WPF.Services; using NavisworksTransport.UI.WPF.Interfaces; namespace NavisworksTransport.UI.WPF.ViewModels { /// /// ViewModel基类,实现INotifyPropertyChanged接口 /// 集成UIStateManager提供线程安全的属性更新和防重入机制 /// 集成智能数据绑定优化功能,支持延迟更新、批量更新和条件更新 /// public abstract class ViewModelBase : IPropertyChangeNotifier { #region 字段和属性 public event PropertyChangedEventHandler PropertyChanged; /// /// UI状态管理器,提供线程安全的UI更新机制 /// private readonly UIStateManager _uiStateManager; /// /// 智能数据绑定优化器,提供延迟更新、批量更新等优化功能 /// private readonly SmartDataBindingOptimizer _bindingOptimizer; /// /// 正在更新的属性集合,用于防重入检测 /// private readonly HashSet _updatingProperties = new HashSet(); /// /// 属性更新锁,确保线程安全 /// private readonly object _propertyLock = new object(); /// /// 是否启用智能优化功能 /// protected bool IsSmartOptimizationEnabled { get; set; } = true; /// /// 主ViewModel引用,用于统一状态栏更新 /// protected LogisticsControlViewModel _mainViewModel; #endregion #region 构造函数 /// /// 初始化ViewModelBase /// protected ViewModelBase() { _uiStateManager = UIStateManager.Instance; _bindingOptimizer = SmartDataBindingOptimizer.Instance; } #endregion #region 属性更新方法 /// /// 触发属性变更通知(线程安全,防重入) /// /// 属性名称,自动获取调用者名称 protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { if (string.IsNullOrEmpty(propertyName)) { return; } try { // 防重入检查 lock (_propertyLock) { if (_updatingProperties.Contains(propertyName)) { // 属性正在更新中,防止重入 LogManager.Debug($"[ViewModel] 检测到属性重入更新,跳过: {propertyName}"); return; } // 标记属性为正在更新状态 _updatingProperties.Add(propertyName); } // 使用UIStateManager确保在UI线程上安全执行 if (_uiStateManager.IsUIThread) { // 已在UI线程上,直接触发 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } else { // 异步切换到UI线程执行 _ = _uiStateManager.ExecuteUIUpdateAsync(() => { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }); } } catch (Exception ex) { LogManager.Error($"[ViewModel] OnPropertyChanged失败: {ex.Message},属性: {propertyName}"); } finally { // 清除更新标记 lock (_propertyLock) { _updatingProperties.Remove(propertyName); } } } /// /// 公共接口:触发指定属性的变更通知(供外部组件使用,替代反射调用) /// /// 属性名称 public virtual void NotifyPropertyChanged(string propertyName) { OnPropertyChanged(propertyName); } /// /// 同步触发属性变更通知(确保在UI线程上执行完成) /// /// 属性名称 /// 超时时间(毫秒),默认3000ms protected virtual async Task OnPropertyChangedAsync(string propertyName, int timeout = 3000) { if (string.IsNullOrEmpty(propertyName)) { return; } // 防重入检查 lock (_propertyLock) { if (_updatingProperties.Contains(propertyName)) { LogManager.Debug($"[ViewModel] 检测到属性重入更新,跳过: {propertyName}"); return; } _updatingProperties.Add(propertyName); } try { // 使用UIStateManager确保同步执行 await _uiStateManager.ExecuteUIUpdateAsync(() => { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }, timeout); } catch (Exception ex) { LogManager.Error($"[ViewModel] OnPropertyChangedAsync失败: {ex.Message},属性: {propertyName}"); throw; } finally { lock (_propertyLock) { _updatingProperties.Remove(propertyName); } } } /// /// 批量触发属性变更通知(原子性操作) /// /// 要更新的属性名称数组 public virtual void OnPropertiesChanged(params string[] propertyNames) { if (propertyNames == null || propertyNames.Length == 0) { return; } // 去重并过滤空值 var uniqueProperties = propertyNames.Where(p => !string.IsNullOrEmpty(p)).Distinct().ToArray(); if (uniqueProperties.Length == 0) { return; } // 防重入检查 var propertiesToUpdate = new List(); lock (_propertyLock) { foreach (var propertyName in uniqueProperties) { if (!_updatingProperties.Contains(propertyName)) { _updatingProperties.Add(propertyName); propertiesToUpdate.Add(propertyName); } else { LogManager.Debug($"[ViewModel] 检测到属性重入更新,跳过: {propertyName}"); } } } if (propertiesToUpdate.Count == 0) { return; // 所有属性都在更新中,避免重入 } try { // 创建批量更新操作 var updateActions = propertiesToUpdate.Select(propertyName => new Action(() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName))) ).ToArray(); // 使用UIStateManager批量执行 _ = _uiStateManager.ExecuteBatchUIUpdate(updateActions); } catch (Exception ex) { LogManager.Error($"[ViewModel] OnPropertiesChanged失败: {ex.Message},属性: {string.Join(", ", propertiesToUpdate)}"); } finally { // 清除所有更新标记 lock (_propertyLock) { foreach (var propertyName in propertiesToUpdate) { _updatingProperties.Remove(propertyName); } } } } /// /// 批量设置属性值并触发变更通知(原子性操作) /// /// 属性名称和值的键值对数组 protected virtual void SetProperties(params (string name, object value)[] properties) { if (properties == null || properties.Length == 0) { return; } try { // 批量更新操作 var updateActions = properties.Select(p => new Action(() => OnPropertyChanged(p.name)) ).ToArray(); // 使用UIStateManager批量执行 _ = _uiStateManager.ExecuteBatchUIUpdate(updateActions); } catch (Exception ex) { LogManager.Error($"[ViewModel] SetProperties失败: {ex.Message}"); } } #endregion #region 属性设置方法 /// /// 设置属性值并触发变更通知(线程安全) /// /// 属性类型 /// 字段引用 /// 新值 /// 属性名称,自动获取调用者名称 /// 如果值发生变化返回true protected bool SetProperty(ref T field, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer.Default.Equals(field, value)) return false; field = value; OnPropertyChanged(propertyName); return true; } /// /// 异步设置属性值并触发变更通知(确保UI线程同步执行) /// /// 属性类型 /// 字段引用 /// 新值 /// 属性名称,自动获取调用者名称 /// 超时时间(毫秒),默认3000ms /// 如果值发生变化返回true protected async Task SetPropertyAsync(T field, T value, [CallerMemberName] string propertyName = null, int timeout = 3000) { if (EqualityComparer.Default.Equals(field, value)) return false; await OnPropertyChangedAsync(propertyName, timeout); return true; } /// /// 线程安全的属性设置方法(使用UIStateManager确保线程安全) /// /// 属性类型 /// 字段引用 /// 新值 /// 属性名称,自动获取调用者名称 /// 如果值发生变化返回true protected bool SetPropertyThreadSafe(ref T field, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer.Default.Equals(field, value)) return false; field = value; // 使用UIStateManager确保在UI线程上触发属性变更通知 if (_uiStateManager.IsUIThread) { OnPropertyChanged(propertyName); } else { _ = _uiStateManager.ExecuteUIUpdateAsync(() => OnPropertyChanged(propertyName)); } return true; } #endregion #region 智能数据绑定优化方法 /// /// 延迟触发属性变更通知 - 将快速连续的更新合并为一次通知 /// /// 属性名称 /// 延迟间隔,null使用默认值 protected void OnPropertyChangedDelayed([CallerMemberName] string propertyName = null, TimeSpan? delayInterval = null) { if (!IsSmartOptimizationEnabled || string.IsNullOrEmpty(propertyName)) { OnPropertyChanged(propertyName); return; } _bindingOptimizer.RegisterDelayedUpdate(this, propertyName, () => OnPropertyChanged(propertyName), delayInterval); } /// /// 条件性触发属性变更通知 - 只有满足条件时才触发更新 /// /// 属性类型 /// 字段引用 /// 新值 /// 更新条件 /// 属性名称 /// 是否触发了更新 protected bool SetPropertyConditional(ref T field, T value, Func condition, [CallerMemberName] string propertyName = null) { if (condition != null && !condition(field, value)) return false; return SetProperty(ref field, value, propertyName); } /// /// 设置属性值并支持智能优化 /// /// 属性类型 /// 字段引用 /// 新值 /// 更新模式 /// 属性名称 /// 是否发生了变化 public bool SetPropertySmart(ref T field, T value, PropertyUpdateMode updateMode = PropertyUpdateMode.Immediate, [CallerMemberName] string propertyName = null) { if (EqualityComparer.Default.Equals(field, value)) return false; var oldValue = field; field = value; switch (updateMode) { case PropertyUpdateMode.Immediate: OnPropertyChanged(propertyName); break; case PropertyUpdateMode.Delayed: OnPropertyChangedDelayed(propertyName); break; case PropertyUpdateMode.Conditional: if (IsSmartOptimizationEnabled) { if (_bindingOptimizer.ShouldUpdateProperty(this, propertyName, oldValue, value)) { OnPropertyChanged(propertyName); } } else { OnPropertyChanged(propertyName); } break; } return true; } /// /// 开始批量属性更新 - 在作用域内的所有属性更新将被合并 /// /// 批量更新作用域 public IBatchUpdateScope BeginBatchUpdate() { if (!IsSmartOptimizationEnabled) return new EmptyBatchScope(); return _bindingOptimizer.BeginBatchUpdate(this); } /// /// 配置属性的条件更新规则 /// /// 属性名称 /// 更新条件 /// 条件配置 public void ConfigurePropertyUpdate(string propertyName, Func condition, ConditionalUpdateConfig config = null) { if (!IsSmartOptimizationEnabled || string.IsNullOrEmpty(propertyName)) return; _bindingOptimizer.ConfigureConditionalUpdate(this, propertyName, condition, config); } /// /// 立即刷新所有延迟的属性更新 /// protected void FlushDelayedUpdates() { if (IsSmartOptimizationEnabled) { _bindingOptimizer.FlushDelayedUpdates(this); } } /// /// 批量设置多个属性(在单个批量更新作用域内) /// /// 属性更新操作集合 protected void SetPropertiesBatch(params Action[] propertyUpdates) { if (propertyUpdates == null || propertyUpdates.Length == 0) return; using (BeginBatchUpdate()) { foreach (var update in propertyUpdates) { try { update?.Invoke(); } catch (Exception ex) { LogManager.Error($"[ViewModel] 批量属性更新失败: {ex.Message}"); } } } } #endregion #region 诊断方法 /// /// 启用或禁用智能优化 /// /// 是否启用 protected void SetSmartOptimization(bool enabled) { IsSmartOptimizationEnabled = enabled; } /// /// 获取智能优化器的统计信息 /// /// 优化器统计 protected OptimizerStatistics GetOptimizerStatistics() { return _bindingOptimizer.GetStatistics(); } #endregion #region 安全执行方法 /// /// 安全执行操作,捕获异常(使用UIStateManager确保线程安全) /// /// 要执行的操作 /// 操作名称 /// 是否强制在UI线程上执行 protected void SafeExecute(Action action, string operationName = "操作", bool runOnUIThread = false) { if (action == null) { LogManager.Warning($"[ViewModel] SafeExecute接收到空操作: {operationName}"); return; } try { if (runOnUIThread && !_uiStateManager.IsUIThread) { // 异步切换到UI线程执行 _ = _uiStateManager.ExecuteUIUpdateAsync(action); } else { // 直接执行 action(); } } catch (Exception ex) { LogManager.Error($"[ViewModel] {operationName}失败: {ex.Message}"); LogManager.Error($"[ViewModel] 堆栈信息: {ex.StackTrace}"); } } /// /// 安全执行操作,捕获异常并返回结果(使用UIStateManager确保线程安全) /// /// 返回类型 /// 要执行的函数 /// 默认返回值 /// 操作名称 /// 是否强制在UI线程上执行 /// 执行结果或默认值 protected T SafeExecute(Func func, T defaultValue = default(T), string operationName = "操作", bool runOnUIThread = false) { if (func == null) { LogManager.Warning($"[ViewModel] SafeExecute接收到空函数: {operationName}"); return defaultValue; } try { if (runOnUIThread && !_uiStateManager.IsUIThread) { // 同步切换到UI线程执行 return _uiStateManager.ExecuteUIUpdateAsync(func).Result; } else { // 直接执行 return func(); } } catch (Exception ex) { LogManager.Error($"[ViewModel] {operationName}失败: {ex.Message}"); LogManager.Error($"[ViewModel] 堆栈信息: {ex.StackTrace}"); return defaultValue; } } /// /// 异步安全执行操作,捕获异常(确保在UI线程上执行) /// /// 要执行的操作 /// 操作名称 /// 超时时间(毫秒),默认5000ms protected async Task SafeExecuteAsync(Action action, string operationName = "操作", int timeout = 5000) { if (action == null) { LogManager.Warning($"[ViewModel] SafeExecuteAsync接收到空操作: {operationName}"); return; } try { await _uiStateManager.ExecuteUIUpdateAsync(action, timeout); } catch (Exception ex) { LogManager.Error($"[ViewModel] {operationName}异步执行失败: {ex.Message}"); LogManager.Error($"[ViewModel] 堆栈信息: {ex.StackTrace}"); } } /// /// 异步安全执行操作,捕获异常并返回结果(确保在UI线程上执行) /// /// 返回类型 /// 要执行的函数 /// 默认返回值 /// 操作名称 /// 超时时间(毫秒),默认5000ms /// 执行结果或默认值 protected async Task SafeExecuteAsync(Func func, T defaultValue = default(T), string operationName = "操作", int timeout = 5000) { if (func == null) { LogManager.Warning($"[ViewModel] SafeExecuteAsync接收到空函数: {operationName}"); return defaultValue; } try { return await _uiStateManager.ExecuteUIUpdateAsync(func, timeout); } catch (Exception ex) { LogManager.Error($"[ViewModel] {operationName}异步执行失败: {ex.Message}"); LogManager.Error($"[ViewModel] 堆栈信息: {ex.StackTrace}"); return defaultValue; } } #endregion #region 统一状态栏更新方法 /// /// 设置主ViewModel引用 /// /// 主ViewModel实例 protected void SetMainViewModel(LogisticsControlViewModel mainViewModel) { _mainViewModel = mainViewModel; } /// /// 更新统一状态栏(简单版本,不显示进度条) /// /// 状态消息 protected void UpdateMainStatus(string message) { try { // 如果有主ViewModel引用,更新统一状态栏 if (_mainViewModel != null) { _mainViewModel.UpdateStatus(message); } } catch (Exception ex) { LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex); } } /// /// 更新统一状态栏(支持百分比进度) /// /// 状态消息 /// 进度百分比 protected void UpdateMainStatus(string message, double percentage) { try { // 如果有主ViewModel引用,更新统一状态栏 if (_mainViewModel != null) { _mainViewModel.UpdateStatus(message, percentage); } } catch (Exception ex) { LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex); } } /// /// 更新统一状态栏(完整版本,支持不确定进度) /// /// 状态消息 /// 进度值(-1表示不确定进度) /// 是否正在处理(可选) protected void UpdateMainStatus(string message, double progress = -1, bool? isProcessing = null) { try { // 如果有主ViewModel引用,更新统一状态栏 if (_mainViewModel != null) { _mainViewModel.UpdateStatus(message, progress, isProcessing); } } catch (Exception ex) { LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex); } } #endregion } /// /// 属性更新模式枚举 /// public enum PropertyUpdateMode { /// /// 立即更新 - 传统模式,立即触发属性变更通知 /// Immediate, /// /// 延迟更新 - 将快速连续的更新合并,在指定延迟后统一触发 /// Delayed, /// /// 条件更新 - 根据预配置的条件和频率限制决定是否触发更新 /// Conditional } }