错误程序子程序优化

This commit is contained in:
“hsc”
2026-08-07 14:54:01 +08:00
parent 80a2cbd80b
commit 99ac3f2b8d
9 changed files with 261 additions and 149 deletions
@@ -568,20 +568,38 @@ namespace TestingModule.ViewModels
{
// 查找最近的未匹配循环开始
StepVM? lastUnmatchedLoopStart = null;
for (int i = Program.StepCollection.Count - 1; i >= 0; i--)
if (_ScopedContext.SelectedStepList == "主程序")
{
if (Program.StepCollection[i].StepType == "循环开始")
for (int i = Program.StepCollection.Count - 1; i >= 0; i--)
{
bool isMatched = Program.StepCollection.Any(s => s.StepType == "循环结束" && s.LoopStartStepId == Program.StepCollection[i].ID);
if (!isMatched)
if (Program.StepCollection[i].StepType == "循环开始")
{
lastUnmatchedLoopStart = Program.StepCollection[i];
break;
bool isMatched = Program.StepCollection.Any(s => s.StepType == "循环结束" && s.LoopStartStepId == Program.StepCollection[i].ID);
if (!isMatched)
{
lastUnmatchedLoopStart = Program.StepCollection[i];
break;
}
}
}
}
else
{
for (int i = Program.ErrorStepCollection.Count - 1; i >= 0; i--)
{
if (Program.ErrorStepCollection[i].StepType == "循环开始")
{
bool isMatched = Program.ErrorStepCollection.Any(s => s.StepType == "循环结束" && s.LoopStartStepId == Program.StepCollection[i].ID);
if (!isMatched)
{
lastUnmatchedLoopStart = Program.ErrorStepCollection[i];
break;
}
}
}
}
var newStep = new StepVM
{
Name = "循环结束",
@@ -99,39 +99,24 @@ namespace TestingModule.ViewModels
public ICommand GoBackCommand { get; set; }
#endregion
#region
#region /
// --- 主程序 Tab 导航属性 ---
public ProgramVM MainCurrentProgram => _ScopedContext.MainNav.CurrentProgram;
public string MainBreadcrumbPath => _ScopedContext.MainNav.BreadcrumbPath;
public bool MainCanGoBack => _ScopedContext.MainNav.CanGoBack;
public ObservableCollection<StepVM> MainDisplaySteps => _ScopedContext.MainNav.DisplaySteps;
// --- 错误程序 Tab 导航属性 ---
public ProgramVM ErrorCurrentProgram => _ScopedContext.ErrorNav.CurrentProgram;
public string ErrorBreadcrumbPath => _ScopedContext.ErrorNav.BreadcrumbPath;
public bool ErrorCanGoBack => _ScopedContext.ErrorNav.CanGoBack;
public ObservableCollection<StepVM> ErrorDisplaySteps => _ScopedContext.ErrorNav.DisplaySteps;
/// <summary>
/// 当前显示的程序(绑定到 DataGrid 的 ItemsSource 根)。
/// 委托到 ScopedContext.CurrentProgram,保证 ShellViewModel 也能通过 ScopedContext 访问。
/// 当前激活的导航状态(根据选中的 Tab 决定)
/// </summary>
public ProgramVM CurrentProgram
{
get => _ScopedContext.CurrentProgram;
set
{
if (_ScopedContext.CurrentProgram != value)
{
_ScopedContext.CurrentProgram = value;
RaisePropertyChanged();
}
}
}
public string BreadcrumbPath
{
get => _ScopedContext.BreadcrumbPath;
set
{
if (_ScopedContext.BreadcrumbPath != value)
{
_ScopedContext.BreadcrumbPath = value;
RaisePropertyChanged();
}
}
}
public bool CanGoBack => _ScopedContext.CanGoBack;
private ProgramNavigationState ActiveNav => _ScopedContext.ActiveNav;
#endregion
@@ -153,19 +138,36 @@ namespace TestingModule.ViewModels
Program.PropertyChanged += Program_PropertyChanged;
Admin = _globalInfo.IsAdmin;
// 初始化 CurrentProgram 为根程序
_ScopedContext.CurrentProgram = Program;
_ScopedContext.BreadcrumbPath = "程序";
// 初始化两套导航状态
_ScopedContext.MainNav.Initialize(Program, "主程序");
_ScopedContext.ErrorNav.Initialize(Program, "错误程序");
// 订阅 ScopedContext 属性变化,外部(ShellViewModel)修改时转发通知给 UI
_ScopedContext.PropertyChanged += (s, e) =>
// 订阅主程序导航状态变化 → 转发给 UI
_ScopedContext.MainNav.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(ScopedContext.CurrentProgram))
RaisePropertyChanged(nameof(CurrentProgram));
else if (e.PropertyName == nameof(ScopedContext.BreadcrumbPath))
RaisePropertyChanged(nameof(BreadcrumbPath));
else if (e.PropertyName == nameof(ScopedContext.CanGoBack))
RaisePropertyChanged(nameof(CanGoBack));
if (e.PropertyName == nameof(ProgramNavigationState.CurrentProgram))
{
RaisePropertyChanged(nameof(MainCurrentProgram));
RaisePropertyChanged(nameof(MainDisplaySteps));
}
else if (e.PropertyName == nameof(ProgramNavigationState.BreadcrumbPath))
RaisePropertyChanged(nameof(MainBreadcrumbPath));
else if (e.PropertyName == nameof(ProgramNavigationState.CanGoBack))
RaisePropertyChanged(nameof(MainCanGoBack));
};
// 订阅错误程序导航状态变化 → 转发给 UI
_ScopedContext.ErrorNav.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(ProgramNavigationState.CurrentProgram))
{
RaisePropertyChanged(nameof(ErrorCurrentProgram));
RaisePropertyChanged(nameof(ErrorDisplaySteps));
}
else if (e.PropertyName == nameof(ProgramNavigationState.BreadcrumbPath))
RaisePropertyChanged(nameof(ErrorBreadcrumbPath));
else if (e.PropertyName == nameof(ProgramNavigationState.CanGoBack))
RaisePropertyChanged(nameof(ErrorCanGoBack));
};
// 订阅子程序导航事件(运行时由 StepRunning 发布)
@@ -272,45 +274,38 @@ namespace TestingModule.ViewModels
#region
/// <summary>
/// 编辑模式:右键打开子程序
/// 编辑模式:右键打开子程序(操作当前激活的 Tab 的导航状态)
/// </summary>
private void OpenSubProgram()
{
if (SelectedStep == null || SelectedStep.StepType != "子程序" || SelectedStep.SubProgram == null)
return;
// 压栈:保存当前程序
_ScopedContext.SubProgramNavigationStack.Push(CurrentProgram);
_ScopedContext.UpdateCanGoBack();
// 更新面包屑
var nav = ActiveNav;
nav.NavigationStack.Push(nav.CurrentProgram);
nav.UpdateCanGoBack();
var stepName = SelectedStep.Name ?? "子程序";
BreadcrumbPath = $"{BreadcrumbPath} > {stepName}";
// 切换到子程序
CurrentProgram = SelectedStep.SubProgram;
RaisePropertyChanged(nameof(CanGoBack));
nav.BreadcrumbPath = $"{nav.BreadcrumbPath} > {stepName}";
nav.CurrentProgram = SelectedStep.SubProgram;
}
/// <summary>
/// 返回上一级程序
/// 返回上一级程序(操作当前激活的 Tab 的导航状态)
/// </summary>
private void GoBack()
{
if (_ScopedContext.SubProgramNavigationStack.Count == 0)
var nav = ActiveNav;
if (nav.NavigationStack.Count == 0)
return;
// 出栈:恢复上一级程序
var parentProgram = _ScopedContext.SubProgramNavigationStack.Pop();
_ScopedContext.UpdateCanGoBack();
CurrentProgram = parentProgram;
var parentProgram = nav.NavigationStack.Pop();
nav.UpdateCanGoBack();
nav.CurrentProgram = parentProgram;
// 更新面包屑:去掉最后一段
var parts = BreadcrumbPath.Split(" > ");
if (parts.Length > 1)
BreadcrumbPath = string.Join(" > ", parts.Take(parts.Length - 1));
else
BreadcrumbPath = "主程序";
RaisePropertyChanged(nameof(CanGoBack));
var parts = nav.BreadcrumbPath.Split(" > ");
nav.BreadcrumbPath = parts.Length > 1
? string.Join(" > ", parts.Take(parts.Length - 1))
: nav == _ScopedContext.MainNav ? "主程序" : "错误程序";
}
/// <summary>
@@ -318,18 +313,25 @@ namespace TestingModule.ViewModels
/// </summary>
private void OnSubProgramNavigate(SubProgramNavigatePayload payload)
{
var nav = payload.IsErrorProgram ? _ScopedContext.ErrorNav : _ScopedContext.MainNav;
if (payload.Action == NavigateAction.Enter && payload.SubProgram != null)
{
_ScopedContext.SubProgramNavigationStack.Push(CurrentProgram);
_ScopedContext.UpdateCanGoBack();
CurrentProgram = payload.SubProgram;
nav.NavigationStack.Push(nav.CurrentProgram);
nav.UpdateCanGoBack();
nav.CurrentProgram = payload.SubProgram;
var stepName = payload.StepName ?? "子程序";
BreadcrumbPath = $"{BreadcrumbPath} > {stepName}";
RaisePropertyChanged(nameof(CanGoBack));
nav.BreadcrumbPath = $"{nav.BreadcrumbPath} > {stepName}";
}
else if (payload.Action == NavigateAction.Exit)
{
GoBack();
if (nav.NavigationStack.Count == 0) return;
var parentProgram = nav.NavigationStack.Pop();
nav.UpdateCanGoBack();
nav.CurrentProgram = parentProgram;
var parts = nav.BreadcrumbPath.Split(" > ");
nav.BreadcrumbPath = parts.Length > 1
? string.Join(" > ", parts.Take(parts.Length - 1))
: nav == _ScopedContext.MainNav ? "主程序" : "错误程序";
}
}
+26 -14
View File
@@ -17,23 +17,23 @@
</UserControl.Resources>
<Grid>
<GroupBox Header="{Binding Title}">
<DockPanel>
<!-- 面包屑导航栏 -->
<Border DockPanel.Dock="Top" Background="#F0F0F0" Padding="6,3" Visibility="{Binding CanGoBack, Converter={StaticResource BooleanToVisibilityConverter}}">
<DockPanel>
<Button DockPanel.Dock="Right" Content="↩ 返回上一级"
Command="{Binding GoBackCommand}"
Style="{StaticResource MaterialDesignFlatButton}"
FontSize="12" Padding="8,2" Margin="8,0,0,0"/>
<TextBlock Text="{Binding BreadcrumbPath}" VerticalAlignment="Center" FontSize="12" Foreground="#555"/>
</DockPanel>
</Border>
<TabControl SelectedIndex="{Binding SelectedTabIndex, Mode=TwoWay}">
<i:Interaction.Behaviors>
<behaviors:TabControlSelectionChangedBehavior Command="{Binding TabSelectionChangedCommand}"
CommandParameter="{Binding SelectedTabHeader}" />
</i:Interaction.Behaviors>
<TabItem Header="主程序">
<DockPanel>
<!-- 主程序面包屑导航栏 -->
<Border DockPanel.Dock="Top" Background="#F0F0F0" Padding="6,3" Visibility="{Binding MainCanGoBack, Converter={StaticResource BooleanToVisibilityConverter}}">
<DockPanel>
<Button DockPanel.Dock="Right" Content="↩ 返回上一级"
Command="{Binding GoBackCommand}"
Style="{StaticResource MaterialDesignFlatButton}"
FontSize="12" Padding="8,2" Margin="8,0,0,0"/>
<TextBlock Text="{Binding MainBreadcrumbPath}" VerticalAlignment="Center" FontSize="12" Foreground="#555"/>
</DockPanel>
</Border>
<DataGrid dd:DragDrop.IsDragSource="{Binding Admin}"
dd:DragDrop.IsDropTarget="{Binding Admin}"
dd:DragDrop.UseDefaultDragAdorner="{Binding Admin}"
@@ -44,7 +44,7 @@
Background="Transparent"
CanUserAddRows="False"
CanUserSortColumns="False"
ItemsSource="{Binding CurrentProgram.StepCollection}"
ItemsSource="{Binding MainDisplaySteps}"
SelectedItem="{Binding SelectedStep, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectionMode="Extended"
SelectionUnit="FullRow">
@@ -144,8 +144,20 @@
</DataGrid>
</DockPanel>
</TabItem>
<TabItem Header="错误程序">
<DockPanel>
<!-- 错误程序面包屑导航栏 -->
<Border DockPanel.Dock="Top" Background="#F0F0F0" Padding="6,3" Visibility="{Binding ErrorCanGoBack, Converter={StaticResource BooleanToVisibilityConverter}}">
<DockPanel>
<Button DockPanel.Dock="Right" Content="↩ 返回上一级"
Command="{Binding GoBackCommand}"
Style="{StaticResource MaterialDesignFlatButton}"
FontSize="12" Padding="8,2" Margin="8,0,0,0"/>
<TextBlock Text="{Binding ErrorBreadcrumbPath}" VerticalAlignment="Center" FontSize="12" Foreground="#555"/>
</DockPanel>
</Border>
<DataGrid dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.UseDefaultDragAdorner="True"
@@ -153,7 +165,7 @@
Background="Transparent"
CanUserAddRows="False"
CanUserSortColumns="False"
ItemsSource="{Binding CurrentProgram.ErrorStepCollection}"
ItemsSource="{Binding ErrorDisplaySteps}"
SelectedItem="{Binding SelectedStep, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectionMode="Extended"
SelectionUnit="FullRow">
@@ -251,9 +263,9 @@
</DataGrid.ContextMenu>
</DataGrid>
</DockPanel>
</TabItem>
</TabControl>
</DockPanel>
</GroupBox>
</Grid>