功能介绍:链接到指定Excel表格,实现界面上分级显示指令目录。
表格第一列对应第一级目录,第二列对应第二级目录,第三列对应具体指令内容,即第三级目录,每行指令对应发送内容由第7、8、9列组成。
效果:
一、Excel数据绑定
ViewModel/MainViewModel.cs
①初始化 ViewModel 的状态和数据
public MainViewModel()
{
CommandGroups = new ObservableCollection<CommandGroup>();
// 获取当前应用程序的启动路径
string projectDirectory = AppDomain.CurrentDomain.BaseDirectory;
// 组合相对路径,确保文件名与工程目录正确结合
string filePath = Path.Combine(projectDirectory, "COM.xlsx");
LoadCommandsFromExcel(filePath);
ClearCheckBoxesCommand = new DelegateCommand(ClearCheckBoxes);
}
②excel数据绑定
private void LoadCommandsFromExcel(string filePath)
{
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
using (var reader = ExcelReaderFactory.CreateReader(stream))
{
var dataSet = reader.AsDataSet();
var dataTable = dataSet.Tables[0];
CommandGroup currentGroup = null;
CommandItem currentCommandItem = null; // 用于存储当前的 CommandItem
for (int i = 1; i < dataTable.Rows.Count; i++) // Assuming first row is header
{
var row = dataTable.Rows[i];
var category = row[0]?.ToString();
var command = row[1]?.ToString();
var subCommand = row[2]?.ToString();
var isFixed = string.IsNullOrEmpty(row[3]?.ToString());
var parameter = $"{row[6]?.ToString()}{row[7]?.ToString()}{row[8]?.ToString()}";
bool isEditable = !isFixed;
// 处理分类(第一列)
if (!string.IsNullOrEmpty(category))
{
// 添加前一个组到列表
if (currentGroup != null)
{
CommandGroups.Add(currentGroup);
}
// 创建新的 CommandGroup
currentGroup = new CommandGroup(category);
currentCommandItem = null; // 重置当前命令项
}
// 处理命令(第二列)
if (!string.IsNullOrEmpty(command))
{
// 创建新命令项并添加到当前组
currentCommandItem = new CommandItem(command);
if (currentGroup != null)
{
currentGroup.Commands.Add(currentCommandItem);
}
}
// 处理子命令(第三列)
if (!string.IsNullOrEmpty(subCommand) && currentCommandItem != null)
{
// 添加子命令到当前命令项
var subCommandItem = new SubCommandItem(subCommand, parameter, isFixed, isEditable);
currentCommandItem.SubCommands.Add(subCommandItem);
}
}
// 添加最后的组
if (currentGroup != null)
{
CommandGroups.Add(currentGroup);
}
}
}
}
二、三级目录子属性声明
每个 CommandGroup
可以包含多个 CommandItem
,而每个 CommandItem
又可以包含多个 SubCommandItem
。三类分别在Models文件夹下声明。
CommandGroup.cs
using MyProject.Models;
using System.Collections.ObjectModel;
namespace MyProject.Models
{
public class CommandGroup
{
public string Name { get; set; }
public ObservableCollection<CommandItem> Commands { get; set; }
public CommandGroup(string name)
{
Name = name;
Commands = new ObservableCollection<CommandItem>();
}
}
}
CommandItem.cs
using System.Collections.ObjectModel;
namespace MyProject.Models
{
public class CommandItem
{
public string Name { get; set; }
public ObservableCollection<SubCommandItem> SubCommands { get; set; }
// public object IsChecked { get; }
public CommandItem(string name)
{
Name = name;
SubCommands = new ObservableCollection<SubCommandItem>();
}
}
}
SubCommandItem.cs
using Prism.Mvvm;
namespace SerialPortExample.Models
{
public class SubCommandItem : BindableBase
{
private bool _isChecked;
private string _parameter;
private bool _isFixed;
private bool _isEditable;
public string Name { get; set; }
public string Parameter
{
get => _parameter;
set => SetProperty(ref _parameter, value);
}
public bool IsFixed
{
get => _isFixed;
set => SetProperty(ref _isFixed, value);
}
public bool IsEditable
{
get => _isEditable;
set => SetProperty(ref _isEditable, value);
}
public bool IsChecked
{
get => _isChecked;
set => SetProperty(ref _isChecked, value);
}
public SubCommandItem(string name, string parameter, bool isFixed, bool isEditable)
{
Name = name;
Parameter = parameter;
IsFixed = isFixed;
IsEditable = isEditable;
}
}
}
三、xaml界面
<!--指令列表-->
<TreeView ItemsSource="{Binding CommandGroups}" Grid.Row="0" Grid.ColumnSpan="4" Background="Transparent">
<TreeView.ItemTemplate>
<!-- Template for the first level (CommandGroup) -->
<HierarchicalDataTemplate ItemsSource="{Binding Commands}" DataType="models:CommandGroup">
<TextBlock Text="{Binding Name}" FontSize="20" Style="{StaticResource TextBlockDefault}" />
<HierarchicalDataTemplate.ItemTemplate>
<!-- Template for the second level (CommandItem) -->
<HierarchicalDataTemplate DataType="models:CommandItem">
<HierarchicalDataTemplate.ItemsSource>
<Binding Path="SubCommands" />
</HierarchicalDataTemplate.ItemsSource>
<TextBlock Text="{Binding Name}" FontSize="20" Style="{StaticResource TextBlockDefault}" />
<!-- Only for the third level -->
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox FontSize="30" Background="LightSkyBlue" IsChecked="{Binding IsChecked}"
d:DataContext="{d:DesignData SubCommandItem}" />
<TextBlock Text="{Binding Name}" FontSize="20" Style="{StaticResource TextBlockDefault}" Margin="0,0,5,0"/>
</StackPanel>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>