CNC数据存储问题,包括中间的处理情况的缓存

This commit is contained in:
zhengxuan.zhang
2026-04-21 07:32:28 +08:00
parent d9d3e31e57
commit 238e97d110
7 changed files with 1871 additions and 111 deletions
+3 -1
View File
@@ -36,6 +36,7 @@ using XplorePlane.Services.Camera;
using XplorePlane.Services.Cnc;
using XplorePlane.Services.Matrix;
using XplorePlane.Services.Measurement;
using XplorePlane.Services.InspectionResults;
using XplorePlane.Services.Recipe;
using XplorePlane.ViewModels;
using XplorePlane.ViewModels.Cnc;
@@ -317,6 +318,7 @@ namespace XplorePlane
containerRegistry.RegisterSingleton<ICncProgramService, CncProgramService>();
containerRegistry.RegisterSingleton<IMatrixService, MatrixService>();
containerRegistry.RegisterSingleton<IMeasurementDataService, MeasurementDataService>();
containerRegistry.RegisterSingleton<IInspectionResultStore, InspectionResultStore>();
// ── CNC / 矩阵 ViewModel(瞬态)──
containerRegistry.Register<CncEditorViewModel>();
@@ -354,4 +356,4 @@ namespace XplorePlane
base.ConfigureModuleCatalog(moduleCatalog);
}
}
}
}
@@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
namespace XplorePlane.Models
{
public enum InspectionAssetType
{
RunSourceImage,
NodeInputImage,
NodeResultImage
}
public enum InspectionNodeStatus
{
Succeeded,
Failed,
PartialSuccess,
AssetMissing
}
public class InspectionRunRecord
{
public Guid RunId { get; set; } = Guid.NewGuid();
public string ProgramName { get; set; } = string.Empty;
public string WorkpieceId { get; set; } = string.Empty;
public string SerialNumber { get; set; } = string.Empty;
public DateTime StartedAt { get; set; } = DateTime.UtcNow;
public DateTime? CompletedAt { get; set; }
public bool OverallPass { get; set; }
public string SourceImagePath { get; set; } = string.Empty;
public string ResultRootPath { get; set; } = string.Empty;
public int NodeCount { get; set; }
}
public class InspectionNodeResult
{
public Guid RunId { get; set; }
public Guid NodeId { get; set; } = Guid.NewGuid();
public int NodeIndex { get; set; }
public string NodeName { get; set; } = string.Empty;
public Guid PipelineId { get; set; }
public string PipelineName { get; set; } = string.Empty;
public string PipelineVersionHash { get; set; } = string.Empty;
public bool NodePass { get; set; }
public string SourceImagePath { get; set; } = string.Empty;
public string ResultImagePath { get; set; } = string.Empty;
public InspectionNodeStatus Status { get; set; } = InspectionNodeStatus.Succeeded;
public long DurationMs { get; set; }
}
public class InspectionMetricResult
{
public Guid RunId { get; set; }
public Guid NodeId { get; set; }
public string MetricKey { get; set; } = string.Empty;
public string MetricName { get; set; } = string.Empty;
public double MetricValue { get; set; }
public string Unit { get; set; } = string.Empty;
public double? LowerLimit { get; set; }
public double? UpperLimit { get; set; }
public bool IsPass { get; set; }
public int DisplayOrder { get; set; }
}
public class InspectionAssetRecord
{
public Guid RunId { get; set; }
public Guid? NodeId { get; set; }
public InspectionAssetType AssetType { get; set; }
public string RelativePath { get; set; } = string.Empty;
public string FileFormat { get; set; } = string.Empty;
public int Width { get; set; }
public int Height { get; set; }
}
public class PipelineExecutionSnapshot
{
public Guid RunId { get; set; }
public Guid NodeId { get; set; }
public string PipelineName { get; set; } = string.Empty;
public string PipelineDefinitionJson { get; set; } = string.Empty;
public string PipelineHash { get; set; } = string.Empty;
}
public class InspectionAssetWriteRequest
{
public InspectionAssetType AssetType { get; set; }
public string FileName { get; set; } = string.Empty;
public string SourceFilePath { get; set; } = string.Empty;
public byte[] Content { get; set; }
public string FileFormat { get; set; } = string.Empty;
public int Width { get; set; }
public int Height { get; set; }
}
public class InspectionRunQuery
{
public string ProgramName { get; set; } = string.Empty;
public string WorkpieceId { get; set; } = string.Empty;
public string SerialNumber { get; set; } = string.Empty;
public string PipelineName { get; set; } = string.Empty;
public DateTime? From { get; set; }
public DateTime? To { get; set; }
public int? Skip { get; set; }
public int? Take { get; set; }
}
public class InspectionRunDetail
{
public InspectionRunRecord Run { get; set; } = new();
public IReadOnlyList<InspectionNodeResult> Nodes { get; set; } = Array.Empty<InspectionNodeResult>();
public IReadOnlyList<InspectionMetricResult> Metrics { get; set; } = Array.Empty<InspectionMetricResult>();
public IReadOnlyList<InspectionAssetRecord> Assets { get; set; } = Array.Empty<InspectionAssetRecord>();
public IReadOnlyList<PipelineExecutionSnapshot> PipelineSnapshots { get; set; } = Array.Empty<PipelineExecutionSnapshot>();
}
}
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using XplorePlane.Models;
namespace XplorePlane.Services.InspectionResults
{
public interface IInspectionResultStore
{
Task BeginRunAsync(InspectionRunRecord runRecord, InspectionAssetWriteRequest runSourceAsset = null);
Task AppendNodeResultAsync(
InspectionNodeResult nodeResult,
IEnumerable<InspectionMetricResult> metrics = null,
PipelineExecutionSnapshot pipelineSnapshot = null,
IEnumerable<InspectionAssetWriteRequest> assets = null);
Task CompleteRunAsync(Guid runId, bool? overallPass = null, DateTime? completedAt = null);
Task<IReadOnlyList<InspectionRunRecord>> QueryRunsAsync(InspectionRunQuery query = null);
Task<InspectionRunDetail> GetRunDetailAsync(Guid runId);
}
}
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -4,10 +4,10 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cnc="clr-namespace:XplorePlane.Views.Cnc"
Title="CNC 编辑器"
Width="544"
Height="750"
MinWidth="544"
MinHeight="750"
Width="1180"
Height="780"
MinWidth="1040"
MinHeight="720"
ResizeMode="CanResize"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner">
+378 -106
View File
@@ -8,7 +8,7 @@
xmlns:prism="http://prismlibrary.com/"
xmlns:vm="clr-namespace:XplorePlane.ViewModels.Cnc"
d:DesignHeight="760"
d:DesignWidth="1040"
d:DesignWidth="1180"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d">
@@ -17,19 +17,35 @@
<local:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
<SolidColorBrush x:Key="PanelBg" Color="White" />
<SolidColorBrush x:Key="PanelBorder" Color="#cdcbcb" />
<SolidColorBrush x:Key="SeparatorBrush" Color="#E0E0E0" />
<SolidColorBrush x:Key="TreeItemHover" Color="#F5F9FF" />
<SolidColorBrush x:Key="TreeItemSelected" Color="#E8F0FE" />
<SolidColorBrush x:Key="PanelBorder" Color="#CDCBCB" />
<SolidColorBrush x:Key="SeparatorBrush" Color="#E5E5E5" />
<SolidColorBrush x:Key="HeaderBg" Color="#F7F7F7" />
<SolidColorBrush x:Key="SoftBlue" Color="#E8F0FE" />
<SolidColorBrush x:Key="SoftBlueBorder" Color="#5B9BD5" />
<FontFamily x:Key="UiFont">Microsoft YaHei UI</FontFamily>
<Style x:Key="ToolbarBtn" TargetType="Button">
<Setter Property="Height" Value="28" />
<Setter Property="Height" Value="26" />
<Setter Property="MinWidth" Value="40" />
<Setter Property="Margin" Value="2,0" />
<Setter Property="Padding" Value="6,0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="#cdcbcb" />
<Setter Property="Padding" Value="8,0" />
<Setter Property="Background" Value="White" />
<Setter Property="BorderBrush" Value="#CDCBCB" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="FontFamily" Value="Microsoft YaHei UI" />
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
<Setter Property="FontSize" Value="11" />
<Setter Property="Cursor" Value="Hand" />
</Style>
<Style x:Key="InsertBtn" TargetType="Button">
<Setter Property="Height" Value="28" />
<Setter Property="Margin" Value="0,0,0,6" />
<Setter Property="Padding" Value="8,0" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="Background" Value="White" />
<Setter Property="BorderBrush" Value="#D7D7D7" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
<Setter Property="FontSize" Value="11" />
<Setter Property="Cursor" Value="Hand" />
</Style>
@@ -41,10 +57,46 @@
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
<Style x:Key="EditorTitle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
<Setter Property="FontSize" Value="13" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Margin" Value="0,0,0,8" />
</Style>
<Style x:Key="LabelStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
<Setter Property="FontSize" Value="11" />
<Setter Property="Foreground" Value="#666666" />
<Setter Property="Margin" Value="0,0,0,3" />
</Style>
<Style x:Key="EditorBox" TargetType="TextBox">
<Setter Property="Height" Value="28" />
<Setter Property="Padding" Value="8,3" />
<Setter Property="Margin" Value="0,0,0,8" />
<Setter Property="BorderBrush" Value="#CFCFCF" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
<Setter Property="FontSize" Value="11" />
</Style>
<Style x:Key="EditorCheck" TargetType="CheckBox">
<Setter Property="Margin" Value="0,2,0,8" />
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
<Setter Property="FontSize" Value="11" />
</Style>
<Style x:Key="CompactGroupBox" TargetType="GroupBox">
<Setter Property="Margin" Value="0,0,0,10" />
<Setter Property="Padding" Value="0" />
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
<Setter Property="FontSize" Value="11" />
</Style>
</UserControl.Resources>
<Border
MinWidth="550"
MinWidth="980"
Background="{StaticResource PanelBg}"
BorderBrush="{StaticResource PanelBorder}"
BorderThickness="1"
@@ -53,7 +105,9 @@
<Grid.ColumnDefinitions>
<ColumnDefinition Width="280" MinWidth="240" />
<ColumnDefinition Width="1" />
<ColumnDefinition Width="*" MinWidth="300" />
<ColumnDefinition Width="430" MinWidth="360" />
<ColumnDefinition Width="1" />
<ColumnDefinition Width="*" MinWidth="260" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
@@ -65,116 +119,116 @@
<Border
Grid.Row="0"
Padding="10,8"
Background="{StaticResource HeaderBg}"
BorderBrush="{StaticResource SeparatorBrush}"
BorderThickness="0,0,0,1">
<StackPanel>
<TextBlock
FontFamily="Microsoft YaHei UI"
FontFamily="{StaticResource UiFont}"
FontSize="14"
FontWeight="SemiBold"
Text="{Binding ProgramName, TargetNullValue=CNC Program}" />
Text="{Binding ProgramName, TargetNullValue=NewCncProgram}" />
<TextBlock
Margin="0,4,0,0"
FontFamily="Microsoft YaHei UI"
FontSize="11"
Foreground="#666"
Text="模块节点下会自动归类显示标记/等待/消息节点" />
Margin="0,3,0,0"
FontFamily="{StaticResource UiFont}"
FontSize="10.5"
Foreground="#666666"
Text="模块节点下会自动显示标记等待消息等子节点" />
</StackPanel>
</Border>
<TreeView
x:Name="CncTreeView"
Grid.Row="1"
Padding="4,6"
Background="Transparent"
BorderThickness="0"
ItemsSource="{Binding TreeNodes}"
SelectedItemChanged="CncTreeView_SelectedItemChanged">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type vm:CncNodeViewModel}" ItemsSource="{Binding Children}">
<Grid x:Name="NodeRoot" MinHeight="42">
<Grid x:Name="NodeRoot" MinHeight="34">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="34" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border
Grid.Column="0"
Width="26"
Height="26"
Width="22"
Height="22"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
CornerRadius="4">
<Image
Width="18"
Height="18"
Width="15"
Height="15"
Source="{Binding Icon}"
Stretch="Uniform" />
</Border>
<StackPanel
Grid.Column="1"
Margin="6,0,0,0"
Margin="4,0,0,0"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
FontFamily="Microsoft YaHei UI"
FontSize="11"
Foreground="#888"
FontFamily="{StaticResource UiFont}"
FontSize="10.5"
Foreground="#888888"
Text="{Binding Index, StringFormat='[{0}] '}" />
<TextBlock
VerticalAlignment="Center"
FontFamily="Microsoft YaHei UI"
FontSize="12"
FontFamily="{StaticResource UiFont}"
FontSize="11.5"
Text="{Binding Name}" />
</StackPanel>
<StackPanel
x:Name="NodeActions"
Grid.Column="2"
Margin="0,0,4,0"
Margin="0,0,2,0"
VerticalAlignment="Center"
Orientation="Horizontal"
Visibility="Collapsed">
<Button
Width="22"
Height="22"
Width="20"
Height="20"
Margin="1,0"
Background="Transparent"
BorderBrush="#cdcbcb"
Background="White"
BorderBrush="#CDCBCB"
BorderThickness="1"
Command="{Binding DataContext.MoveNodeUpCommand, RelativeSource={RelativeSource AncestorType=TreeView}}"
CommandParameter="{Binding}"
Content=""
Content=""
Cursor="Hand"
FontSize="10"
ToolTip="上移" />
<Button
Width="22"
Height="22"
Width="20"
Height="20"
Margin="1,0"
Background="Transparent"
BorderBrush="#cdcbcb"
Background="White"
BorderBrush="#CDCBCB"
BorderThickness="1"
Command="{Binding DataContext.MoveNodeDownCommand, RelativeSource={RelativeSource AncestorType=TreeView}}"
CommandParameter="{Binding}"
Content=""
Content=""
Cursor="Hand"
FontSize="10"
ToolTip="下移" />
<Button
Width="22"
Height="22"
Width="20"
Height="20"
Margin="1,0"
Background="Transparent"
Background="White"
BorderBrush="#E05050"
BorderThickness="1"
Command="{Binding DataContext.DeleteNodeCommand, RelativeSource={RelativeSource AncestorType=TreeView}}"
Content=""
Content="×"
Cursor="Hand"
FontSize="10"
ToolTip="删除" />
@@ -199,42 +253,15 @@
Fill="{StaticResource SeparatorBrush}" />
<ScrollViewer Grid.Column="2" VerticalScrollBarVisibility="Auto">
<Grid Margin="18,18,22,18">
<Grid.Resources>
<Style x:Key="EditorTitle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Microsoft YaHei UI" />
<Setter Property="FontSize" Value="13" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Margin" Value="0,0,0,12" />
</Style>
<Style x:Key="LabelStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Microsoft YaHei UI" />
<Setter Property="FontSize" Value="12" />
<Setter Property="Foreground" Value="#666" />
<Setter Property="Margin" Value="0,0,0,4" />
</Style>
<Style x:Key="EditorBox" TargetType="TextBox">
<Setter Property="Height" Value="30" />
<Setter Property="Padding" Value="8,4" />
<Setter Property="Margin" Value="0,0,0,12" />
<Setter Property="BorderBrush" Value="#CFCFCF" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="FontFamily" Value="Microsoft YaHei UI" />
</Style>
<Style x:Key="EditorCheck" TargetType="CheckBox">
<Setter Property="Margin" Value="0,4,0,12" />
<Setter Property="FontFamily" Value="Microsoft YaHei UI" />
</Style>
</Grid.Resources>
<Grid Margin="14,12,16,12">
<StackPanel Visibility="{Binding SelectedNode, Converter={StaticResource NullToVisibilityConverter}}">
<TextBlock Style="{StaticResource EditorTitle}" Text="节点属性" />
<TextBlock Style="{StaticResource LabelStyle}" Text="名称" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Name, UpdateSourceTrigger=PropertyChanged}" />
<UniformGrid Columns="2" Margin="0,0,0,12">
<StackPanel Margin="0,0,12,0">
<UniformGrid Columns="2" Margin="0,0,0,8">
<StackPanel Margin="0,0,8,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="索引" />
<TextBox Style="{StaticResource EditorBox}" IsReadOnly="True" Text="{Binding SelectedNode.Index, Mode=OneWay}" />
</StackPanel>
@@ -245,11 +272,11 @@
</UniformGrid>
<GroupBox
Margin="0,0,0,12"
Style="{StaticResource CompactGroupBox}"
Header="运动参数"
Visibility="{Binding SelectedNode.IsMotionSnapshotNode, Converter={StaticResource BoolToVisibilityConverter}}">
<UniformGrid Margin="12" Columns="2">
<StackPanel Margin="0,0,12,0">
<UniformGrid Margin="10,8,10,6" Columns="2">
<StackPanel Margin="0,0,8,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="XM" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.XM, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
@@ -257,7 +284,7 @@
<TextBlock Style="{StaticResource LabelStyle}" Text="YM" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.YM, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel Margin="0,0,12,0">
<StackPanel Margin="0,0,8,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="ZT" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.ZT, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
@@ -265,7 +292,7 @@
<TextBlock Style="{StaticResource LabelStyle}" Text="ZD" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.ZD, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel Margin="0,0,12,0">
<StackPanel Margin="0,0,8,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="TiltD" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.TiltD, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
@@ -277,10 +304,10 @@
</GroupBox>
<GroupBox
Margin="0,0,0,12"
Style="{StaticResource CompactGroupBox}"
Header="射线源"
Visibility="{Binding SelectedNode.IsReferencePoint, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Margin="12">
<StackPanel Margin="10,8,10,6">
<CheckBox Style="{StaticResource EditorCheck}" Content="射线源开启" IsChecked="{Binding SelectedNode.IsRayOn}" />
<TextBlock Style="{StaticResource LabelStyle}" Text="电压 (kV)" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Voltage, UpdateSourceTrigger=LostFocus}" />
@@ -290,10 +317,10 @@
</GroupBox>
<GroupBox
Margin="0,0,0,12"
Style="{StaticResource CompactGroupBox}"
Header="采集参数"
Visibility="{Binding SelectedNode.IsSaveNode, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Margin="12">
<StackPanel Margin="10,8,10,6">
<CheckBox Style="{StaticResource EditorCheck}" Content="射线源开启" IsChecked="{Binding SelectedNode.IsRayOn}" />
<TextBlock Style="{StaticResource LabelStyle}" Text="电压 (kV)" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Voltage, UpdateSourceTrigger=LostFocus}" />
@@ -309,10 +336,10 @@
</GroupBox>
<GroupBox
Margin="0,0,0,12"
Style="{StaticResource CompactGroupBox}"
Header="采集参数"
Visibility="{Binding SelectedNode.IsSaveNodeWithImage, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Margin="12">
<StackPanel Margin="10,8,10,6">
<CheckBox Style="{StaticResource EditorCheck}" Content="射线源开启" IsChecked="{Binding SelectedNode.IsRayOn}" />
<TextBlock Style="{StaticResource LabelStyle}" Text="电压 (kV)" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Voltage, UpdateSourceTrigger=LostFocus}" />
@@ -330,20 +357,20 @@
</GroupBox>
<GroupBox
Margin="0,0,0,12"
Style="{StaticResource CompactGroupBox}"
Header="检测模块"
Visibility="{Binding SelectedNode.IsInspectionModule, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Margin="12">
<StackPanel Margin="10,8,10,6">
<TextBlock Style="{StaticResource LabelStyle}" Text="Pipeline 名称" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.PipelineName, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</GroupBox>
<GroupBox
Margin="0,0,0,12"
Style="{StaticResource CompactGroupBox}"
Header="标记参数"
Visibility="{Binding SelectedNode.IsInspectionMarker, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Margin="12">
<StackPanel Margin="10,8,10,6">
<TextBlock Style="{StaticResource LabelStyle}" Text="标记类型" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.MarkerType, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Style="{StaticResource LabelStyle}" Text="MarkerX" />
@@ -354,28 +381,32 @@
</GroupBox>
<GroupBox
Margin="0,0,0,12"
Style="{StaticResource CompactGroupBox}"
Header="消息弹窗"
Visibility="{Binding SelectedNode.IsPauseDialog, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Margin="12">
<StackPanel Margin="10,8,10,6">
<TextBlock Style="{StaticResource LabelStyle}" Text="标题" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.DialogTitle, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Style="{StaticResource LabelStyle}" Text="消息内容" />
<TextBox
MinHeight="80"
Margin="0,0,0,12"
MinHeight="68"
Margin="0,0,0,8"
Padding="8,6"
AcceptsReturn="True"
BorderBrush="#CFCFCF"
BorderThickness="1"
FontFamily="{StaticResource UiFont}"
FontSize="11"
Text="{Binding SelectedNode.DialogMessage, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" />
</StackPanel>
</GroupBox>
<GroupBox
Margin="0,0,0,12"
Style="{StaticResource CompactGroupBox}"
Header="等待参数"
Visibility="{Binding SelectedNode.IsWaitDelay, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Margin="12">
<StackPanel Margin="10,8,10,6">
<TextBlock Style="{StaticResource LabelStyle}" Text="延时 (ms)" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.DelayMilliseconds, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
@@ -383,7 +414,7 @@
</StackPanel>
<Border
Padding="24"
Padding="18"
Background="#FAFAFA"
BorderBrush="#E6E6E6"
BorderThickness="1"
@@ -391,19 +422,260 @@
Visibility="{Binding SelectedNode, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Invert}">
<StackPanel>
<TextBlock
FontFamily="Microsoft YaHei UI"
FontSize="15"
FontFamily="{StaticResource UiFont}"
FontSize="14"
FontWeight="SemiBold"
Text="未选择节点" />
<TextBlock
Margin="0,8,0,0"
FontFamily="Microsoft YaHei UI"
Foreground="#666"
Text="从左侧树中选择一个节点后,这里会显示并允许编辑该节点的参数。" />
Margin="0,6,0,0"
FontFamily="{StaticResource UiFont}"
FontSize="11"
Foreground="#666666"
Text="从左侧树中选择一个节点后,这里会显示可编辑的参数。" />
</StackPanel>
</Border>
</Grid>
</ScrollViewer>
<Rectangle
Grid.Column="3"
Width="1"
Fill="{StaticResource SeparatorBrush}" />
<Grid Grid.Column="4">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border
Grid.Row="0"
Padding="8,6"
Background="{StaticResource HeaderBg}"
BorderBrush="{StaticResource SeparatorBrush}"
BorderThickness="0,0,0,1">
<TextBlock
FontFamily="{StaticResource UiFont}"
FontSize="12"
FontWeight="SemiBold"
Text="图像" />
</Border>
<Border
Grid.Row="1"
Padding="6,4"
BorderBrush="{StaticResource SeparatorBrush}"
BorderThickness="0,0,0,1">
<WrapPanel>
<Button Command="{Binding NewProgramCommand}" Content="新建" Style="{StaticResource ToolbarBtn}" />
<Button Command="{Binding SaveProgramCommand}" Content="保存" Style="{StaticResource ToolbarBtn}" />
<Button Command="{Binding ExportCsvCommand}" Content="另存为" Style="{StaticResource ToolbarBtn}" />
<Button Command="{Binding LoadProgramCommand}" Content="加载" Style="{StaticResource ToolbarBtn}" />
</WrapPanel>
</Border>
<Border
Grid.Row="2"
Margin="8,8,8,6"
Padding="10"
Background="#FBFBFB"
BorderBrush="#DDDDDD"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock
FontFamily="{StaticResource UiFont}"
FontSize="11"
FontWeight="SemiBold"
Foreground="#D90000"
Text="{Binding ProgramName, StringFormat='配方名:{0}.xpm'}" />
<Border
Grid.Row="1"
Margin="0,8,0,10"
Height="140"
Background="Black">
<Grid>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="{StaticResource UiFont}"
FontSize="11"
Foreground="White"
Opacity="0.72"
Text="图像预览区域" />
</Grid>
</Border>
<StackPanel Grid.Row="2">
<Button Command="{Binding InsertReferencePointCommand}" Style="{StaticResource InsertBtn}">
<StackPanel Orientation="Horizontal">
<Border
Width="20"
Height="20"
Margin="0,0,8,0"
Background="{StaticResource SoftBlue}"
BorderBrush="{StaticResource SoftBlueBorder}"
BorderThickness="1"
CornerRadius="4">
<Image Width="13" Height="13" Source="/Assets/Icons/reference.png" Stretch="Uniform" />
</Border>
<TextBlock VerticalAlignment="Center" Text="参考点" />
</StackPanel>
</Button>
<Button Command="{Binding InsertInspectionModuleCommand}" Style="{StaticResource InsertBtn}">
<StackPanel Orientation="Horizontal">
<Border
Width="20"
Height="20"
Margin="0,0,8,0"
Background="{StaticResource SoftBlue}"
BorderBrush="{StaticResource SoftBlueBorder}"
BorderThickness="1"
CornerRadius="4">
<Image Width="13" Height="13" Source="/Assets/Icons/Module.png" Stretch="Uniform" />
</Border>
<TextBlock VerticalAlignment="Center" Text="检测模块" />
</StackPanel>
</Button>
<Button Command="{Binding InsertInspectionMarkerCommand}" Style="{StaticResource InsertBtn}">
<StackPanel Orientation="Horizontal">
<Border
Width="20"
Height="20"
Margin="0,0,8,0"
Background="{StaticResource SoftBlue}"
BorderBrush="{StaticResource SoftBlueBorder}"
BorderThickness="1"
CornerRadius="4">
<Image Width="13" Height="13" Source="/Assets/Icons/mark.png" Stretch="Uniform" />
</Border>
<TextBlock VerticalAlignment="Center" Text="标记节点" />
</StackPanel>
</Button>
<Button Command="{Binding InsertSaveNodeCommand}" Style="{StaticResource InsertBtn}" Content="插入保存节点" />
<Button Command="{Binding InsertSaveNodeWithImageCommand}" Style="{StaticResource InsertBtn}" Content="插入带图像保存节点" />
<Button Command="{Binding InsertSavePositionCommand}" Style="{StaticResource InsertBtn}" Content="插入保存位置" />
<Button Command="{Binding InsertPauseDialogCommand}" Style="{StaticResource InsertBtn}" Content="插入消息节点" />
<Button Command="{Binding InsertWaitDelayCommand}" Style="{StaticResource InsertBtn}" Content="插入等待节点" />
<Button Command="{Binding InsertCompleteProgramCommand}" Style="{StaticResource InsertBtn}" Content="插入结束节点" />
</StackPanel>
</Grid>
</Border>
<Border
Grid.Row="3"
Padding="8,6"
Background="{StaticResource HeaderBg}"
BorderBrush="{StaticResource SeparatorBrush}"
BorderThickness="0,1,0,1">
<TextBlock
FontFamily="{StaticResource UiFont}"
FontSize="12"
FontWeight="SemiBold"
Text="参数配置" />
</Border>
<StackPanel Grid.Row="4" Margin="8,8,8,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="节点名称" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Name, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
<StackPanel Grid.Row="5" Margin="8,4,8,8">
<Grid Margin="0,0,0,6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="84" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
VerticalAlignment="Center"
FontFamily="{StaticResource UiFont}"
FontSize="11"
Text="节点类型" />
<TextBox
Grid.Column="1"
Height="26"
Padding="6,3"
BorderBrush="#CFCFCF"
BorderThickness="1"
FontFamily="{StaticResource UiFont}"
FontSize="11"
IsReadOnly="True"
Text="{Binding SelectedNode.NodeTypeDisplay}" />
</Grid>
<Grid Margin="0,0,0,6" Visibility="{Binding SelectedNode.IsMotionSnapshotNode, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="84" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
VerticalAlignment="Center"
FontFamily="{StaticResource UiFont}"
FontSize="11"
Text="Dist" />
<TextBox
Grid.Column="1"
Height="26"
Padding="6,3"
BorderBrush="#CFCFCF"
BorderThickness="1"
FontFamily="{StaticResource UiFont}"
FontSize="11"
Text="{Binding SelectedNode.Dist, UpdateSourceTrigger=LostFocus}" />
</Grid>
<Grid Margin="0,0,0,6" Visibility="{Binding SelectedNode.IsReferencePoint, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="84" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
VerticalAlignment="Center"
FontFamily="{StaticResource UiFont}"
FontSize="11"
Text="标准差" />
<TextBox
Grid.Column="1"
Height="26"
Padding="6,3"
BorderBrush="#CFCFCF"
BorderThickness="1"
FontFamily="{StaticResource UiFont}"
FontSize="11"
Text="{Binding SelectedNode.Current, UpdateSourceTrigger=LostFocus}" />
</Grid>
</StackPanel>
<Border
Grid.Row="6"
Padding="8,4"
Background="{StaticResource HeaderBg}"
BorderBrush="{StaticResource SeparatorBrush}"
BorderThickness="0,1,0,0">
<TextBlock
FontFamily="{StaticResource UiFont}"
FontSize="10.5"
Foreground="#555555"
Text="Status: 编辑界面已更新为紧凑布局" />
</Border>
</Grid>
</Grid>
</Border>
</UserControl>