1、超炫颜值



2、项目背景
自动生产管理平台(Automated Production Management Platform)是一种基于现代信息技术(如工业互联网、物联网、大数据、人工智能等)构建的综合性软件系统。
它的核心目标是将传统依赖人工操作和纸质记录的生产管理流程,转变为数字化、智能化和自动化的运行模式。简单来说,就是让工厂的 "大脑"(管理系统)能够自动感知、自动决策、自动调度和自动监控生产过程。
1. 核心功能:它能做什么?
一个成熟的自动生产管理平台通常集成了以下几个关键模块:
- 生产计划自动排程 (APS) :
- 传统模式:计划员根据经验手工排产,容易出错且难以应对插单、急单。
- 平台模式:系统根据订单需求、物料库存、设备状态自动计算出最优的生产计划,并自动下发到各个生产单元。
- 设备联网与数据采集 (SCADA/MES) :
- 传统模式:工人定时去看仪表读数,或设备坏了才发现。
- 平台模式:平台自动连接 PLC、传感器和机床,实时采集产量、温度、压力、设备故障等数据,无需人工干预。
- 物料自动配送与仓储 (WMS/AGV) :
- 传统模式:工人推着小车去仓库领料,容易发错料或库存不准。
- 平台模式:系统根据生产进度,自动指令 AGV(自动导引车)去仓库取货并送到生产线边,同时自动扣减库存。
- 质量管理自动化 (QMS) :
- 传统模式:人工抽检,填写纸质检验单,事后分析慢。
- 平台模式:检测设备自动将数据上传平台,系统自动判定合格与否。若发现异常(如尺寸偏差变大),系统可自动触发报警甚至暂停生产线。
- 能源与能耗管理 :
- 自动监控水、电、气的消耗,分析能耗瓶颈,自动优化设备启停时间以节约成本。
2. 关键技术支撑
该平台之所以能 "自动",主要依赖以下技术:
- 物联网 (IoT):实现物理设备与软件系统的互联互通。
- 大数据分析:处理海量的生产数据,找出生产规律和瓶颈。
- 人工智能 (AI):用于预测性维护(预测设备什么时候会坏)、智能排产和质量缺陷图像识别。
- 数字孪生 (Digital Twin):在电脑上建立一个虚拟的工厂,实时映射现实工厂的运行状态,方便模拟和监控。
3. 带来的价值(为什么要用?)
- 降本增效:减少了大量的统计员、仓管员和调度员,生产效率显著提升。
- 质量追溯:产品出了问题,平台可以一键查询出是哪台设备生产的、哪个工人操作的、用了哪批原材料、当时的工艺参数是多少。
- 柔性生产:能够快速响应市场变化,支持多品种、小批量的混线生产。
- 透明化管理:老板或管理者在手机或电脑上就能实时看到工厂的每一个角落的实时状态,而不需要去车间。
4. 与传统管理软件的区别

自动生产管理平台 是智能制造(Smart Manufacturing)的核心枢纽。它就像一个智能管家,不仅能帮你记录账目,还能实时指挥机器干活、调配物料、监控质量,并在问题发生前提前预警
3、案例介绍
WPF(Windows Presentation Foundation)是微软推出的桌面应用开发框架,特别适合开发工业场景下的自动化生产管理平台 ------ 它既能满足工业软件对高性能、实时性的要求,又能轻松实现复杂的可视化界面(比如生产看板、设备监控仪表盘)。
一、WPF 开发该平台的核心优势
为什么工业场景首选 WPF 而非 WinForm/Qt?
- 强大的可视化能力:支持矢量图形、3D 渲染、自定义控件模板,能轻松做出专业的生产监控大屏、设备状态仪表盘。
- 数据绑定与 MVVM 架构:天然适配 MVVM 模式,实现界面与业务逻辑解耦,便于后期维护和功能扩展(工业软件迭代频繁,这点至关重要)。
- 高性能与实时性:基于 DirectX 渲染,比 WinForm 更流畅,能高效处理设备实时上报的海量数据(如每秒数百条的设备状态数据)。
- 丰富的控件生态:可集成 LiveCharts(图表)、OxyPlot(工控图表)、DevExpress(工业级控件库)等,快速实现工控场景的 UI。
- 跨线程处理友好:工业场景中需要频繁从串口 / 网口接收设备数据(子线程),WPF 的 Dispatcher 机制能安全更新 UI,避免界面卡顿。
二、WPF 版自动化生产管理平台核心架构
一个典型的架构分为 4 层,完全遵循 MVVM 设计模式,4 层架构与 MVVM 的对应关系是:设备层(物理层)→ 数据采集层(接口层)→ 业务逻辑层(ViewModel 核心)→ UI 展示层(View 层),其中 MVVM 的 Model 贯穿前三层,是数据载体的核心。以下是每层的详细拆解:

