前言
工业上位机这个领域,WPF 一直是主力。设备要连、数据要采、曲线要画、报警要管、历史还要能查,事情一件不少。但很多项目卡在第一步:界面怎么写才不别扭,代码怎么放才不越写越乱。这篇聊的是一个设备监控系统的实现思路。
项目介绍
一个基于 WPF 和 MVVM 的工业设备监控系统,支持实时数据采集、曲线显示、报警管理、SQLite 存储与历史查询。主窗口采用菜单栏 + 内容区 + 状态栏的经典三段式布局,左侧设备树负责分类导航,右侧用卡片看板展示设备状态。项目定位是工业现场的监控上位机,兼顾实时性和可维护性。
项目功能
项目特点
界面结构清晰:菜单栏、内容区、状态栏三层划分,功能入口和状态信息各归其位。 设备分类直观:左侧树按协议类型分组,S7、Modbus、模拟设备一眼区分,方便现场快速定位。 卡片式看板:右侧用 WrapPanel 排列设备卡片,状态点用颜色区分,鼠标点击即可进入详情。 状态实时可见:状态栏绑定当前时间、设备总数、在线数和报警数,不用切页面就能掌握全局。 MVVM 分离:界面通过 Binding 取数据,设备集合、状态色、统计值都由 ViewModel 提供,XAML 里不写业务逻辑。 存储轻量:SQLite 免安装、单文件,适合部署在现场工控机上。
项目技术
项目代码
展示了整个界面的骨架:菜单栏、设备树、卡片看板和状态栏。
<Window x:Class="EquipmentMonitor.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:EquipmentMonitor.ViewModels"
Title="设备监控系统" Height="700" Width="1100"
WindowStartupLocation="CenterScreen">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- ===== 菜单栏 ===== -->
<Menu Grid.Row="0" Background="#2c3e50">
<MenuItem Header="系统管理" Foreground="White">
<MenuItem Header="用户管理" Foreground="#333333" Click="UserManagement_Click"/>
<MenuItem Header="系统设置" Foreground="#333333" Click="SystemSetting_Click"/>
<Separator/>
<MenuItem Header="退出" Foreground="#333333" Click="Exit_Click"/>
</MenuItem>
<MenuItem Header="设备管理" Foreground="White">
<MenuItem Header="添加设备" Foreground="#333333" Click="AddDevice_Click"/>
<MenuItem Header="设备列表" Foreground="#333333"/>
</MenuItem>
<MenuItem Header="报警" Foreground="White">
<MenuItem Header="实时报警" Foreground="#333333" Click="Alarm_Click"/>
<MenuItem Header="历史报警" Foreground="#333333" Click="Alarm_Click"/>
</MenuItem>
<MenuItem Header="帮助" Foreground="White">
<MenuItem Header="关于" Foreground="#333333" Click="About_Click"/>
</MenuItem>
</Menu>
<!-- ===== 内容区 ===== -->
<Grid Grid.Row="1" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="220"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 左侧:设备树 -->
<TreeView x:Name="tvDevices" Background="#ecf0f1">
<TreeViewItem Header="S7 设备" IsExpanded="True"/>
<TreeViewItem Header="Modbus 设备" IsExpanded="True"/>
<TreeViewItem Header="模拟设备" IsExpanded="True"/>
</TreeView>
<!-- 右侧:设备卡片看板 -->
<ScrollViewer Grid.Column="1">
<ItemsControl ItemsSource="{Binding Devices}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Width="240" MinHeight="160" Margin="8"
Background="White" CornerRadius="8"
BorderBrush="#ddd" BorderThickness="1"
Cursor="Hand"
MouseLeftButtonDown="DeviceCard_Click">
<Border.Effect>
<DropShadowEffect ShadowDepth="2" Opacity="0.15"/>
</Border.Effect>
<StackPanel Margin="12">
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<Ellipse Width="12" Height="12"
Fill="{Binding StatusColor}" Margin="0,0,8,0"
VerticalAlignment="Center"/>
<TextBlock Text="{Binding Name}" FontWeight="Bold"
FontSize="14"/>
</StackPanel>
<TextBlock Text="{Binding DeviceType}" Foreground="#7f8c8d"
FontSize="12" Margin="0,0,0,8"/>
<Rectangle Height="1" Fill="#ecf0f1" Margin="0,0,0,8"/>
<TextBlock Text="数据采集中..." Foreground="#95a5a6"
FontSize="12"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
<!-- ===== 状态栏 ===== -->
<StatusBar Grid.Row="2" Background="#2c3e50" Foreground="White">
<StatusBarItem Content="{Binding CurrentTime}"/>
<Separator/>
<StatusBarItem>
<TextBlock>
<Run Text="总设备: "/>
<Run Text="{Binding TotalDevices}"/>
</TextBlock>
</StatusBarItem>
<Separator/>
<StatusBarItem>
<TextBlock>
<Run Text="在线: "/>
<Run Text="{Binding OnlineDevices}"/>
</TextBlock>
</StatusBarItem>
<Separator/>
<StatusBarItem>
<TextBlock>
<Run Text="报警: "/>
<Run Text="{Binding AlarmCount}" Foreground="Red"/>
</TextBlock>
</StatusBarItem>
</StatusBar>
</Grid>
</Window>项目效果
界面跑起来大致是这样一个布局:顶部深色菜单栏,四个主菜单项,下拉里是具体功能入口;中间左侧是浅灰底的设备树,三种设备类型默认展开;
右侧是卡片看板,每张卡片 240 宽、圆角 8、带浅阴影,卡片内第一行是状态圆点加设备名,第二行是设备类型,下面一条分隔线,最下面是采集状态文字;
底部状态栏同样是深色,从左到右依次是当前时间、总设备数、在线数、报警数,报警数字用红色标出。
这套设备监控系统的主界面结构不复杂,但该有的都有了:菜单栏管功能入口,设备树管分类导航,卡片看板管状态展示,状态栏管全局统计。技术上用 WPF 加 MVVM,界面靠 Binding 取数据,逻辑不往 XAML 里塞,后续加实时采集、曲线、报警和历史查询时,扩展点比较清楚。SQLite 做存储对现场部署友好,免安装、单文件,维护成本低。整体思路是先搭好界面骨架,再往上挂数据链路,一步一步来,不容易乱总结