MVVM
Base
csharp
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace WpfApp5
{
public class InotifyBase:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName=null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace WpfApp5
{
public class RelayCommand : ICommand
{
private Action _execute;
private Func<bool> _canExecute;
public RelayCommand(Action execute, Func<bool> canExecute = null)
{
_execute = execute ?? throw new ArgumentException(nameof(_canExecute));
_canExecute = canExecute??(() => true);
}
public RelayCommand(Action execute)
{
_execute = execute ?? throw new ArgumentException(nameof(_canExecute));
_canExecute = () => true;
}
public event EventHandler CanExecuteChanged {
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)=>
_canExecute();
//{
// throw new NotImplementedException();
//}
public void Execute(object parameter)=>
_execute();
//{
// throw new NotImplementedException();
//}
}
}
ViewModel
csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace WpfApp5
{
public class MainViewModel: InotifyBase
{
private string name;
public string Name
{
get { return name; }
set { name = value;
OnPropertyChanged();
}
}
public RelayCommand CCommand { get; set; }
public MainViewModel()
{
CCommand = new RelayCommand(cc);
Name = "张三";
}
private void cc()
{
// throw new NotImplementedException();
MessageBox.Show("Hello " + Name);
}
}
}
View
csharp
<Window x:Class="WpfApp5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp5"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Top">
<Button Content="Button 1" Margin="5" Command="{Binding CCommand}"/>
<TextBox Text="{Binding Name}"/>
</StackPanel>
</Grid>
</Window>
csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp5
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}
}


X 光检测业务流程梳理
基础框架
设备启动流程:打开 X 光机 → 初始化平板探测器 → 自检 XY 运动平台 → 设备就绪;
(1)设备启动流程:对应硬件 SDK 对接、运动控制、WPF 状态绑定
打开 X 光机:通过硬件 SDK下发设备上电指令,持续轮询设备状态,确认上电成功;
初始化平板探测器:调用探测器 SDK 接口完成初始化,配置图像采集的基础参数,同时处理通信失败、硬件报错等异常;
自检 XY 运动平台:下发原点回归指令,读取轴卡状态,校验限位、电机运行状态,自检失败时在上位机弹窗提示;
设备就绪:通过 WPF 数据绑定,更新界面设备状态,解锁扫描按钮,控制 UI 的启用 / 禁用。
扫描检测流程:配置扫描参数 → XY 轴移动至起始位置 → 触发 X 光发射 + 图像采集 → 调用自研算法分析 → 结果展示 + 数据保存 + 报表生成;
(2)扫描检测流程:对应 WPF 界面、运动控制、Halcon 图像、数据库、报表
配置扫描参数:通过 MVVM 双向绑定,实现扫描参数的界面配置,同时校验参数数值范围,最后将参数下发至硬件;
XY 轴移动至起始位置:下发绝对定位指令,等待轴卡反馈到位信号,完成点位移动;
触发 X 光发射 + 图像采集:实现同步触发逻辑(上位机核心难点),控制 X 光发射和探测器图像采集的时序,采集后将图像转为HImage格式,适配 Halcon 处理;
调用自研算法:调用 Halcon 自研算法接口,传入图像数据,接收缺陷的坐标、大小、类型等结果;
结果展示 + 数据保存 + 报表生成:在 WPF 界面可视化标记缺陷位置,使用 SQLite 存储图像和检测数据,最后自动生成 Excel 检测报表。
(3)核心术语的岗位化理解
硬件 SDK 适配
封装 X 光机、探测器、运动轴卡的 SDK 指令,实现上位机和硬件的通信;
灰度图像
图像的 WPF 界面显示,以及为 Halcon 算法提供图像数据;X 光拍摄出来的基础画面,只有明暗灰度、无彩色,是算法分析的原始素材。
XY 扫描平台
运动控制的点位移动、原点回归等逻辑;电机驱动的运动机构,带动产品前后左右移动,完成全覆盖扫描作业。
硬件 SDK 适配:调用设备官方接口程序,实现上位机操控 X 光机、探测器、运动轴,收发指令与数据。
缺陷检测、三维重建:
调用算法,并将算法的分析结果可视化展示。
缺陷检测:通过图像分析,识别产品内部裂纹、气泡、杂质等不良瑕疵。
三维重建:把多张二维扫描图像整合,还原产品立体内部结构,精准判断缺陷位置与深度。
X 光平板探测器
X 光成像核心硬件,接收射线信号,转换成数字图像,负责图像采集
速记小关联
平台走位→探测器拍片→生成灰度图→算法查缺陷→可立体建模→全程靠 SDK 对接硬件
运动控制基础
X光场景运动控制
适合口头沟通、面试应答,好记易懂
运动平台核心作用
搭载并带动工件平稳移动,配合X光射线完成产品全覆盖扫描,获取完整内部成像,保障检测无盲区。
核心交互逻辑(固定时序流程)
上位机下发运动控制指令 → 轴卡接收指令驱动XY平台移动 → 平台抵达指定位置、反馈到位信号 → 触发X光发射与图像采集
4项基础运动指令&实际用途
- 点位定位
控制轴移动到预设扫描起始坐标,做好拍摄准备。 - 匀速扫描
控制平台低速平稳连续移动,同步逐帧采集图像。 - 设备回零
开机自检、每次检测结束后,让轴回归基准原点,校准坐标位置。 - 急停停止
遇到异常、故障时立刻终止运动,保护设备与工件安全。