1. 设备层(物理层)
- 核心定位:平台的 "数据源",是所有生产数据的源头。
- 关键特性 :
- 数据格式不统一(不同设备协议不同:Modbus 寄存器、OPC UA 节点、串口指令);
- 要求高可靠性(工业设备 7×24 运行,断连需快速检测);
- 实时性要求(毫秒级数据采集,如设备温度 / 转速)。
- 与上层交互:仅通过数据采集层提供的通信协议暴露数据,不直接对接业务层
2. 数据采集层(接口层 / Model 层)
- 核心定位:"数据翻译官",将设备层的异构数据转换为平台统一的 Model 模型。
- 核心职责 :✅ 设备连接管理(断线重连、心跳检测);✅ 原始数据解析(如 Modbus 寄存器值→温度 / 产量,OPC UA 节点→设备状态);✅ 数据标准化(封装为
DeviceRealTimeData/ProductionPlan等 Model);✅ 数据预处理(过滤无效值、补全缺失数据、单位转换)。
3. 业务逻辑层(ViewModel 层)
- 核心定位:平台的 "大脑",MVVM 的核心层,承上启下。
- 核心职责 :✅ 订阅采集层的数据更新事件,处理业务规则(如温度 > 35℃触发报警、产量统计);✅ 封装 UI 交互命令(如启动 / 停止采集、下发生产计划、导出报表);✅ 数据持久化(将实时数据写入数据库,供历史查询 / 报表分析);✅ 状态通知(通过
INotifyPropertyChanged通知 UI 层更新)。
4. UI 展示层(View 层)
- 核心定位:"可视化面板",纯展示 + 交互,无任何业务逻辑。
- 核心职责:✅ 通过数据绑定接收 ViewModel 的状态更新(如设备列表、温度趋势);✅ 提供用户操作入口(按钮 / 输入框),绑定 ViewModel 的命令;✅ 工业级可视化(生产看板、设备仪表盘、报警弹窗)。
核心依赖组件(必选):
- 数据采集:
OpcUaClient(对接工业设备)、Modbus.Device(Modbus 协议) - MVVM 框架:
Prism/MvvmLight(简化 MVVM 开发) - 实时图表:
LiveCharts.Wpf(生产数据趋势图) - 数据库:
SqlSugar/EF Core(对接 SQL Server/MySQL) - 异步处理:
Task/Async/Await(处理实时数据接收)
数据流向

- 正向流:设备原始数据 → 采集层标准化 → 业务层处理 → UI 展示;
- 反向流:用户操作(UI 按钮)→ ViewModel 命令 → 采集层控制设备 → 设备执行动作。
4、技术体系
1)项目技能点
Livechart图表控件,用户控件,自定义控件,MVVM模式,硬件对接,通信协议
2)开发环境
开发工具:Visual Studio 2022
开发语言:C#
UI 框架:WPF
运行时框架:.Net 6.0
设备 :Modbus Slave,Configure Virtual Serial Port Driver
协议:ModbusRtu
依赖:Livechart,NModbus,SerialPort

3)代码展示



