#CNC检测模块概念设计

This commit is contained in:
zhengxuan.zhang
2026-04-21 12:56:22 +08:00
parent 238e97d110
commit b966e0b8e8
10 changed files with 134 additions and 301 deletions
@@ -261,6 +261,18 @@ namespace XplorePlane.ViewModels.Cnc
}
}
public PipelineModel Pipeline
{
get => _model is InspectionModuleNode im ? im.Pipeline : null;
set
{
if (_model is InspectionModuleNode im)
{
UpdateModel(im with { Pipeline = value ?? new PipelineModel() });
}
}
}
public string MarkerType
{
get => _model is InspectionMarkerNode mk ? mk.MarkerType : string.Empty;
@@ -508,6 +520,7 @@ namespace XplorePlane.ViewModels.Cnc
RaisePropertyChanged(nameof(FrameRate));
RaisePropertyChanged(nameof(Resolution));
RaisePropertyChanged(nameof(ImageFileName));
RaisePropertyChanged(nameof(Pipeline));
RaisePropertyChanged(nameof(PipelineName));
RaisePropertyChanged(nameof(MarkerType));
RaisePropertyChanged(nameof(MarkerX));
@@ -8,6 +8,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using XP.Common.Logging.Interfaces;
using XplorePlane.Events;
@@ -16,7 +17,7 @@ using XplorePlane.Services;
namespace XplorePlane.ViewModels
{
public class PipelineEditorViewModel : BindableBase
public class PipelineEditorViewModel : BindableBase, IPipelineEditorHostViewModel
{
private const int MaxPipelineLength = 20;
private const int DebounceDelayMs = 300;
@@ -165,6 +166,15 @@ namespace XplorePlane.ViewModels
public DelegateCommand<PipelineNodeViewModel> MoveNodeUpCommand { get; }
public DelegateCommand<PipelineNodeViewModel> MoveNodeDownCommand { get; }
ICommand IPipelineEditorHostViewModel.AddOperatorCommand => AddOperatorCommand;
ICommand IPipelineEditorHostViewModel.RemoveOperatorCommand => RemoveOperatorCommand;
ICommand IPipelineEditorHostViewModel.MoveNodeUpCommand => MoveNodeUpCommand;
ICommand IPipelineEditorHostViewModel.MoveNodeDownCommand => MoveNodeDownCommand;
ICommand IPipelineEditorHostViewModel.NewPipelineCommand => NewPipelineCommand;
ICommand IPipelineEditorHostViewModel.SavePipelineCommand => SavePipelineCommand;
ICommand IPipelineEditorHostViewModel.SaveAsPipelineCommand => SaveAsPipelineCommand;
ICommand IPipelineEditorHostViewModel.LoadPipelineCommand => LoadPipelineCommand;
// ── Command Implementations ───────────────────────────────────
private bool CanAddOperator(string operatorKey) =>
+16 -4
View File
@@ -21,6 +21,7 @@ namespace XplorePlane.ViewModels
{
public class MainViewModel : BindableBase
{
private const double CncEditorHostWidth = 1162d;
private readonly ILoggerService _logger;
private readonly IContainerProvider _containerProvider;
private readonly IEventAggregator _eventAggregator;
@@ -92,6 +93,13 @@ namespace XplorePlane.ViewModels
set => SetProperty(ref _imagePanelWidth, value);
}
/// <summary>主视图区宽度 | Main viewport width</summary>
public GridLength ViewportPanelWidth
{
get => _viewportPanelWidth;
set => SetProperty(ref _viewportPanelWidth, value);
}
// 窗口引用(单例窗口防止重复打开)
private Window _motionDebugWindow;
private Window _detectorConfigWindow;
@@ -100,7 +108,8 @@ namespace XplorePlane.ViewModels
private Window _toolboxWindow;
private Window _raySourceConfigWindow;
private object _imagePanelContent;
private GridLength _imagePanelWidth = new GridLength(350);
private GridLength _viewportPanelWidth = new GridLength(1, GridUnitType.Star);
private GridLength _imagePanelWidth = new GridLength(320);
private bool _isCncEditorMode;
public MainViewModel(ILoggerService logger, IContainerProvider containerProvider, IEventAggregator eventAggregator)
@@ -156,7 +165,8 @@ namespace XplorePlane.ViewModels
OpenRealTimeLogViewerCommand = new DelegateCommand(ExecuteOpenRealTimeLogViewer);
ImagePanelContent = new PipelineEditorView();
ImagePanelWidth = new GridLength(350);
ViewportPanelWidth = new GridLength(1, GridUnitType.Star);
ImagePanelWidth = new GridLength(320);
_logger.Info("MainViewModel 已初始化");
}
@@ -207,7 +217,8 @@ namespace XplorePlane.ViewModels
if (_isCncEditorMode)
{
ImagePanelContent = new PipelineEditorView();
ImagePanelWidth = new GridLength(350);
ViewportPanelWidth = new GridLength(1, GridUnitType.Star);
ImagePanelWidth = new GridLength(320);
_isCncEditorMode = false;
_logger.Info("已退出 CNC 编辑模式");
return;
@@ -227,7 +238,8 @@ namespace XplorePlane.ViewModels
private void ShowCncEditor()
{
ImagePanelContent = _cncPageView;
ImagePanelWidth = new GridLength(720);
ViewportPanelWidth = new GridLength(1, GridUnitType.Star);
ImagePanelWidth = new GridLength(CncEditorHostWidth);
_isCncEditorMode = true;
_logger.Info("CNC 编辑器已切换到主界面图像区域");
}
+2 -2
View File
@@ -4,9 +4,9 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cnc="clr-namespace:XplorePlane.Views.Cnc"
Title="CNC 编辑器"
Width="1180"
Width="1040"
Height="780"
MinWidth="1040"
MinWidth="960"
MinHeight="720"
ResizeMode="CanResize"
ShowInTaskbar="False"
+43 -273
View File
@@ -6,9 +6,10 @@
xmlns:local="clr-namespace:XplorePlane.Views.Cnc"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/"
xmlns:views="clr-namespace:XplorePlane.Views"
xmlns:vm="clr-namespace:XplorePlane.ViewModels.Cnc"
d:DesignHeight="760"
d:DesignWidth="1180"
d:DesignWidth="600"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d">
@@ -20,36 +21,8 @@
<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="26" />
<Setter Property="MinWidth" Value="40" />
<Setter Property="Margin" Value="2,0" />
<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="{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>
<Style x:Key="TreeItemStyle" TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="Padding" Value="0" />
@@ -96,18 +69,20 @@
</UserControl.Resources>
<Border
MinWidth="980"
Width="1162"
MinWidth="1162"
HorizontalAlignment="Left"
Background="{StaticResource PanelBg}"
BorderBrush="{StaticResource PanelBorder}"
BorderThickness="1"
CornerRadius="4">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="280" MinWidth="240" />
<ColumnDefinition Width="248" />
<ColumnDefinition Width="1" />
<ColumnDefinition Width="430" MinWidth="360" />
<ColumnDefinition Width="292" />
<ColumnDefinition Width="1" />
<ColumnDefinition Width="*" MinWidth="260" />
<ColumnDefinition Width="620" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
@@ -127,7 +102,7 @@
FontFamily="{StaticResource UiFont}"
FontSize="14"
FontWeight="SemiBold"
Text="{Binding ProgramName, TargetNullValue=NewCncProgram}" />
Text="{Binding ProgramName, TargetNullValue=CNC编辑}" />
<TextBlock
Margin="0,3,0,0"
FontFamily="{StaticResource UiFont}"
@@ -203,7 +178,7 @@
BorderThickness="1"
Command="{Binding DataContext.MoveNodeUpCommand, RelativeSource={RelativeSource AncestorType=TreeView}}"
CommandParameter="{Binding}"
Content=""
Content=""
Cursor="Hand"
FontSize="10"
ToolTip="上移" />
@@ -216,7 +191,7 @@
BorderThickness="1"
Command="{Binding DataContext.MoveNodeDownCommand, RelativeSource={RelativeSource AncestorType=TreeView}}"
CommandParameter="{Binding}"
Content=""
Content=""
Cursor="Hand"
FontSize="10"
ToolTip="下移" />
@@ -228,7 +203,7 @@
BorderBrush="#E05050"
BorderThickness="1"
Command="{Binding DataContext.DeleteNodeCommand, RelativeSource={RelativeSource AncestorType=TreeView}}"
Content="×"
Content=""
Cursor="Hand"
FontSize="10"
ToolTip="删除" />
@@ -253,7 +228,7 @@
Fill="{StaticResource SeparatorBrush}" />
<ScrollViewer Grid.Column="2" VerticalScrollBarVisibility="Auto">
<Grid Margin="14,12,16,12">
<Grid Margin="10">
<StackPanel Visibility="{Binding SelectedNode, Converter={StaticResource NullToVisibilityConverter}}">
<TextBlock Style="{StaticResource EditorTitle}" Text="节点属性" />
@@ -261,7 +236,7 @@
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Name, UpdateSourceTrigger=PropertyChanged}" />
<UniformGrid Columns="2" Margin="0,0,0,8">
<StackPanel Margin="0,0,8,0">
<StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="索引" />
<TextBox Style="{StaticResource EditorBox}" IsReadOnly="True" Text="{Binding SelectedNode.Index, Mode=OneWay}" />
</StackPanel>
@@ -275,8 +250,8 @@
Style="{StaticResource CompactGroupBox}"
Header="运动参数"
Visibility="{Binding SelectedNode.IsMotionSnapshotNode, Converter={StaticResource BoolToVisibilityConverter}}">
<UniformGrid Margin="10,8,10,6" Columns="2">
<StackPanel Margin="0,0,8,0">
<UniformGrid Margin="8,8,8,6" Columns="2">
<StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="XM" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.XM, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
@@ -284,7 +259,7 @@
<TextBlock Style="{StaticResource LabelStyle}" Text="YM" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.YM, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel Margin="0,0,8,0">
<StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="ZT" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.ZT, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
@@ -292,7 +267,7 @@
<TextBlock Style="{StaticResource LabelStyle}" Text="ZD" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.ZD, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel Margin="0,0,8,0">
<StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="TiltD" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.TiltD, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
@@ -307,7 +282,7 @@
Style="{StaticResource CompactGroupBox}"
Header="射线源"
Visibility="{Binding SelectedNode.IsReferencePoint, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Margin="10,8,10,6">
<StackPanel Margin="8,8,8,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}" />
@@ -320,7 +295,7 @@
Style="{StaticResource CompactGroupBox}"
Header="采集参数"
Visibility="{Binding SelectedNode.IsSaveNode, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Margin="10,8,10,6">
<StackPanel Margin="8,8,8,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}" />
@@ -339,7 +314,7 @@
Style="{StaticResource CompactGroupBox}"
Header="采集参数"
Visibility="{Binding SelectedNode.IsSaveNodeWithImage, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Margin="10,8,10,6">
<StackPanel Margin="8,8,8,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}" />
@@ -360,7 +335,7 @@
Style="{StaticResource CompactGroupBox}"
Header="检测模块"
Visibility="{Binding SelectedNode.IsInspectionModule, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Margin="10,8,10,6">
<StackPanel Margin="8,8,8,6">
<TextBlock Style="{StaticResource LabelStyle}" Text="Pipeline 名称" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.PipelineName, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
@@ -370,7 +345,7 @@
Style="{StaticResource CompactGroupBox}"
Header="标记参数"
Visibility="{Binding SelectedNode.IsInspectionMarker, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Margin="10,8,10,6">
<StackPanel Margin="8,8,8,6">
<TextBlock Style="{StaticResource LabelStyle}" Text="标记类型" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.MarkerType, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Style="{StaticResource LabelStyle}" Text="MarkerX" />
@@ -384,7 +359,7 @@
Style="{StaticResource CompactGroupBox}"
Header="消息弹窗"
Visibility="{Binding SelectedNode.IsPauseDialog, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Margin="10,8,10,6">
<StackPanel Margin="8,8,8,6">
<TextBlock Style="{StaticResource LabelStyle}" Text="标题" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.DialogTitle, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Style="{StaticResource LabelStyle}" Text="消息内容" />
@@ -414,7 +389,7 @@
</StackPanel>
<Border
Padding="18"
Padding="12"
Background="#FAFAFA"
BorderBrush="#E6E6E6"
BorderThickness="1"
@@ -443,237 +418,32 @@
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>
<views:PipelineEditorView
x:Name="InspectionModulePipelineEditor"
Visibility="{Binding EditorVisibility}" />
<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>
x:Name="InspectionModulePipelineEmptyState"
Margin="12"
Padding="16"
Background="#FAFAFA"
BorderBrush="#E6E6E6"
BorderThickness="1"
CornerRadius="6"
Visibility="{Binding EmptyStateVisibility}">
<StackPanel>
<TextBlock
FontFamily="{StaticResource UiFont}"
FontSize="11"
FontSize="14"
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>
Text="未选择检测模块" />
<TextBlock
Grid.Column="0"
VerticalAlignment="Center"
Margin="0,6,0,0"
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: 编辑界面已更新为紧凑布局" />
Foreground="#666666"
Text="请选择一个检测模块节点后,在这里拖拽算子并配置参数。" />
</StackPanel>
</Border>
</Grid>
</Grid>
+31 -2
View File
@@ -4,6 +4,8 @@ using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using XP.Common.Logging.Interfaces;
using XplorePlane.Services;
using XplorePlane.ViewModels.Cnc;
namespace XplorePlane.Views.Cnc
@@ -13,6 +15,8 @@ namespace XplorePlane.Views.Cnc
/// </summary>
public partial class CncPageView : UserControl
{
private CncInspectionModulePipelineViewModel _inspectionModulePipelineViewModel;
public CncPageView()
{
InitializeComponent();
@@ -21,17 +25,42 @@ namespace XplorePlane.Views.Cnc
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (DataContext is not CncEditorViewModel)
CncEditorViewModel editorViewModel = DataContext as CncEditorViewModel;
if (editorViewModel == null)
{
try
{
DataContext = ContainerLocator.Current?.Resolve<CncEditorViewModel>();
editorViewModel = ContainerLocator.Current?.Resolve<CncEditorViewModel>();
DataContext = editorViewModel;
}
catch (Exception)
{
// keep existing DataContext if resolution fails
}
}
if (editorViewModel == null || _inspectionModulePipelineViewModel != null)
return;
try
{
var imageProcessingService = ContainerLocator.Current.Resolve<IImageProcessingService>();
var persistenceService = ContainerLocator.Current.Resolve<IPipelinePersistenceService>();
var logger = ContainerLocator.Current.Resolve<ILoggerService>();
_inspectionModulePipelineViewModel = new CncInspectionModulePipelineViewModel(
editorViewModel,
imageProcessingService,
persistenceService,
logger);
InspectionModulePipelineEditor.DataContext = _inspectionModulePipelineViewModel;
InspectionModulePipelineEmptyState.DataContext = _inspectionModulePipelineViewModel;
}
catch (Exception)
{
// keep page usable even if pipeline editor host setup fails
}
}
private void CncTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
@@ -1,5 +1,5 @@
using System;
using Prism.Ioc;
using System;
using System.Windows;
using System.Windows.Controls;
using XP.Common.Logging.Interfaces;
@@ -23,7 +23,7 @@ namespace XplorePlane.Views
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (DataContext is not PipelineEditorViewModel)
if (DataContext is not IPipelineEditorHostViewModel)
{
try
{
@@ -46,36 +46,35 @@ namespace XplorePlane.Views
private void OnDragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(OperatorToolboxView.DragFormat))
e.Effects = DragDropEffects.Copy;
else
e.Effects = DragDropEffects.None;
e.Effects = e.Data.GetDataPresent(OperatorToolboxView.DragFormat)
? DragDropEffects.Copy
: DragDropEffects.None;
e.Handled = true;
}
private void OnOperatorDropped(object sender, DragEventArgs e)
{
if (DataContext is not PipelineEditorViewModel vm)
if (DataContext is not IPipelineEditorHostViewModel vm)
{
_logger?.Warn("Drop 事件触发但 DataContext 不是 PipelineEditorViewModel");
_logger?.Warn("Drop 事件触发但 DataContext 不是流水线宿主 ViewModel");
return;
}
if (!e.Data.GetDataPresent(OperatorToolboxView.DragFormat))
{
_logger?.Warn("Drop 事件触发但数据中没有 {Format}", OperatorToolboxView.DragFormat);
_logger?.Warn("Drop 事件触发但数据中没有 {Format}", OperatorToolboxView.DragFormat);
return;
}
var operatorKey = e.Data.GetData(OperatorToolboxView.DragFormat) as string;
if (string.IsNullOrEmpty(operatorKey))
if (string.IsNullOrWhiteSpace(operatorKey))
{
_logger?.Warn("Drop 事件触发但 OperatorKey 为空");
_logger?.Warn("Drop 事件触发但 OperatorKey 为空");
return;
}
_logger?.Info("算子已放入流水线:{OperatorKey}VM HashCode={Hash}当前节点数(执行前)={Count}",
operatorKey, vm.GetHashCode(), vm.PipelineNodes.Count);
_logger?.Info("算子已放入流水线:{OperatorKey},当前节点数(执行前)={Count}",
operatorKey, vm.PipelineNodes.Count);
vm.AddOperatorCommand.Execute(operatorKey);
_logger?.Info("AddOperator 执行后节点数={Count}PipelineListBox.Items.Count={ItemsCount}",
vm.PipelineNodes.Count, PipelineListBox.Items.Count);
+1 -1
View File
@@ -13,7 +13,7 @@
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Row="0" Background="#F0F0F0" BorderBrush="#DDDDDD" BorderThickness="0,0,0,1">
<TextBlock Margin="8,4" HorizontalAlignment="Left" VerticalAlignment="Center"
<TextBlock Margin="4,2" HorizontalAlignment="Left" VerticalAlignment="Center"
FontWeight="SemiBold" Foreground="#333333" Text="图像" />
</Border>
<ContentControl Grid.Row="1" Content="{Binding ImagePanelContent}" />
+3 -3
View File
@@ -400,7 +400,7 @@
Size="Large"
SmallImage="/Assets/Icons/spiral.png" />
</telerik:RadRibbonGroup>
<!--
<!--
<telerik:RadRibbonGroup Header="图像处理">
<telerik:RadRibbonGroup.Variants>
<telerik:GroupVariant Priority="0" Variant="Large" />
@@ -470,9 +470,9 @@
Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="NavColumn" Width="0" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="{Binding ViewportPanelWidth}" />
<ColumnDefinition Width="{Binding ImagePanelWidth}" />
<ColumnDefinition Width="350" />
<ColumnDefinition Width="300" />
</Grid.ColumnDefinitions>
<!-- 左侧: 计划导航 (默认隐藏,点击CNC AccountingNumberFormatButton显示) -->
@@ -19,7 +19,7 @@
<!-- 标题栏 -->
<Border Grid.Row="0" Background="#F0F0F0" BorderBrush="#DDDDDD" BorderThickness="0,0,0,1">
<TextBlock Margin="8,4" HorizontalAlignment="Left" VerticalAlignment="Center"
<TextBlock Margin="4,2" HorizontalAlignment="Left" VerticalAlignment="Center"
FontWeight="SemiBold" Foreground="#333333" Text="实时图像" />
</Border>
@@ -30,7 +30,7 @@
<!-- 图像信息栏 -->
<Border Grid.Row="2" Background="#F0F0F0" BorderBrush="#DDDDDD" BorderThickness="0,1,0,0">
<TextBlock Margin="8,2" FontSize="11" Foreground="#666666"
<TextBlock Margin="4,2" FontSize="11" Foreground="#666666"
Text="{Binding ImageInfo}" />
</Border>
</Grid>