解决了有些操作需要UI实时更新的问题

This commit is contained in:
tian 2025-08-19 23:04:46 +08:00
parent 9928dda6e3
commit 5d2ed56936
4 changed files with 179 additions and 14 deletions

View File

@ -390,26 +390,51 @@ namespace NavisworksTransport
{
try
{
LogManager.Info($"*** RaiseRouteGenerated被调用: {route?.Name}, Method: {generationMethod} ***");
var eventArgs = new RouteGeneratedEventArgs(route, generationMethod, _managerId);
if (_uiStateManager != null)
// 检查是否有订阅者
if (RouteGenerated != null)
{
_uiStateManager.QueueUIUpdate(() =>
var invocationList = RouteGenerated.GetInvocationList();
LogManager.Info($"*** RouteGenerated事件有 {invocationList.Length} 个订阅者 ***");
for (int i = 0; i < invocationList.Length; i++)
{
RouteGenerated?.Invoke(this, eventArgs);
// 向后兼容的事件
RouteGenerated_Legacy?.Invoke(this, route);
});
var handler = invocationList[i];
LogManager.Info($"*** 订阅者 {i}: {handler.Target?.GetType().Name}.{handler.Method.Name} ***");
}
}
else
{
LogManager.Warning("*** RouteGenerated事件没有订阅者 ***");
}
// RouteGenerated事件使用立即执行确保UI及时更新
if (_uiStateManager != null)
{
LogManager.Info("*** 使用UIStateManager立即执行RouteGenerated事件 ***");
_uiStateManager.ExecuteImmediateUIUpdate(() =>
{
LogManager.Info($"*** 立即执行RouteGenerated事件: {route?.Name} ***");
RouteGenerated?.Invoke(this, eventArgs);
// 向后兼容的事件
RouteGenerated_Legacy?.Invoke(this, route);
LogManager.Info($"*** RouteGenerated事件立即执行完成: {route?.Name} ***");
}, $"RouteGenerated事件({route?.Name})");
}
else
{
LogManager.Info("*** 直接触发RouteGenerated事件UIStateManager为null***");
RouteGenerated?.Invoke(this, eventArgs);
RouteGenerated_Legacy?.Invoke(this, route);
LogManager.Info($"*** RouteGenerated事件直接调用完成: {route?.Name} ***");
}
}
catch (Exception ex)
{
LogManager.Error($"[路径生成] 事件触发失败: {ex.Message}");
LogManager.Error($"*** [路径生成] 事件触发失败: {ex.Message} ***");
}
}

View File

@ -345,6 +345,121 @@ namespace NavisworksTransport.Core
}
}
/// <summary>
/// 立即执行UI更新操作绕过队列机制
/// 用于关键UI事件如RouteGenerated需要立即响应的场景
/// </summary>
/// <param name="operation">要执行的UI操作</param>
/// <param name="operationType">操作类型描述,用于日志记录</param>
/// <param name="timeout">超时时间毫秒默认2000ms</param>
public void ExecuteImmediateUIUpdate(Action operation, string operationType = "立即UI更新", int timeout = 2000)
{
if (_isDisposed || operation == null)
{
LogManager.Warning($"跳过{operationType}UIStateManager已释放或操作为null");
return;
}
try
{
LogManager.Info($"*** 开始立即执行{operationType} ***");
// 如果已经在UI线程中直接执行
if (IsUIThread)
{
LogManager.Info($"*** 当前已在UI线程直接执行{operationType} ***");
operation();
LogManager.Info($"*** {operationType}立即执行完成 ***");
return;
}
// 创建同步等待信号
var completed = false;
Exception exception = null;
var resetEvent = new ManualResetEventSlim(false);
LogManager.Info($"*** 切换到UI线程执行{operationType} ***");
// 使用同步方式切换到UI线程
if (_uiContext != null)
{
_uiContext.Send(_ =>
{
try
{
LogManager.Info($"*** SynchronizationContext中执行{operationType} ***");
operation();
completed = true;
}
catch (Exception ex)
{
exception = ex;
LogManager.Error($"{operationType}在UI线程中执行失败: {ex.Message}");
}
finally
{
resetEvent.Set();
}
}, null);
}
else
{
// 回退到Control.Invoke
var mainForm = GetMainForm();
if (mainForm != null)
{
mainForm.Invoke(new Action(() =>
{
try
{
LogManager.Info($"*** Control.Invoke中执行{operationType} ***");
operation();
completed = true;
}
catch (Exception ex)
{
exception = ex;
LogManager.Error($"{operationType}在UI线程中执行失败Control.Invoke: {ex.Message}");
}
finally
{
resetEvent.Set();
}
}));
}
else
{
throw new InvalidOperationException($"无法找到UI上下文来执行{operationType}");
}
}
// 等待完成或超时
if (!resetEvent.Wait(timeout))
{
LogManager.Error($"*** {operationType}执行超时({timeout}ms ***");
throw new TimeoutException($"{operationType}执行超时({timeout}ms");
}
// 检查执行结果
if (exception != null)
{
throw new Exception($"{operationType}执行失败", exception);
}
if (!completed)
{
throw new InvalidOperationException($"{operationType}未正确完成");
}
LogManager.Info($"*** {operationType}立即执行成功完成 ***");
}
catch (Exception ex)
{
LogManager.Error($"*** {operationType}立即执行失败: {ex.Message} ***", ex);
throw;
}
}
/// <summary>
/// 处理队列中的UI更新操作
/// </summary>