cs
<Window
x:Class="West.Automatic.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:local="clr-namespace:West.Automatic"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Name="window"
Title="领航自动化生产管理平台"
Width="1150"
Height="750"
Background="Transparent"
FontFamily="Microsoft YaHei"
FontSize="12"
FontWeight="ExtraLight"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<WindowChrome.WindowChrome>
<WindowChrome GlassFrameThickness="-1" />
</WindowChrome.WindowChrome>
<Window.Resources>
<Style x:Key="ControlButtonStyle" TargetType="Button">
<Setter Property="Width" Value="40" />
<Setter Property="Background" Value="#11FFFFFF" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontFamily" Value="Assets/Fonts/#iconfont" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="{TemplateBinding Background}">
<Border x:Name="root">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="root" Property="Background" Value="#33FFFFFF" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.Background>
<!-- 从中心向外辐射的渐变效果 -->
<RadialGradientBrush>
<!-- GradientStops:定义渐变颜色的关键点集合。 -->
<GradientStop Offset="0" Color="#FF285173" />
<GradientStop Offset="0.3" Color="#FF244967" />
<GradientStop Offset="1" Color="#FF14273A" />
</RadialGradientBrush>
</Grid.Background>
<!-- 整体分三部分,上部占45,底部占20,其他都给中间 -->
<Grid.RowDefinitions>
<RowDefinition Height="45" />
<RowDefinition />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<!-- 第一行:头部标题布局 -->
<Border BorderBrush="#5518AABD" BorderThickness="0,0,0,1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!-- 第一列图片 -->
<Image Margin="10,7" Source="Assets/Images/Logo.png" />
<!-- 第二列文字,采用stackpanel的垂直布局 -->
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock
FontSize="16"
Foreground="White"
Text="{Binding Title, ElementName=window}" />
<TextBlock
Margin="0,2,0,0"
FontSize="10"
Foreground="LightGray"
Text="日月神华 只为财富 领航科技 创造未来" />
</StackPanel>
<!-- 第三列,分两行, -->
<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="13" />
</Grid.RowDefinitions>
<!-- 第一行放最大最小关闭按钮 -->
<Border
Width="200"
HorizontalAlignment="Right"
BorderBrush="Transparent"
WindowChrome.IsHitTestVisibleInChrome="True">
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button Content="" Style="{StaticResource ControlButtonStyle}" />
<Button Content="" Style="{StaticResource ControlButtonStyle}" />
<Button
Background="DarkRed"
Content=""
Style="{StaticResource ControlButtonStyle}" Click="Button_Click" />
</StackPanel>
</Border>
<!-- 第二行放线条装饰 -->
<Border
Grid.Row="1"
BorderBrush="#5518AABD"
BorderThickness="0,1,0,0" />
<Border Grid.Row="1" Margin="0,3,0,2">
<Border.Background>
<VisualBrush
TileMode="Tile"
Viewport="0,0,7,7"
ViewportUnits="Absolute">
<VisualBrush.Visual>
<Grid Width="20" Height="20">
<Line
Stroke="Gray"
StrokeThickness="1"
X1="0"
X2="10"
Y1="10"
Y2="0" />
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Border.Background>
</Border>
</Grid>
</Grid>
</Border>
<!-- 第二行:内容部分 -->
<ContentControl Grid.Row="1" Content="{Binding PageContent}" />
<!-- 第三行:状态栏 -->
<Border
Grid.Row="2"
BorderBrush="#5518AABD"
BorderThickness="0,1,0,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Margin="0,5">
<Border.Background>
<VisualBrush
TileMode="Tile"
Viewport="0,0,7,7"
ViewportUnits="Absolute">
<VisualBrush.Visual>
<Grid Width="20" Height="20">
<Line
Stroke="Gray"
StrokeThickness="1"
X1="0"
X2="10"
Y1="10"
Y2="0" />
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Border.Background>
</Border>
<TextBlock
Grid.Column="1"
Margin="10,1"
VerticalAlignment="Center"
FontSize="11"
FontWeight="Bold"
Foreground="White"
Text="2026 北京领航智能科技有限公司 Co.Ltd" />
</Grid>
</Border>
</Grid>
</Window>
cs
<UserControl
x:Class="West.Automatic.Views.MonitorView"
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:local="clr-namespace:West.Automatic.Views"
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:zxc="clr-namespace:West.Automatic.Controls"
d:DesignHeight="450"
d:DesignWidth="1100"
mc:Ignorable="d">
<UserControl.Resources>
<!-- 作用于groupbox控件的样式 -->
<Style TargetType="GroupBox">
<Setter Property="Margin" Value="10,5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupBox">
<Grid>
<Polyline
HorizontalAlignment="Left"
VerticalAlignment="Top"
Points="0 30,0 10,10 0,30 0"
Stroke="#9918AABD"
StrokeThickness="1" />
<Ellipse
Width="4"
Height="4"
Margin="24,-2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Fill="#9918AABD" />
<Ellipse
Width="4"
Height="4"
Margin="-2,24,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Fill="#9918AABD" />
<Path
HorizontalAlignment="Right"
VerticalAlignment="Top"
Data="M0 0,3 3,30 3,33 0,68 0,73 7,78 7,78 10M8 0,25 0"
Stroke="#5518AABD" />
<Polyline
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Points="0,0 0,15 10,15"
Stroke="#5518AABD" />
<Polyline
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Points="10,0 0,10"
Stroke="#5518AABD" />
<Polygon
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Fill="#9918AABD"
Points="0,7 7 7 7 0" />
<Border
Margin="30,-0.5,78,0"
VerticalAlignment="Top"
BorderBrush="#5518AABD"
BorderThickness="0,1,0,0" />
<Border
Margin="0,10"
HorizontalAlignment="Right"
BorderBrush="#5518AABD"
BorderThickness="0,0,1,0" />
<Border
Margin="10,0"
VerticalAlignment="Bottom"
BorderBrush="#5518AABD"
BorderThickness="0,1,0,0" />
<Border
Margin="-0.5,15"
HorizontalAlignment="Left"
BorderBrush="#5518AABD"
BorderThickness="0,0,1,0" />
<Path
Margin="10,13"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Data="M0 0,3 0,5 4,3 8,0 8,3 4"
Fill="#9918AABD" />
<Path
Margin="16,13"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Data="M0 0,3 0,5 4,3 8,0 8,3 4"
Fill="#5518AABD" />
<TextBlock
Margin="25,8"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Foreground="#99FFFFFF"
Text="{TemplateBinding Header}" />
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<!-- 整体分三行,上面占50,下面占120,其他给中间 -->
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition />
<RowDefinition Height="120" />
</Grid.RowDefinitions>
<!-- 第一行布局,分两列 -->
<!-- 第一行 -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
FontFamily="../Assets/Fonts/#digital_display"
FontSize="30"
Foreground="White"
Text="20:00" />
<StackPanel
Margin="15,0,0,0"
TextBlock.FontSize="10"
TextBlock.Foreground="White">
<TextBlock Text="2022-07-05" />
<TextBlock HorizontalAlignment="Right" Text="星期五" />
</StackPanel>
</StackPanel>
<!-- 计数 -->
<StackPanel
Grid.Column="1"
Margin="20,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Orientation="Horizontal">
<!-- 定义资源,用于ItemsControl的数据模板 -->
<StackPanel.Resources>
<DataTemplate x:Key="dataTemp">
<Border
Width="15"
Margin="2,0"
Background="#3318AABD">
<TextBlock
HorizontalAlignment="left"
VerticalAlignment="Center"
FontSize="16"
FontWeight="Normal"
Foreground="White"
Text="{Binding}" />
</Border>
</DataTemplate>
</StackPanel.Resources>
<!-- 图标 -->
<TextBlock
VerticalAlignment="Center"
FontFamily="../Assets/Fonts/#iconfont"
FontSize="20"
Foreground="#55FFFFFF"
Text="" />
<!-- 机台总数 -->
<TextBlock
Margin="10,0"
VerticalAlignment="Center"
FontSize="10"
Foreground="#99FFFFFF"
Text="机台 总数" />
<ItemsControl ItemTemplate="{StaticResource dataTemp}" ItemsSource="{Binding Total}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<!-- 生产计数 -->
<TextBlock
Margin="20,0,10,0"
VerticalAlignment="Center"
Foreground="#99FFFFFF"
Text="生产计数" />
<ItemsControl ItemTemplate="{StaticResource dataTemp}" ItemsSource="{Binding ProductionCount}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<!-- 不良计数 -->
<TextBlock
Margin="20,0,10,0"
VerticalAlignment="Center"
Foreground="#99FFFFFF"
Text="不良计数" />
<ItemsControl ItemTemplate="{StaticResource dataTemp}" ItemsSource="{Binding BadCount}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
<!-- 配置按钮 -->
<Button
Grid.Column="1"
Width="80"
Height="33"
Margin="20,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Command="{Binding SettingsCommand, RelativeSource={RelativeSource AncestorType=Window}}"
Content="配置"
Style="{StaticResource ButtonStyle}"
Tag="" />
</Grid>
<!-- 第二行布局,分三列 -->
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!-- 第1列包含3个groupbox:环境,产能,质量 -->
<UniformGrid
Grid.Column="0"
Margin="10,0"
Columns="1">
<!-- 环境面板 -->
<GroupBox Header="环境">
<ItemsControl VerticalAlignment="Center" ItemsSource="{Binding Evironment}">
<!-- 面板模板 -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="4" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- 项模板 -->
<ItemsControl.ItemTemplate>
<!-- 数据模板 -->
<DataTemplate>
<StackPanel
Margin="0,5"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock
Margin="0,5"
HorizontalAlignment="Center"
FontSize="16"
Foreground="#FF2BEDF1"
Text="{Binding Value}" />
<TextBlock
FontSize="10"
Foreground="#AAFFFFFF"
Text="{Binding Header}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</GroupBox>
<!-- 产能面板:柱状图 -->
<GroupBox Header="产能">
<Grid>
<lvc:CartesianChart Margin="20,35,20,5">
<!-- 序列部分:包含2个序列(生产计数和不良计数) -->
<lvc:CartesianChart.Series>
<lvc:ColumnSeries
Title="生产计数"
MaxColumnWidth="10"
Values="300,400,480,450,380,450,450,330,340,280,220">
<lvc:ColumnSeries.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#FF3FBBE6" />
<GradientStop Offset="1" Color="#FF2BEDF1" />
</LinearGradientBrush>
</lvc:ColumnSeries.Fill>
</lvc:ColumnSeries>
<lvc:ColumnSeries
Title="不良计数"
MaxColumnWidth="10"
Values="15,55,15,40,38,45,25,15">
<lvc:ColumnSeries.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#FFFB9A9A" />
<GradientStop Offset="1" Color="#FFFF5151" />
</LinearGradientBrush>
</lvc:ColumnSeries.Fill>
</lvc:ColumnSeries>
</lvc:CartesianChart.Series>
<!-- X轴数据 -->
<lvc:CartesianChart.AxisX>
<lvc:Axis Labels="8:00,9:00,10:00,11:00,12:00,13:00,14:00,15:00,16:00,17:00,18:00">
<lvc:Axis.Separator>
<lvc:Separator Step="1" StrokeThickness="0" />
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisX>
<!-- Y轴数据 -->
<lvc:CartesianChart.AxisY>
<lvc:Axis MaxValue="500" MinValue="0">
<lvc:Axis.Separator>
<lvc:Separator Step="100" Stroke="#11FFFFFF" />
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisY>
</lvc:CartesianChart>
<StackPanel
Margin="10"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Orientation="Horizontal">
<Border
Width="6"
Height="6"
Margin="5,0"
Background="#FF2BEDF1" />
<TextBlock
FontSize="10"
Foreground="#44FFFFFF"
Text="生产计数" />
<Border
Width="6"
Height="6"
Margin="5,0"
Background="#FFFF5151" />
<TextBlock
FontSize="10"
Foreground="#44FFFFFF"
Text="不良计数" />
</StackPanel>
</Grid>
</GroupBox>
<!-- 质量面板:拆线图 -->
<GroupBox Header="质量">
<lvc:CartesianChart Margin="20,35,20,5">
<!-- 序列部分 -->
<lvc:CartesianChart.Series>
<lvc:LineSeries
Title="不良计数"
PointGeometrySize="0"
Stroke="#FF2BEDF1"
StrokeThickness="1"
Values="15,55,15,40,38,45,25,15,45,25,15,49">
<lvc:LineSeries.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#552BEDF1" />
<GradientStop Offset="1" Color="Transparent" />
</LinearGradientBrush>
</lvc:LineSeries.Fill>
</lvc:LineSeries>
</lvc:CartesianChart.Series>
<!-- X轴数据 -->
<lvc:CartesianChart.AxisX>
<lvc:Axis Labels="8:00,9:00,10:00,11:00,12:00,13:00,14:00,15:00,16:00,17:00,18:00">
<lvc:Axis.Separator>
<lvc:Separator Step="1" StrokeThickness="0" />
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisX>
<!-- Y轴数据 -->
<lvc:CartesianChart.AxisY>
<lvc:Axis MaxValue="100" MinValue="0">
<lvc:Axis.Separator>
<lvc:Separator Step="20" Stroke="#11FFFFFF" />
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisY>
</lvc:CartesianChart>
</GroupBox>
</UniformGrid>
<!-- 第2列包含3个内容 -->
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="120" />
<RowDefinition Height="1.5*" />
</Grid.RowDefinitions>
<!-- 第1行放边框 -->
<Border
Grid.RowSpan="2"
Width="400"
Height="150"
HorizontalAlignment="Right"
VerticalAlignment="Top">
<Border.Background>
<ImageBrush ImageSource="../Assets/Images/device.png" Stretch="Uniform" />
</Border.Background>
</Border>
<!-- 第2行放报警记录:数据列表 -->
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontWeight="Normal"
Foreground="#99FFFFFF">
<Run FontFamily="../Assets/Fonts/#iconfont" Text="" />
<Run Text="报警记录" />
</TextBlock>
<ItemsControl Grid.Row="1" ItemsSource="{Binding AlarmList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Height="23">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="1.3*" />
<ColumnDefinition />
<ColumnDefinition Width="0.5*" />
</Grid.ColumnDefinitions>
<Border
Width="6"
Height="6"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="IndianRed"
CornerRadius="3" />
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontWeight="Normal"
Foreground="#992BEDF1"
Text="{Binding Num}" />
<TextBlock
Grid.Column="2"
VerticalAlignment="Center"
FontWeight="Normal"
Foreground="#992BEDF1"
Text="{Binding Message}" />
<TextBlock
Grid.Column="3"
VerticalAlignment="Center"
FontWeight="Normal"
Foreground="#992BEDF1"
Text="{Binding Time}" />
<TextBlock
Grid.Column="4"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontWeight="Normal"
Foreground="#992BEDF1"
Text="{Binding Duration, StringFormat=时长{0}秒}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
<!-- 第3行放报警比率:饼状图 -->
<GroupBox
Grid.Row="2"
Margin="0,5"
Header="数据异常报警比率">
<lvc:PieChart Margin="0,40,0,20" InnerRadius="45">
<lvc:PieChart.Resources>
<Style TargetType="lvc:PieSeries">
<Setter Property="DataLabelsTemplate">
<Setter.Value>
<!-- 数据模板 -->
<DataTemplate>
<StackPanel Orientation="Horizontal" TextBlock.Foreground="#44FFFFFF">
<!-- 绑定标签文字 -->
<TextBlock Margin="0,0,5,0" Text="{Binding Point.SeriesView.Title}" />
<!-- 绑定序列的值 -->
<TextBlock Text="{Binding Point.SeriesView.Values[0]}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</lvc:PieChart.Resources>
<!-- 数据序列 -->
<lvc:PieChart.Series>
<lvc:PieSeries
Title="颜色"
DataLabels="True"
LabelPosition="OutsideSlice"
StrokeThickness="0"
Values="24" />
<lvc:PieSeries
Title="光照"
DataLabels="True"
LabelPosition="OutsideSlice"
StrokeThickness="0"
Values="30" />
<lvc:PieSeries
Title="温度"
DataLabels="True"
LabelPosition="OutsideSlice"
StrokeThickness="0"
Values="10" />
<lvc:PieSeries
Title="振动"
DataLabels="True"
LabelPosition="OutsideSlice"
StrokeThickness="0"
Values="40" />
<lvc:PieSeries
Title="压差"
DataLabels="True"
LabelPosition="OutsideSlice"
StrokeThickness="0"
Values="27" />
<lvc:PieSeries
Title="力差"
DataLabels="True"
LabelPosition="OutsideSlice"
StrokeThickness="0"
Values="45" />
<lvc:PieSeries
Title="溶度"
DataLabels="True"
LabelPosition="OutsideSlice"
StrokeThickness="0"
Values="20" />
<lvc:PieSeries
Title="角度"
DataLabels="True"
LabelPosition="OutsideSlice"
StrokeThickness="0"
Values="16" />
<lvc:PieSeries
Title="压差"
DataLabels="True"
LabelPosition="OutsideSlice"
StrokeThickness="0"
Values="25" />
</lvc:PieChart.Series>
</lvc:PieChart>
</GroupBox>
</Grid>
<!-- 第3列包含3个groupbox -->
<UniformGrid
Grid.Column="2"
Margin="10,0"
Columns="1">
<!-- 设备数据列表 -->
<GroupBox Header="设备">
<ItemsControl VerticalAlignment="Center" ItemsSource="{Binding DeviceMonitor}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!-- 设置表格有4列 -->
<UniformGrid Columns="4" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel
Margin="0,5"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock
Margin="0,5"
HorizontalAlignment="Center"
FontSize="16"
Foreground="#FF2BEDF1"
Text="{Binding Value}" />
<TextBlock
FontSize="10"
Foreground="#AAFFFFFF"
Text="{Binding Header}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</GroupBox>
<!-- 能耗数据,使用用户控件来呈现 -->
<GroupBox Header="能耗">
<zxc:RaderChart ItemsSources="{Binding RaderDatas}" />
</GroupBox>
<GroupBox Header="人力">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="1.8*" />
</Grid.ColumnDefinitions>
<!-- 第1列内容,垂直放2个文本 -->
<StackPanel
Grid.Column="0"
Margin="0,20,0,0"
VerticalAlignment="Center">
<TextBlock
HorizontalAlignment="Center"
FontSize="25"
Foreground="#99FFFFFF"
Text="1600" />
<TextBlock
Margin="0,5"
HorizontalAlignment="Center"
FontSize="12"
Foreground="#55FFFFFF"
Text="在职在岗" />
</StackPanel>
<!-- 第2列内容,放文字和ItemControl -->
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock
VerticalAlignment="Center"
Foreground="#18AABD"
Text="缺岗统计" />
<!-- 数据列表 -->
<ItemsControl Grid.Row="1" ItemsSource="{Binding PersonnelList}">
<ItemsControl.ItemTemplate>
<!-- 数据模板,定义4列,分别绑定集合中对象的各个属性 -->
<DataTemplate>
<Grid Height="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="40" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border
Width="5"
Height="5"
Background="Orange"
CornerRadius="5" />
<TextBlock
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="11"
Foreground="#99FFFFFF"
Text="{Binding Name}" />
<TextBlock
Grid.Column="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="11"
Foreground="#99FFFFFF"
Text="{Binding Duties}" />
<StackPanel Grid.Column="3" Orientation="Horizontal">
<Border
Width="70"
Height="3"
Margin="5,0"
Background="#AA2BEDF1" />
<TextBlock
VerticalAlignment="Center"
FontSize="9"
Foreground="#99FFFFFF"
Text="{Binding ManHour}" />
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Grid>
</GroupBox>
</UniformGrid>
</Grid>
<!-- 第三行,放itemcontrol -->
<ItemsControl
Grid.Row="2"
Margin="10,0"
ItemsSource="{Binding WorkshopList}">
<!-- 面板模板 -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- 数据模板 -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- 所有数据放在一个边框内 -->
<Border
Margin="10,5"
Background="#0A18AABD"
BorderBrush="#9918AABD"
BorderThickness="0,1,0,0">
<Grid>
<!-- 分2行2列 -->
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!-- 第一行放名称和详情按钮 -->
<TextBlock
Margin="10,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="#18AABD"
Text="{Binding Name}" />
<TextBlock
Grid.Column="1"
Margin="10,0"
HorizontalAlignment="Right"
VerticalAlignment="Center">
<Hyperlink
Command="{Binding DetailCommand, RelativeSource={RelativeSource AncestorType=Window}}"
CommandParameter="{Binding}"
Foreground="#33FFFFFF"
TextDecorations="None">
[ 详情 ]
</Hyperlink>
</TextBlock>
<!-- 第二行放机台总数和UniformGrid -->
<StackPanel
Grid.Row="1"
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock
FontSize="10"
Foreground="#55FFFFFF"
Text="机台总数" />
<TextBlock
Margin="0,5"
HorizontalAlignment="Center"
FontSize="30"
Foreground="#99FFFFFF"
Text="{Binding TotalCount}" />
</StackPanel>
<UniformGrid Grid.Row="1" Grid.Column="1">
<StackPanel>
<TextBlock
HorizontalAlignment="Center"
FontSize="16"
FontWeight="Normal"
Foreground="LightSeaGreen"
Text="{Binding WorkCount}" />
<TextBlock
HorizontalAlignment="Center"
FontSize="10"
Foreground="#55FFFFFF"
Text="作业" />
</StackPanel>
<StackPanel>
<TextBlock
HorizontalAlignment="Center"
FontSize="16"
FontWeight="Normal"
Foreground="DarkOrange"
Text="{Binding WaitCount}" />
<TextBlock
HorizontalAlignment="Center"
Foreground="#55FFFFFF"
Text="等待" />
</StackPanel>
<StackPanel>
<TextBlock
HorizontalAlignment="Center"
FontSize="16"
FontWeight="Normal"
Foreground="DarkRed"
Text="{Binding FaultCount}" />
<TextBlock
HorizontalAlignment="Center"
Foreground="#55FFFFFF"
Text="故障" />
</StackPanel>
<StackPanel>
<TextBlock
HorizontalAlignment="Center"
FontSize="16"
FontWeight="Normal"
Foreground="Gray"
Text="{Binding StopCount}" />
<TextBlock
HorizontalAlignment="Center"
Foreground="#55FFFFFF"
Text="停机" />
</StackPanel>
</UniformGrid>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
5、超大礼包


6、小结
- WPF 是工业自动化生产管理平台的优选框架:核心优势是可视化能力强、MVVM 解耦、实时性高,适配工业场景的复杂 UI 和数据处理需求。
- 核心架构遵循 MVVM:设备数据采集层(Modbus/OPC UA)→ 业务逻辑层(ViewModel)→ UI 展示层(View),便于维护和扩展。
- 关键实现要点:异步采集设备数据、线程安全更新 UI、数据可视化(图表)、状态实时监控,示例代码可直接落地并扩展为完整平台。
原创不易,打字不易,截图不易,撸码不易,整理不易,走过路过,不要错过,欢迎点赞,收藏,转载,复制,抄袭,留言,灌水,请动动你的金手指,祝您早日实现财务自由。


