1.从阿里图标库引入,icon到项目
下载 图标库下载iconfont.ttf 到项目
使用: Content="" 是用icon
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Background="Transparent" shell:WindowChrome.IsHitTestVisibleInChrome="True">
<Button Content="" Style="{StaticResource OperateBtnStyle}" Click="BtnMin"></Button>
<Button Content="" Style="{StaticResource OperateBtnStyle}"></Button>
<Button Content="" Style="{StaticResource OperateBtnStyle}" Background="DarkRed"
Click="BtnClose"></Button>
</StackPanel>
效果:
按钮资源
<!-- 资源字典:定义可重用的样式和资源 -->
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- 定义按钮样式,通过 x:Key 指定键名,供其他控件显式调用 -->
<Style TargetType="Button" x:Key="OperateBtnStyle">
<!-- 设置按钮的固定宽度为 40 像素 -->
<Setter Property="Width" Value="40"></Setter>
<!-- 设置背景色为半透明白色(透明度约 93%)
格式:#AARRGGBB,AA 为透明度(11 表示 0x11≈6.7% 不透明度) -->
<Setter Property="Background" Value="#11ffffff"></Setter>
<!-- 设置前景色(字体/图标颜色)为纯白色 -->
<Setter Property="Foreground" Value="White"></Setter>
<!-- 设置字体来源:使用项目中的图标字体文件
路径格式:../Resource/Fonts/#字体名称
#iconfont 表示使用该字体文件中的 "iconfont" 字体家族 -->
<Setter Property="FontFamily" Value="../Resource/Fonts/#iconfont"></Setter>
<!-- 定义控件的可视化结构(模板) -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<!-- 使用 Grid 作为根容器,背景绑定到按钮的 Background 属性 -->
<Grid Background="{TemplateBinding Background}">
<!-- 添加边框元素,用于鼠标悬停时的背景变化 -->
<Border x:Name="border">
<!-- 内容呈现器:显示按钮的实际内容(如图标或文字)
水平和垂直居中显示 -->
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"></ContentPresenter>
</Border>
</Grid>
<!-- 定义模板触发器,根据状态改变控件外观 -->
<ControlTemplate.Triggers>
<!-- 触发器:当鼠标悬停在按钮上时(IsMouseOver = True) -->
<Trigger Property="IsMouseOver" Value="True">
<!-- 修改边框的背景色为更亮一点的半透明白色(透明度约 20%) -->
<Setter TargetName="border"
Property="Background"
Value="#33ffffff"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
2.定时器来定期更新时间并触发属性变更事件。
实现方式
- 添加定时器 :在 MainWindowVM 和 MonitorUCVM 中都添加了 System.Timers.Timer 定时器,设置为每秒钟触发一次。
- 时间更新逻辑 :当定时器触发时,调用 OnPropertyChanged("TimeStr") 方法,通知 UI 界面时间属性已更新。
- 资源清理 :添加了析构函数,在 ViewModel 被垃圾回收时停止并释放定时器资源,避免内存泄漏。
// 添加定时器
private Timer _timer;
public MainWindowVM() {
// 初始化定时器,每秒更新一次时间
_timer = new Timer(1000);
_timer.Elapsed += Timer_Elapsed;
_timer.AutoReset = true;
_timer.Start();
// 其他初始化代码...
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
// 触发时间属性变更通知
OnPropertyChanged("TimeStr");
}
~MainWindowVM()
{
// 清理定时器
if (_timer != null)
{
_timer.Stop();
_timer.Dispose();
}
}
3.使用 字体 FontFamily="../Resource/Fonts/#Digital Display"
<TextBlock Text="{Binding TimeStr}" Foreground="White" FontSize="30" VerticalAlignment="Center" FontFamily="../Resource/Fonts/#Digital Display"/>
4.循环用 ItemsControl(重点)
/// <summary>
/// 机台总数 - 私有字段,存储实际的机台数量值
/// 初始值设为 "02981" 可能是为了显示效果(保留前导零)
/// </summary>
private string _MachineCount = "02981";
/// <summary>
/// 机台总数 - 公共属性,供数据绑定使用
/// 实现了属性变更通知(INotifyPropertyChanged),当值改变时通知UI更新
/// </summary>
public string MachineCount
{
get
{
// 获取当前的机台总数
return _MachineCount;
}
set
{
// 设置新的机台总数
_MachineCount = value;
// 触发属性变更通知事件
// 检查是否有订阅事件的处理程序(避免空引用异常)
if (PropertyChanged != null)
{
// 触发PropertyChanged事件,通知UI"MachineCount"属性的值已改变
// 这样绑定到该属性的UI元素会自动更新显示
PropertyChanged(this, new PropertyChangedEventArgs("MachineCount"));
}
}
}
<!-- 定义水平排列的堆栈面板,位于网格的第1列 -->
<StackPanel Grid.Column="1"
Orientation="Horizontal" <!-- 水平方向排列子元素 -->
VerticalAlignment="Center" <!-- 垂直居中 -->
HorizontalAlignment="Left"> <!-- 水平左对齐 -->
<!-- 定义当前StackPanel内部的资源,供子元素使用 -->
<StackPanel.Resources>
<!-- 定义数据模板,用于显示单个数字字符,指定Key为machineCount -->
<DataTemplate x:Key="machineCount">
<!-- 每个数字字符的边框容器:宽度15像素,浅蓝色半透明背景,左右外边距2 -->
<Border Width="15" Background="#3318aabd" Margin="2,0">
<!-- 文本块:绑定到单个字符,居中显示,白色字体,字号16 -->
<TextBlock Text="{Binding}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="White"
FontSize="16"/>
</Border>
</DataTemplate>
</StackPanel.Resources>
<!-- 显示"机台总数"标签, 表示换行符,所以显示为"机台"在上,"总数"在下 -->
<TextBlock Text="机台 总数"
Foreground="#99ffffff" <!-- 半透明白色 -->
Margin="10,0" <!-- 左右外边距10 -->
VerticalAlignment="Center"
FontSize="10"/> <!-- 小字号 -->
<!-- 知识点:页面循环用 ItemsControl - 用于显示序列数据 -->
<!-- 机台总数显示区域:绑定到MachineCount属性,使用上面定义的machineCount模板 -->
<ItemsControl ItemsSource="{Binding MachineCount}"
ItemTemplate="{StaticResource machineCount}">
<!-- 指定ItemsControl内部的面板模板 -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!-- 使用水平StackPanel来横向排列各个数字项 -->
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<!-- 生产计数标签 -->
<TextBlock Text="生产计数"
Foreground="#99ffffff"
VerticalAlignment="Center"
FontSize="10"
Margin="20,0"></TextBlock>
<!-- 生产计数显示区域:绑定到ProductCount属性,同样使用数字模板 -->
<ItemsControl ItemsSource="{Binding ProductCount}"
ItemTemplate="{StaticResource machineCount}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<!-- 不良计数标签 -->
<TextBlock Text="不良计数"
Foreground="#99ffffff"
Margin="20,0"
VerticalAlignment="Center"
FontSize="10"></TextBlock>
<!-- 不良计数显示区域:绑定到BadCount属性,同样使用数字模板 -->
<ItemsControl ItemsSource="{Binding BadCount}"
ItemTemplate="{StaticResource machineCount}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
5.按钮属性 效果:显示为"图标 + 配置"的按钮,图标来自字体编码
<!-- 配置按钮 - 使用触发器实现悬停效果和渐变色背景 -->
<Button Style="{StaticResource BtnStyle}" <!-- 引用静态资源中定义的按钮样式(包含触发器效果) -->
HorizontalAlignment="Right" <!-- 水平右对齐(在父容器中) -->
Grid.Column="1" <!-- 位于网格的第1列 -->
Height="35" <!-- 按钮高度35像素 -->
Width="80" <!-- 按钮宽度80像素 -->
VerticalAlignment="Center" <!-- 垂直居中(在父容器中) -->
Margin="20,0" <!-- 左右外边距20像素,上下0 -->
Content="配置" <!-- 按钮显示的文本内容为"配置" -->
Tag="" <!-- 标签属性:存储额外数据,这里存储了一个图标字体编码(Unicode字符)
这个值可以在样式或代码中用于显示图标 -->
Command="{Binding ShowSettingaCmm, <!-- 绑定命令:当按钮点击时执行ShowSettingaCmm命令 -->
RelativeSource={RelativeSource AncestorType=Window}}"> <!-- 命令来源:向上查找最近的Window对象作为相对源 -->
</Button>
<!-- 资源字典:定义可重用的样式和资源 -->
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- 定义按钮样式,通过 x:Key="BtnStyle" 供其他控件显式调用 -->
<Style TargetType="Button" x:Key="BtnStyle">
<!-- 设置按钮前景色(文字颜色)为浅灰色 (#AAAAAA) -->
<Setter Property="Foreground" Value="#aaa"></Setter>
<!-- 定义按钮的可视化结构模板 -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<!-- 边框元素:作为按钮的主体容器 -->
<Border BorderThickness="1" <!-- 边框厚度为1像素 -->
Background="Transparent" <!-- 默认背景透明 -->
x:Name="border"> <!-- 命名以便在触发器中引用 -->
<!-- 定义边框的渐变色画笔 -->
<Border.BorderBrush>
<!-- 线性渐变画笔:从左到右的渐变效果 -->
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<!-- 渐变起点:22%透明度的白色 -->
<GradientStop Color="#22ffffff" Offset="0"></GradientStop>
<!-- 渐变中点:77%透明度的白色(更亮) -->
<GradientStop Color="#77ffffff" Offset="0.5"></GradientStop>
<!-- 渐变终点:22%透明度的白色 -->
<GradientStop Color="#22ffffff" Offset="1"></GradientStop>
</LinearGradientBrush>
</Border.BorderBrush>
<!-- 堆栈面板:水平排列按钮内容 -->
<StackPanel Orientation="Horizontal" <!-- 水平方向排列 -->
HorizontalAlignment="Center" <!-- 水平居中 -->
VerticalAlignment="Center"> <!-- 垂直居中 -->
<!-- 图标文本块:绑定到按钮的Tag属性,用于显示图标字体 -->
<TextBlock Text="{TemplateBinding Tag}" <!-- 绑定Tag属性值 -->
FontFamily="../Resource/Fonts/#iconfont" <!-- 使用图标字体文件 -->
Margin="0,2,5,0"></TextBlock> <!-- 上边距2,右边距5 -->
<!-- 内容文本块:绑定到按钮的Content属性,显示普通文本 -->
<TextBlock Text="{TemplateBinding Content}" <!-- 绑定Content属性值 -->
VerticalAlignment="Center"></TextBlock> <!-- 垂直居中 -->
</StackPanel>
</Border>
<!-- 定义模板触发器,根据按钮状态改变外观 -->
<ControlTemplate.Triggers>
<!-- 触发器:鼠标悬停在按钮上时 -->
<Trigger Property="IsMouseOver" Value="True">
<!-- 设置边框的背景为半透明白色(约6.7%不透明度) -->
<Setter TargetName="border"
Property="Background"
Value="#11ffffff"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
样式特性说明:
1. 视觉效果
- 边框渐变:左右两侧较淡(#22ffffff),中间较亮(#77ffffff),形成光泽感
- 背景透明:默认背景透明,仅显示边框
- 悬停效果:鼠标悬停时出现半透明背景(#11ffffff),提供交互反馈
2. 内容结构
-
图标 + 文本组合:通过两个TextBlock实现
- 左侧:图标字体(绑定到
Tag属性) - 右侧:文字标签(绑定到
Content属性)
- 左侧:图标字体(绑定到
-
水平居中排列:图标和文字整体在按钮内居中
3. 使用方式示例
<Button Style="{StaticResource BtnStyle}"
Content="配置"
Tag=""
Command="{Binding ConfigCommand}"/>
6.用线条绘制边框(重点)
<!-- 定义 GroupBox 的全局样式,将应用于当前 UserControl 中所有的 GroupBox 控件 -->
<Style TargetType="GroupBox">
<!-- 设置 GroupBox 的外边距:左右10像素,上下3像素 -->
<Setter Property="Margin" Value="10,3"></Setter>
<!-- 重写 GroupBox 的控件模板,实现自定义外观 -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupBox">
<!-- 使用 Grid 作为根容器,便于多个图形元素的叠加 -->
<Grid>
<!-- ========== 知识点:形状(Shape) ========== -->
<!-- 左上角的L形拐角线条 -->
<Polyline Points="0 30,0 10,10 0,30 0"
Stroke="#9918aabd" <!-- 半透明蓝色 (#18aabd, 透明度60%) -->
StrokeThickness="1"
VerticalAlignment="Top"
HorizontalAlignment="Left"></Polyline>
<!-- 左上角横线上的装饰点 - 小圆 -->
<Ellipse Width="4" Height="4"
HorizontalAlignment="Left"
Fill="#9918aabd" <!-- 与线条相同的颜色 -->
VerticalAlignment="Top"
Margin="24,-2,0,0"></Ellipse> <!-- 向右偏移24,向上偏移2 -->
<!-- 左侧竖线上的装饰点 - 小圆 -->
<Ellipse Width="4" Height="4"
HorizontalAlignment="Left"
Fill="#9918aabd"
VerticalAlignment="Top"
Margin="-2,24,0,0"></Ellipse> <!-- 向左偏移2,向下偏移24 -->
<!-- 顶部右上角的路径装饰(Moveto表示路径起点)
M0 0: 起点(0,0)
3 3: 画到(3,3)
30 3: 画到(30,3)
33 0: 画到(33,0)
68 0: 画到(68,0)
73 7: 画到(73,7)
78 7: 画到(78,7)
78,10: 画到(78,10)
M8 0,25 0: 另一条路径从(8,0)到(25,0) -->
<Path Data="M0 0,3 3,30 3,33 0,68 0,73 7,78 7,78,10M8 0,25 0"
Stroke="#9918aabd"
VerticalAlignment="Top"
HorizontalAlignment="Right"></Path>
<!-- 左下角的水平短线条 -->
<Polyline Points="0 0,0 15,10 15"
Stroke="#9918aabd"
StrokeThickness="1"
VerticalAlignment="Bottom" <!-- 底部对齐 -->
HorizontalAlignment="Left"></Polyline> <!-- 左对齐 -->
<!-- 右下角的折线(小拐角) -->
<Polyline Points="10 0,0,10"
Stroke="#9918aabd"
StrokeThickness="1"
HorizontalAlignment="Right" <!-- 右对齐 -->
VerticalAlignment="Bottom"></Polyline> <!-- 底部对齐 -->
<!-- 右下角的实心三角形装饰 -->
<Polygon Points="0 7,7 7,7 0"
Fill="#9918aabd"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"></Polygon>
<!-- 顶部的横线边框(从左上装饰延伸到右上装饰) -->
<Border BorderThickness="0,1,0,0" <!-- 仅显示顶部边框 -->
BorderBrush="#9918aabd"
VerticalAlignment="Top"
Margin="30,-0.5,78,0"></Border> <!-- 左边距30,右边距78,向上微调0.5 -->
<!-- 右侧的竖线边框 -->
<Border BorderThickness="0,0,1,0" <!-- 仅显示右侧边框 -->
BorderBrush="#9918aabd"
HorizontalAlignment="Right"
Margin="0,10"></Border> <!-- 上下边距10 -->
<!-- 底部的横线边框 -->
<Border BorderThickness="0,0,0,1" <!-- 仅显示底部边框 -->
BorderBrush="#9918aabd"
VerticalAlignment="Bottom"
Margin="10,0"></Border> <!-- 左右边距10 -->
<!-- 左侧的竖线边框 -->
<Border BorderThickness="1,0,0,0" <!-- 仅显示左侧边框 -->
BorderBrush="#9918aabd"
HorizontalAlignment="Left"
Margin="-0.5,15"></Border> <!-- 向左微调0.5,上下边距15 -->
<!-- 标题前的第一个装饰图标(六边形/菱形) -->
<Path Data="M0 0,3 0,5 4,3 8,0 8,3 4" <!-- 绘制六边形路径 -->
Fill="#9918aabd" <!-- 半透明蓝色 -->
Margin="10,13"></Path> <!-- 位置偏移 -->
<!-- 标题前的第二个装饰图标(相同形状,较浅的透明度,产生叠影效果) -->
<Path Data="M0 0,3 0,5 4,3 8,0 8,3 4"
Fill="#5518aabd" <!-- 透明度约33%,更淡 -->
Margin="16,13"></Path> <!-- 向右偏移更多,与第一个错开 -->
<!-- 标题文本:绑定到 GroupBox 的 Header 属性 -->
<TextBlock Text="{TemplateBinding Header}"
Foreground="White"
FontWeight="Bold"
Margin="25,8" <!-- 左边距25,上边距8 -->
HorizontalAlignment="Left"
VerticalAlignment="Top"></TextBlock>
<!-- 内容呈现器:显示 GroupBox 内部的实际内容 -->
<ContentPresenter></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<!-- 环境信息分组框 -->
<GroupBox Header="环境"> <!-- 分组框标题为"环境",使用上面定义的科技感GroupBox样式 -->
<!-- ItemsControl:用于循环显示环境参数列表 -->
<ItemsControl ItemsSource="{Binding EnviromentList}" <!-- 绑定到ViewModel中的环境数据集合 -->
VerticalContentAlignment="Center" <!-- 内容垂直居中 -->
Margin="0,10"> <!-- 上下外边距10像素 -->
<!-- 定义ItemsControl内部的面板布局 -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!-- UniformGrid:均匀网格布局,所有单元格大小一致 -->
<UniformGrid Columns="4"></UniformGrid> <!-- 固定为4列,行数自动适应 -->
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- 定义每个数据项的显示模板 -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- 垂直堆栈面板:每个环境参数的容器 -->
<StackPanel HorizontalAlignment="Center" <!-- 水平居中 -->
VerticalAlignment="Center" <!-- 垂直居中 -->
Margin="0,5"> <!-- 上下边距5像素 -->
<!-- 环境参数值:大号字体显示 -->
<TextBlock Text="{Binding EnItemValue}" <!-- 绑定到数据项的数值属性 -->
FontSize="16" <!-- 字号16,突出显示 -->
Foreground="#ff2bedf1" <!-- 亮青色 (#2bedf1) -->
Margin="0,5"/> <!-- 上下边距5像素 -->
<!-- 环境参数名称:小号字体显示 -->
<TextBlock Text="{Binding EnItemName}" <!-- 绑定到数据项的名称属性 -->
FontSize="10" <!-- 字号10,辅助信息 -->
Foreground="#aaffffff" <!-- 半透明白色 (约67%不透明度) -->
Margin="0,5"/> <!-- 上下边距5像素 -->
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</GroupBox>
1. 数据结构
假设 EnviromentList 集合中包含多个环境参数对象,每个对象有:
namespace ProductMonitor.Models
{
// 环境信息
public class EnviromentModel
{
// 环境名称
public string EnItemName { get; set; }
// 环境项的值
public int EnItemValue { get; set; }
}
}
// 私有字段:存储环境监控数据列表
private List<EnviromentModel> _EnviromentList;
/// <summary>
/// 环境监控数据集合
/// 绑定到UI上的ItemsControl,用于显示温度、湿度、气压等环境参数
/// </summary>
public List<EnviromentModel> EnviromentList
{
get
{
// 返回当前的环境数据列表
return _EnviromentList;
}
set
{
// 设置新的环境数据列表
_EnviromentList = value;
// 触发属性变更通知事件
// 检查是否有订阅事件的处理程序(避免空引用异常)
if (PropertyChanged != null)
{
// 触发PropertyChanged事件,通知UI"EnviromentList"属性的值已改变
// 这样绑定到该属性的UI元素(如ItemsControl)会自动刷新显示
PropertyChanged(this, new PropertyChangedEventArgs("EnviromentList"));
}
}
}
#region 初始化环境监控数据
EnviromentList = new List<EnviromentModel>();
EnviromentList.Add(new EnviromentModel { EnItemName = "光照(Lux)", EnItemValue = 123 });
EnviromentList.Add(new EnviromentModel { EnItemName = "噪音(db)", EnItemValue = 55 });
EnviromentList.Add(new EnviromentModel { EnItemName = "温度(℃)", EnItemValue = 80 });
EnviromentList.Add(new EnviromentModel { EnItemName = "湿度(%)", EnItemValue = 43 });
EnviromentList.Add(new EnviromentModel { EnItemName = "PM2.5(m³)", EnItemValue = 20 });
EnviromentList.Add(new EnviromentModel { EnItemName = "硫化氢(PPM)", EnItemValue = 15 });
EnviromentList.Add(new EnviromentModel { EnItemName = "氮气(PPM)", EnItemValue = 18 });
#endregion
7.引用/使用数据可视化 LiveCharts LiveCharts.Wpf
<!-- 产能分组框:显示生产数据的柱状图 -->
<GroupBox Header="产能">
<!-- 使用Grid容器,方便图表和图例的叠加布局 -->
<Grid>
<!-- ========== LiveCharts 柱状图 ========== -->
<!-- 引入lvc命名空间(xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf")的图表控件 -->
<lvc:CartesianChart Margin="20,35,20,5"> <!-- 上边距35为图例留出空间,左右边距20 -->
<!-- ===== 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"> <!-- 9个时间点标签 -->
<lvc:Axis.Separator>
<!-- 分隔线设置:Step="1"表示每个标签之间显示分隔线,StrokeThickness="0"隐藏线条 -->
<lvc:Separator Step="1" StrokeThickness="0"/>
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisX>
<!-- ===== 数据系列定义(Y轴数据) ===== -->
<lvc:CartesianChart.Series>
<!-- 生产计数柱状图系列(蓝色系) -->
<lvc:ColumnSeries Values="300,400,480,450,380,450,450,330,340" <!-- 9个时间点的生产数量 -->
Title="生产计数" <!-- 系列名称,用于图例绑定 -->
MaxColumnWidth="10"> <!-- 柱状图最大宽度10像素,防止柱子过宽 -->
<!-- 生产计数的渐变色填充:从上到下渐变 -->
<lvc:ColumnSeries.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <!-- 垂直渐变(从上到下) -->
<GradientStop Color="#ff3fbbe6" Offset="0"></GradientStop> <!-- 起点:亮蓝色(完全不透明) -->
<GradientStop Color="#ff2bedf1" Offset="1"></GradientStop> <!-- 终点:青色(完全不透明) -->
</LinearGradientBrush>
</lvc:ColumnSeries.Fill>
</lvc:ColumnSeries>
<!-- 不良计数柱状图系列(红色系) -->
<lvc:ColumnSeries Values="15,55,15,40,38,45,56,42,24" <!-- 9个时间点的不良品数量 -->
Title="不良计数" <!-- 系列名称 -->
MaxColumnWidth="10"> <!-- 相同宽度,保持视觉一致 -->
<!-- 不良计数的渐变色填充 -->
<lvc:ColumnSeries.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <!-- 垂直渐变 -->
<GradientStop Color="#fffb9a9a" Offset="0"></GradientStop> <!-- 起点:浅红色 -->
<GradientStop Color="#ffff5151" Offset="1"></GradientStop> <!-- 终点:亮红色 -->
</LinearGradientBrush>
</lvc:ColumnSeries.Fill>
</lvc:ColumnSeries>
</lvc:CartesianChart.Series>
<!-- ===== Y轴定义(数值轴) ===== -->
<lvc:CartesianChart.AxisY>
<lvc:Axis MinValue="0" MaxValue="500" > <!-- Y轴范围:0-500,适应生产计数最大值480 -->
<lvc:Axis.Separator>
<!-- Y轴分隔线:每隔100显示一条水平线,半透明白色 -->
<lvc:Separator Step="100" Stroke="#11ffffff"></lvc:Separator> <!-- 约6.7%不透明度 -->
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisY>
</lvc:CartesianChart>
<!-- ===== 图例(右上角) ===== -->
<StackPanel Orientation="Horizontal" <!-- 水平排列 -->
HorizontalAlignment="Right" <!-- 右对齐 -->
VerticalAlignment="Top" <!-- 顶部对齐 -->
Margin="10"> <!-- 边距10像素 -->
<!-- 生产计数图例项 -->
<Border Height="6" Width="6" <!-- 小色块:6x6像素 -->
Background="#ff2bedf1" <!-- 与生产计数渐变的终点色一致 -->
Margin="5,0"></Border> <!-- 右边距5 -->
<TextBlock Text="生产计数" <!-- 图例文字 -->
FontSize="10"
Foreground="#44ffffff"></TextBlock> <!-- 半透明白色(约27%不透明度) -->
<!-- 不良计数图例项 -->
<Border Height="6" Width="6"
Background="#ffff5151" <!-- 与不良计数渐变的终点色一致 -->
Margin="5,0"></Border>
<TextBlock Text="不良计数"
FontSize="10"
Foreground="#44ffffff"></TextBlock>
</StackPanel>
</Grid>
</GroupBox>
<!-- 质量分组框:显示各机台的不良率趋势 -->
<GroupBox Header="质量">
<!-- 使用Grid容器,便于后续可能添加其他元素(如图例、标注等) -->
<Grid>
<!-- ========== LiveCharts 折线图 ========== -->
<!-- 引入lvc命名空间的图表控件,边距设置为上35为标题留出空间 -->
<lvc:CartesianChart Margin="20,35,20,5"> <!-- 左边距20,上边距35,右边距20,下边距5 -->
<!-- ===== X轴定义(机台编号) ===== -->
<lvc:CartesianChart.AxisX>
<!-- Labels属性设置X轴标签:1#到6#,代表6个不同的机台/工位 -->
<lvc:Axis Labels="1#,2#,3#,4#,5#,6#">
<lvc:Axis.Separator>
<!-- 分隔线设置:Step="1"表示在每个标签之间显示分隔线 -->
<!-- StrokeThickness="0"隐藏分隔线,保持图表简洁 -->
<lvc:Separator Step="1" StrokeThickness="0"></lvc:Separator>
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisX>
<!-- ===== 数据系列定义(不良率数据) ===== -->
<lvc:CartesianChart.Series>
<!-- 折线图系列:显示各机台的不良品数量/不良率 -->
<lvc:LineSeries Values="8,2,7,6,4,14" <!-- 6个机台对应的不良数据 -->
PointGeometrySize="0" <!-- 数据点大小为0,即不显示数据点标记 -->
Stroke="#ff2bedf1"> <!-- 折线颜色:亮青色(完全不透明) -->
<!-- 折线图下方区域填充(渐变色) -->
<lvc:LineSeries.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <!-- 垂直渐变(从上到下) -->
<!-- 起点:半透明青色(约33%不透明度) -->
<GradientStop Color="#552bedf1" Offset="0"></GradientStop>
<!-- 终点:完全透明,形成从有到无的渐变效果 -->
<GradientStop Color="Transparent" Offset="1"></GradientStop>
</LinearGradientBrush>
</lvc:LineSeries.Fill>
</lvc:LineSeries>
</lvc:CartesianChart.Series>
<!-- ===== Y轴定义(不良数值范围) ===== -->
<lvc:CartesianChart.AxisY>
<!-- Y轴范围:最小值0,最大值15,适应数据最大值14 -->
<lvc:Axis MinValue="0" MaxValue="15" >
<lvc:Axis.Separator>
<!-- Y轴分隔线:每隔5显示一条水平网格线 -->
<lvc:Separator Step="5" Stroke="#11ffffff"></lvc:Separator> <!-- 半透明白色(约6.7%不透明度) -->
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisY>
</lvc:CartesianChart>
</Grid>
</GroupBox>
<!-- 第三行:数据异常报警比例分组框 -->
<GroupBox Grid.Row="2" <!-- 位于网格的第3行(行索引为2) -->
Header="数据异常报警比例" <!-- 分组框标题 -->
Margin="0,5"> <!-- 上下外边距5像素 -->
<!-- ========== 饼形图:显示各类异常报警的占比 ========== -->
<!-- 使用LiveCharts的PieChart控件,InnerRadius="45"创建环形图效果(类似甜甜圈图) -->
<lvc:PieChart InnerRadius="45" <!-- 内圆半径45,值越大环越粗,45表示中等粗细的环形 -->
Margin="0,40,0,20"> <!-- 上边距40为标题留空间,下边距20 -->
<!-- ===== 定义饼图系列的数据标签样式(全局应用) ===== -->
<lvc:PieChart.Resources>
<!-- 针对所有PieSeries设置统一的样式 -->
<Style TargetType="lvc:PieSeries">
<!-- 设置数据标签的模板(决定标签显示的内容和格式) -->
<Setter Property="DataLabelsTemplate">
<Setter.Value>
<DataTemplate>
<!-- 水平排列的堆栈面板:显示"类别名称 + 数值" -->
<StackPanel Orientation="Horizontal">
<!-- 绑定到当前数据点的系列标题(如"压差"、"振动"等) -->
<TextBlock Text="{Binding Point.SeriesView.Title}"
Margin="0,0,5,0" <!-- 右边距5像素 -->
Foreground="#44ffffff"></TextBlock> <!-- 半透明白色(约27%不透明度) -->
<!-- 绑定到当前数据点的数值(第一个值,饼图通常只有一个值) -->
<TextBlock Text="{Binding Point.SeriesView.Values[0]}"
Foreground="#44ffffff"></TextBlock> <!-- 同样半透明白色 -->
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</lvc:PieChart.Resources>
<!-- ===== 定义饼图数据系列(4个异常类别) ===== -->
<lvc:PieChart.Series>
<!-- 压差异常:占比20%(数值20) -->
<lvc:PieSeries Values="20" <!-- 数据值,决定扇形大小 -->
Title="压差" <!-- 系列标题,显示在标签和图例中 -->
StrokeThickness="0" <!-- 边框厚度为0,不显示扇形之间的分隔线 -->
DataLabels="True" <!-- 显示数据标签 -->
LabelPosition="OutsideSlice"></lvc:PieSeries> <!-- 标签显示在扇形外部 -->
<!-- 振动异常:占比40%(最大占比) -->
<lvc:PieSeries Values="40"
Title="振动"
StrokeThickness="0"
DataLabels="True"
LabelPosition="OutsideSlice"></lvc:PieSeries>
<!-- 设备温度异常:占比10%(最小占比) -->
<lvc:PieSeries Values="10"
Title="设备温度"
StrokeThickness="0"
DataLabels="True"
LabelPosition="OutsideSlice"></lvc:PieSeries>
<!-- 光照异常:占比30% -->
<lvc:PieSeries Values="30"
Title="光照"
StrokeThickness="0"
DataLabels="True"
LabelPosition="OutsideSlice"></lvc:PieSeries>
</lvc:PieChart.Series>
</lvc:PieChart>
</GroupBox>
视觉设计特点:
-
环形图(甜甜圈图)
InnerRadius="45":创建环形效果,中间空心- 比普通饼图更现代,可以在中心添加额外信息(如总数)
-
标签设计
- 标签位置:扇形外部(
LabelPosition="OutsideSlice"),避免遮挡 - 标签内容:显示"类别名称 + 数值"
- 标签样式:半透明文字,不喧宾夺主
- 标签位置:扇形外部(
-
简洁边框
StrokeThickness="0":取消扇形之间的分隔线,使颜色过渡更自然
8.数据循环显示
<!-- 位于网格的第2行(行索引为1)的报警记录区域 -->
<Grid Grid.Row="1">
<!-- 定义Grid的行布局:两行 -->
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition> <!-- 第一行固定高度30像素,用于显示标题 -->
<RowDefinition></RowDefinition> <!-- 第二行自适应填充剩余空间,用于显示报警列表 -->
</Grid.RowDefinitions>
<!-- ===== 第一行:标题栏 ===== -->
<StackPanel Orientation="Horizontal" <!-- 水平排列 -->
VerticalAlignment="Center" <!-- 垂直居中 -->
HorizontalAlignment="Left"> <!-- 水平左对齐 -->
<!-- 报警图标:使用图标字体显示报警符号 -->
<TextBlock Text="" <!-- 图标字体编码,对应一个报警/铃铛图标 -->
FontFamily="../Resource/Fonts/#iconfont" <!-- 引用图标字体文件 -->
Foreground="#99ffffff" <!-- 半透明白色(约60%不透明度) -->
Margin="5,0"></TextBlock> <!-- 左右边距5像素 -->
<!-- 标题文字:"报警记录" -->
<TextBlock Text="报警记录"
Foreground="#99ffffff"></TextBlock> <!-- 相同半透明白色 -->
</StackPanel>
<!-- ===== 第二行:报警列表 ===== -->
<!-- 使用ItemsControl循环显示报警记录,绑定到AlarmList集合 -->
<ItemsControl Grid.Row="1" <!-- 位于Grid的第二行 -->
ItemsSource="{Binding AlarmList}" <!-- 绑定到ViewModel中的报警数据集合 -->
Margin="5,0"> <!-- 左右边距5像素 -->
<!-- 定义每条报警记录的显示模板 -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- 每条报警记录使用Grid布局,固定高度23像素 -->
<Grid Height="23">
<!-- 定义5列表格 -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"></ColumnDefinition> <!-- 第1列:红点报警图标,宽度20 -->
<ColumnDefinition Width="30"></ColumnDefinition> <!-- 第2列:报警编号,宽度30 -->
<ColumnDefinition Width="150"></ColumnDefinition> <!-- 第3列:报警信息,宽度150 -->
<ColumnDefinition></ColumnDefinition> <!-- 第4列:报警时间,自适应宽度 -->
<ColumnDefinition></ColumnDefinition> <!-- 第5列:报警时长,自适应宽度 -->
</Grid.ColumnDefinitions>
<!-- 知识点:红点报警 - 用红色圆点表示报警状态 -->
<Border Background="IndianRed" <!-- 印第安红色背景 -->
Height="6" Width="6" <!-- 6x6像素的正方形 -->
CornerRadius="3" <!-- 圆角半径3,形成正圆形 -->
VerticalAlignment="Center"
HorizontalAlignment="Center"></Border> <!-- 居中显示 -->
<!-- 报警编号:绑定到Num属性 -->
<TextBlock Text="{Binding Num}"
Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="#992bedf1"></TextBlock> <!-- 半透明青色(约60%不透明度) -->
<!-- 报警信息内容:绑定到Msg属性 -->
<TextBlock Text="{Binding Msg}"
Grid.Column="2"
VerticalAlignment="Center"
Foreground="#992bedf1"></TextBlock>
<!-- 报警发生时间:绑定到Time属性 -->
<TextBlock Text="{Binding Time}"
Grid.Column="3"
VerticalAlignment="Center"
Foreground="#992bedf1"></TextBlock>
<!-- 报警持续时间:绑定到Duration属性,并格式化显示 -->
<TextBlock Text="{Binding Duration,StringFormat=时长{0}秒}" <!-- 格式化为"时长X秒" -->
Grid.Column="4"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="#992bedf1"></TextBlock>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
数据结构说明:
1. AlarmList 集合中的数据模型
namespace ProductMonitor.Models
{
/// <summary>
/// 报警数据模型
/// </summary>
internal class AlarmModel
{
/// <summary>
/// 编号
/// </summary>
public string Num { get; set; }
/// <summary>
/// 报警信息
/// </summary>
public string Msg { get; set; }
/// <summary>
/// 报警时间
/// </summary>
public string Time { get; set; }
/// <summary>
/// 报警时长 单位:秒
/// </summary>
public int Duration { get; set; }
}
}
#region 报警属性
/// <summary>
/// 报警集合
/// </summary>
private List<AlarmModel> _AlarmList;
/// <summary>
/// 报警集合
/// </summary>
public List<AlarmModel> AlarmList
{
get { return _AlarmList; }
set
{
_AlarmList = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("AlarmList"));
}
}
}
#endregion
#region 初始化报警列表
AlarmList = new List<AlarmModel>();
AlarmList.Add(new AlarmModel { Num = "01", Msg = "设备温度过高", Time = "2023-11-23 18:34:56", Duration = 7 });
AlarmList.Add(new AlarmModel { Num = "02", Msg = "车间温度过高", Time = "2023-12-08 20:40:59", Duration = 10 });
AlarmList.Add(new AlarmModel { Num = "03", Msg = "设备转速过快", Time = "2024-01-05 12:24:34", Duration = 12 });
AlarmList.Add(new AlarmModel { Num = "04", Msg = "设备气压偏低", Time = "2024-02-04 19:58:00", Duration = 90 });
#endregion
9.缺岗进度条:宽度绑定到ShowWidth属性,动态显示缺岗比例
<!-- 人力分组框:显示在职人数和缺岗统计 -->
<GroupBox Header="人力">
<!-- 使用Grid作为主容器,分为两列布局 -->
<Grid>
<!-- 定义两列:左侧列自适应,右侧列宽度为左侧的1.8倍 -->
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition> <!-- 第1列:自适应宽度,显示在职人数 -->
<ColumnDefinition Width="1.8*"></ColumnDefinition> <!-- 第2列:宽度为第1列的1.8倍,显示缺岗统计 -->
</Grid.ColumnDefinitions>
<!-- ===== 左侧:在职人数统计 ===== -->
<StackPanel VerticalAlignment="Center" <!-- 垂直居中 -->
Margin="0,20,0,0"> <!-- 上边距20像素 -->
<!-- 在职人数大号数字 -->
<TextBlock Text="870"
HorizontalAlignment="Center"
Foreground="#99ffffff" <!-- 半透明白色(约60%不透明度) -->
FontSize="25"></TextBlock> <!-- 大字号突出显示 -->
<!-- 状态说明文字 -->
<TextBlock Text="在职在岗"
HorizontalAlignment="Center"
Foreground="#55ffffff" <!-- 更透明的白色(约33%不透明度) -->
FontSize="12"></TextBlock> <!-- 小字号辅助信息 -->
</StackPanel>
<!-- ===== 右侧:缺岗统计列表 ===== -->
<Grid Grid.Column="1"> <!-- 位于第2列 -->
<!-- 定义两行布局 -->
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition> <!-- 第一行固定高度30,显示标题 -->
<RowDefinition></RowDefinition> <!-- 第二行自适应,显示缺岗人员列表 -->
</Grid.RowDefinitions>
<!-- 缺岗统计标题 -->
<TextBlock Text="缺岗统计"
VerticalAlignment="Center"
Foreground="#18aabd"></TextBlock> <!-- 亮蓝色,与主题色一致 -->
<!-- 缺岗人员列表:绑定到StuffOutWorkList集合 -->
<ItemsControl Grid.Row="1"
ItemsSource="{Binding StuffOutWorkList}">
<!-- 定义每条缺岗记录的显示模板 -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- 每条记录使用Grid布局,固定高度20像素 -->
<Grid Height="20" Width="auto">
<!-- 定义4列表格 -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"></ColumnDefinition> <!-- 第1列:状态圆点,宽度10 -->
<ColumnDefinition Width="50"></ColumnDefinition> <!-- 第2列:姓名,宽度50 -->
<ColumnDefinition Width="40"></ColumnDefinition> <!-- 第3列:职位,宽度40 -->
<ColumnDefinition></ColumnDefinition> <!-- 第4列:缺岗进度条,自适应 -->
</Grid.ColumnDefinitions>
<!-- 缺岗状态圆点(橙色表示缺岗) -->
<Border Width="5" Height="5"
CornerRadius="5" <!-- 圆角半径5,形成正圆 -->
Background="Orange"></Border> <!-- 橙色背景 -->
<!-- 缺岗人员姓名 -->
<TextBlock Text="{Binding StuffName}"
Grid.Column="1"
Foreground="#99ffffff"
HorizontalAlignment="Center"
VerticalAlignment="Center"></TextBlock>
<!-- 缺岗人员职位 -->
<TextBlock Text="{Binding Position}"
Grid.Column="2"
Foreground="#99ffffff"
HorizontalAlignment="Center"
VerticalAlignment="Center"></TextBlock>
<!-- 缺岗统计进度条区域 -->
<StackPanel Grid.Column="3"
Orientation="Horizontal"> <!-- 水平排列 -->
<!-- 缺岗进度条:宽度绑定到ShowWidth属性,动态显示缺岗比例 -->
<Border Background="#aa2bedf1" <!-- 半透明青色(约67%不透明度) -->
Height="3" <!-- 高度3像素的细条 -->
Width="{Binding ShowWidth}" <!-- 宽度绑定到数据模型 -->
Margin="5,0"></Border> <!-- 左右边距5像素 -->
<!-- 缺岗次数/天数 -->
<TextBlock Text="{Binding OutWorkCount}"
FontSize="9"
Foreground="#99ffffff"
VerticalAlignment="Center"></TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Grid>
</GroupBox>
数据结构说明:
1. StuffOutWorkList 集合中的数据模型
/// <summary>
/// 缺岗数据模型
/// </summary>
internal class StuffOutWorkModel
{
/// <summary>
/// 员工姓名
/// </summary>
public string StuffName { get; set; }
/// <summary>
/// 职位
/// </summary>
public string Position { get; set; }
/// <summary>
/// 缺岗次数
/// </summary>
public int OutWorkCount { get; set; }
/// <summary>
/// 界面显示宽度
/// </summary>
public int ShowWidth
{
get
{
return OutWorkCount * 70 / 100;
}
}
}
#region 缺岗员工属性
/// <summary>
/// 缺岗员工
/// </summary>
private List<StuffOutWorkModel> _StuffOutWorkList;
/// <summary>
/// 缺岗员工
/// </summary>
public List<StuffOutWorkModel> StuffOutWorkList
{
get { return _StuffOutWorkList; }
set
{
_StuffOutWorkList = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("StuffOutWorkList"));
}
}
}
#endregion
#region 初始化人员缺岗信息
StuffOutWorkList = new List<StuffOutWorkModel>();
StuffOutWorkList.Add(new StuffOutWorkModel { StuffName = "张晓婷", Position = "技术员", OutWorkCount = 123 });
StuffOutWorkList.Add(new StuffOutWorkModel { StuffName = "李晓", Position = "操作员", OutWorkCount = 23 });
StuffOutWorkList.Add(new StuffOutWorkModel { StuffName = "王克俭", Position = "技术员", OutWorkCount = 134 });
StuffOutWorkList.Add(new StuffOutWorkModel { StuffName = "陈家栋", Position = "统计员", OutWorkCount = 143 });
StuffOutWorkList.Add(new StuffOutWorkModel { StuffName = "杨过", Position = "技术员", OutWorkCount = 12 });
#endregion
<UserControl.Resources>
<!-- 定义 RadioButton 的全局样式,将应用于当前 UserControl 中所有的 RadioButton 控件 -->
<Style TargetType="RadioButton">
<!-- 基础属性设置 -->
<Setter Property="Height" Value="22"></Setter> <!-- 按钮高度22像素 -->
<Setter Property="Width" Value="50"></Setter> <!-- 按钮宽度50像素,统一大小 -->
<Setter Property="Background" Value="#ddd"></Setter> <!-- 默认背景色:浅灰色 (#DDDDDD) -->
<Setter Property="Foreground" Value="#888"></Setter> <!-- 默认前景色(文字颜色):深灰色 (#888888) -->
<Setter Property="FontSize" Value="11"></Setter> <!-- 字体大小:11像素 -->
<Setter Property="BorderBrush" Value="#33ffffff"></Setter> <!-- 边框颜色:半透明白色(约20%不透明度) -->
<!-- 自定义控件模板:完全重写 RadioButton 的可视化外观 -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<!-- 使用 Border 作为按钮容器 -->
<Border Background="{TemplateBinding Background}"> <!-- 背景绑定到 Background 属性 -->
<!-- 内容呈现器:显示 RadioButton 的 Content 内容(如"全部"、"作业"等文字) -->
<ContentPresenter HorizontalAlignment="Center" <!-- 水平居中 -->
VerticalAlignment="Center"></ContentPresenter> <!-- 垂直居中 -->
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<!-- 样式触发器:根据状态改变外观 -->
<Style.Triggers>
<!-- 触发器:当 RadioButton 被选中时(IsChecked = True) -->
<Trigger Property="IsChecked" Value="True">
<!-- 设置背景色为橙色,醒目提示选中状态 -->
<Setter Property="Background" Value="Orange"></Setter>
<!-- 设置前景色(文字颜色)为白色,提高对比度 -->
<Setter Property="Foreground" Value="White"></Setter>
</Trigger>
<!-- 注意:这里没有定义鼠标悬停等交互状态的触发器 -->
</Style.Triggers>
</Style>
</UserControl.Resources>
<!-- 机台状态筛选栏:水平排列的堆栈面板,位于界面右侧 -->
<StackPanel HorizontalAlignment="Right" <!-- 水平右对齐(在父容器中) -->
Orientation="Horizontal" <!-- 水平方向排列子元素 -->
VerticalAlignment="Center" <!-- 垂直居中 -->
Margin="20,0"> <!-- 左右外边距20像素,上下0 -->
<!-- 状态筛选标签 -->
<TextBlock Text="机台状态" <!-- 显示文字:"机台状态" -->
Foreground="White" <!-- 白色文字 -->
VerticalAlignment="Center"> <!-- 垂直居中 -->
</TextBlock>
<!-- 单选按钮组:用于筛选不同状态的机台 -->
<!-- IsChecked="True" 表示默认选中"全部"选项 -->
<RadioButton Content="全部" <!-- 显示文字:"全部" -->
IsChecked="True"> <!-- 默认选中状态 -->
</RadioButton>
<!-- 作业状态:显示正在作业的机台 -->
<RadioButton Content="作业"></RadioButton>
<!-- 等待状态:显示等待中的机台 -->
<RadioButton Content="等待"></RadioButton>
<!-- 故障状态:显示发生故障的机台 -->
<RadioButton Content="故障"></RadioButton>
<!-- 停机状态:显示已停机的机台 -->
<RadioButton Content="停机"></RadioButton>
</StackPanel>
样式效果说明:
1. 默认状态(未选中)
- 背景色:浅灰色 (#ddd)
- 文字颜色:深灰色 (#888)
- 尺寸:50×22 像素的统一大小
- 边框:半透明白色边框 (#33ffffff)
2. 选中状态
- 背景色:橙色 (Orange)
- 文字颜色:白色 (White)
- 其他属性:保持不变