View File

@ -937,6 +937,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
try
{
LogManager.Info($"*** 开始订阅PathPlanningManager事件Manager实例: {_pathPlanningManager.GetType().Name} ***");
// 订阅路径点操作事件(用于手工路径编辑)
_pathPlanningManager.PathPointOperation += OnPathPointOperation;
@ -951,12 +953,23 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 订阅路径生成事件(用于处理自动路径)
_pathPlanningManager.RouteGenerated += OnRouteGenerated;
LogManager.Info("PathEditingViewModel已订阅PathPlanningManager事件");
LogManager.Info("*** PathEditingViewModel已成功订阅PathPlanningManager事件包括RouteGenerated ***");
// 验证事件订阅是否成功
var routeGeneratedField = _pathPlanningManager.GetType().GetEvent("RouteGenerated");
if (routeGeneratedField != null)
{
LogManager.Info($"*** RouteGenerated事件存在事件类型: {routeGeneratedField.EventHandlerType?.Name} ***");
}
else
{
LogManager.Error("*** RouteGenerated事件不存在 ***");
}
}
catch (Exception ex)
{
LogManager.Error($"订阅PathPlanningManager事件失败: {ex.Message}", ex);
LogManager.Error($"*** 订阅PathPlanningManager事件失败: {ex.Message} ***", ex);
}
}
@ -1158,7 +1171,14 @@ namespace NavisworksTransport.UI.WPF.ViewModels
/// </summary>
private async void OnRouteGenerated(object sender, RouteGeneratedEventArgs e)
{
if (e?.Route == null) return;
// 添加调试日志确认事件是否被调用
LogManager.Info($"*** OnRouteGenerated被调用Sender: {sender?.GetType().Name}, Route: {e?.Route?.Name}, Method: {e?.GenerationMethod} ***");
if (e?.Route == null)
{
LogManager.Warning("*** OnRouteGenerated: RouteGeneratedEventArgs或Route为null退出处理 ***");
return;
}
try
{
@ -1169,6 +1189,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 处理自动路径生成
if (e.GenerationMethod == RouteGenerationMethod.AutoPlanning)
{
LogManager.Info($"*** 开始处理自动路径生成: {e.Route.Name} ***");
// 创建对应的 WPF ViewModel
var autoPathViewModel = new PathRouteViewModel
{
@ -1190,6 +1212,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
};
autoPathViewModel.Points.Add(wpfPoint);
}
LogManager.Info($"*** 已创建PathRouteViewModel包含 {autoPathViewModel.Points.Count} 个点 ***");
// 检查是否已存在同名路径,避免重复添加
var existingPath = PathRoutes.FirstOrDefault(p => p.Name == e.Route.Name);
@ -1199,7 +1223,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
PathRoutes.Add(autoPathViewModel);
SelectedPathRoute = autoPathViewModel;
LogManager.Info($"自动路径已添加到UI列表: {e.Route.Name}");
LogManager.Info($"*** 自动路径已添加到UI列表: {e.Route.Name}当前PathRoutes.Count = {PathRoutes.Count} ***");
}
else
{
@ -1211,10 +1235,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
SelectedPathRoute = existingPath;
LogManager.Info($"自动路径已更新UI列表: {e.Route.Name}");
LogManager.Info($"*** 自动路径已更新UI列表: {e.Route.Name} ***");
}
AutoPathStatus = $"✅ 自动路径规划完成: {e.Route.Name},共 {e.Route.Points.Count} 个路径点";
LogManager.Info($"*** AutoPathStatus已更新: {AutoPathStatus} ***");
}
else if (e.GenerationMethod == RouteGenerationMethod.Manual)
{
@ -1225,7 +1250,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
catch (Exception ex)
{
LogManager.Error($"处理路径生成事件失败: {ex.Message}", ex);
LogManager.Error($"*** OnRouteGenerated异常: {ex.Message} ***", ex);
}
}