子程序优化

This commit is contained in:
2026-08-07 16:30:13 +08:00
parent 8daa1df8e9
commit a9355087ad
9 changed files with 408 additions and 10 deletions
@@ -0,0 +1,89 @@
using Prism.Mvvm;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using UIShare.UIViewModel;
namespace UIShare.GlobalVariable
{
/// <summary>
/// 单个 Tab(主程序 / 错误程序)的子程序导航状态。
/// 主程序和错误程序各自持有一个独立实例,互不干扰。
/// </summary>
public class ProgramNavigationState : BindableBase
{
/// <summary>是否为错误程序 Tab</summary>
public bool IsErrorTab { get; set; }
public Stack<ProgramVM> NavigationStack { get; } = new();
private ProgramVM _currentProgram;
public ProgramVM CurrentProgram
{
get => _currentProgram;
set
{
if (SetProperty(ref _currentProgram, value))
RaisePropertyChanged(nameof(DisplaySteps));
}
}
/// <summary>
/// DataGrid 实际绑定的步骤集合。
/// 根程序 + 错误 Tab → ErrorStepCollection;其他情况 → StepCollection。
/// </summary>
public ObservableCollection<StepVM> DisplaySteps
{
get
{
if (CurrentProgram == null)
return new ObservableCollection<StepVM>();
// 在根程序且是错误 Tab → 显示错误步骤集合
if (NavigationStack.Count == 0 && IsErrorTab)
return CurrentProgram.ErrorStepCollection;
// 其他情况(主 Tab 或已进入子程序)→ 显示正常步骤集合
return CurrentProgram.StepCollection;
}
}
private string _breadcrumbPath = "主程序";
public string BreadcrumbPath
{
get => _breadcrumbPath;
set => SetProperty(ref _breadcrumbPath, value);
}
private bool _canGoBack;
public bool CanGoBack
{
get => _canGoBack;
set => SetProperty(ref _canGoBack, value);
}
/// <summary>
/// 用根程序初始化导航状态
/// </summary>
public void Initialize(ProgramVM rootProgram, string label)
{
NavigationStack.Clear();
CurrentProgram = rootProgram;
BreadcrumbPath = label;
CanGoBack = false;
}
/// <summary>
/// 清空导航栈,回到根程序
/// </summary>
public void Reset(ProgramVM rootProgram, string label)
{
NavigationStack.Clear();
CurrentProgram = rootProgram;
BreadcrumbPath = label;
CanGoBack = false;
}
/// <summary>
/// 根据栈状态刷新 CanGoBack
/// </summary>
public void UpdateCanGoBack() => CanGoBack = NavigationStack.Count > 0;
}
}
+29 -1
View File
@@ -1,5 +1,6 @@
using DeviceCommand.Base;
using MaterialDesignThemes.Wpf;
using Prism.Mvvm;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -14,9 +15,35 @@ using UIShare.UIViewModel;
namespace UIShare.GlobalVariable
{
public class ScopedContext
public class ScopedContext : BindableBase
{
private static readonly Random _randomSeed = new Random();
#region /
/// <summary>主程序 Tab 的导航状态</summary>
public ProgramNavigationState MainNav { get; } = new();
/// <summary>错误程序 Tab 的导航状态</summary>
public ProgramNavigationState ErrorNav { get; } = new();
/// <summary>
/// 根据当前选中的 Tab 返回对应的导航状态
/// </summary>
public ProgramNavigationState ActiveNav =>
SelectedStepList == "错误程序" ? ErrorNav : MainNav;
/// <summary>
/// 重置两个 Tab 的导航栈,回到根程序
/// </summary>
public void ResetNavigation()
{
MainNav.Reset(Program, "主程序");
ErrorNav.Reset(Program, "错误程序");
}
#endregion
public ProgramVM Program { get; set; } = new();
public String SelectedStepList { get; set; } = "主程序";
public string CurrentFilePath { get; set; }
@@ -45,6 +72,7 @@ namespace UIShare.GlobalVariable
public int DebugRandomId { get; private set; }
public ScopedContext()
{
ErrorNav.IsErrorTab = true;
lock (_randomSeed)
{
// 每次诞生一个新上下文,就在 10000 到 99999 之间随机摇一个数
+30
View File
@@ -181,7 +181,23 @@ namespace UIShare
_scopedContext.SingleStep = false;
}
LoggerHelper.InfoWithNotify(_systemConfig.Title, $"开始执行子程序 [ {step.Index} ] [ {step.Name} ] ", depth);
// 发布进入子程序导航事件
_eventAggregator.GetEvent<SubProgramNavigateEvent>().Publish(new SubProgramNavigatePayload
{
Scope = _systemConfig.Title,
Action = NavigateAction.Enter,
SubProgram = step.SubProgram,
StepName = step.Name,
IsErrorProgram = true
});
stepSuccess = await ExecuteSteps(step.SubProgram, depth + 1, cancellationToken);
// 发布退出子程序导航事件
_eventAggregator.GetEvent<SubProgramNavigateEvent>().Publish(new SubProgramNavigatePayload
{
Scope = _systemConfig.Title,
Action = NavigateAction.Exit,
IsErrorProgram = true
});
UpdateCurrentStepResult(step, true, stepSuccess, depth);
if (SubSingleStep)
{
@@ -356,7 +372,21 @@ namespace UIShare
_scopedContext.SingleStep = false;
}
LoggerHelper.InfoWithNotify(_systemConfig.Title, $"开始执行子程序 [ {step.Index} ] [ {step.Name} ] ", depth);
// 发布进入子程序导航事件
_eventAggregator.GetEvent<SubProgramNavigateEvent>().Publish(new SubProgramNavigatePayload
{
Scope = _systemConfig.Title,
Action = NavigateAction.Enter,
SubProgram = step.SubProgram,
StepName = step.Name
});
stepSuccess = await ExecuteSteps(step.SubProgram, depth + 1, cancellationToken);
// 发布退出子程序导航事件
_eventAggregator.GetEvent<SubProgramNavigateEvent>().Publish(new SubProgramNavigatePayload
{
Scope = _systemConfig.Title,
Action = NavigateAction.Exit
});
UpdateCurrentStepResult(step, true, stepSuccess, depth);
if (SubSingleStep)
{