using DeviceService.Core;
|
using DeviceService.Device;
|
using DeviceService.Driver;
|
using DeviceService.Logging;
|
using DeviceService.Service;
|
using System.Collections.ObjectModel;
|
using System.IO;
|
using System.Windows;
|
using System.Windows.Controls;
|
using System.Windows.Controls.Primitives;
|
using System.Windows.Threading;
|
|
namespace DeviceService;
|
|
/// <summary>
|
/// 设备树分组节点(按 IDevice.Type 分组)。
|
/// </summary>
|
public class DeviceGroupNode
|
{
|
public DeviceGroupNode(string type, IEnumerable<DeviceNode> children)
|
{
|
Type = type;
|
Children = new ObservableCollection<DeviceNode>(children);
|
}
|
|
public string Type { get; }
|
|
public ObservableCollection<DeviceNode> Children { get; }
|
}
|
|
/// <summary>
|
/// 设备树叶子节点。
|
/// </summary>
|
public class DeviceNode
|
{
|
public DeviceNode(IDevice device)
|
{
|
Device = device;
|
}
|
|
public IDevice Device { get; }
|
|
public string DisplayName => $"{Device.DeviceId}({Device.Brand})";
|
}
|
|
/// <summary>
|
/// Interaction logic for MainWindow.xaml
|
/// </summary>
|
public partial class MainWindow : Window
|
{
|
private readonly DriverManager _manager = DriverManager.Instance;
|
private readonly ObservableCollection<DeviceGroupNode> _groups = new ObservableCollection<DeviceGroupNode>();
|
|
public MainWindow()
|
{
|
InitializeComponent();
|
DeviceTree.ItemsSource = _groups;
|
Loaded += MainWindow_Loaded;
|
}
|
|
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
|
{
|
// 加载驱动包,供设备 Init 时查找驱动
|
_manager.Scan(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Driver"), s => { });
|
|
// 扫描 DeviceDesc 注解,填充 AllDeviceType
|
DeviceHelper.ScanDeviceTypes();
|
|
// 以数据库为准恢复设备列表(不调用 Init,避免启动即占用硬件)
|
ReloadDeviceList();
|
|
RefreshDeviceTree();
|
}
|
|
private void RefreshButton_Click(object sender, RoutedEventArgs e)
|
{
|
RefreshDeviceTree();
|
}
|
|
private void AddDeviceButton_Click(object sender, RoutedEventArgs e)
|
{
|
var dialog = new AddDeviceWindow { Owner = this };
|
if (dialog.ShowDialog() != true || dialog.Device == null)
|
{
|
return;
|
}
|
|
IDevice device = dialog.Device;
|
if (!DeviceHelper.SaveDevice(device))
|
{
|
HeaderText.Text = $"设备 {device.DeviceId} 保存失败";
|
return;
|
}
|
|
// 保存成功后从数据库重新读取设备列表,而不是把弹窗里新建的实例直接塞进列表
|
ReloadDeviceList();
|
RefreshDeviceTree();
|
|
HeaderText.Text = $"已添加设备 {device.DeviceId}";
|
}
|
|
/// <summary>以 Config\Devices.db 为准刷新内存中的设备列表(不调用 Init)。</summary>
|
private static void ReloadDeviceList()
|
{
|
DeviceManager.Refresh(DeviceHelper.LoadDevices());
|
}
|
|
private void StartService_Click(object sender, RoutedEventArgs e)
|
{
|
// 运行中点击即为“停止”
|
if (ServiceStateMachine.GlobalState.State == ServiceStatus.Running)
|
{
|
ServiceManager.Stop();
|
HeaderText.Text = "服务已停止";
|
return;
|
}
|
|
try
|
{
|
ServiceManager.Start();
|
}
|
catch (Exception ex)
|
{
|
MessageBox.Show(ex.Message);
|
}
|
}
|
|
private void DebugWindowButton_Click(object sender, RoutedEventArgs e)
|
{
|
var debug = new DebugWindow { Owner = this };
|
debug.Show();
|
}
|
|
private void LogWindowButton_Click(object sender, RoutedEventArgs e)
|
{
|
var log = new LogWindow { Owner = this };
|
log.Show();
|
}
|
|
private void DeviceTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
{
|
if (e.NewValue is DeviceNode node)
|
{
|
ShowDeviceConfig(node.Device);
|
}
|
else
|
{
|
ConfigHost.Content = null;
|
HeaderText.Text = "设备配置";
|
}
|
}
|
|
private void ShowDeviceConfig(IDevice device)
|
{
|
HeaderText.Text = $"{device.Type} - {device.DeviceId}";
|
|
UserControl? control = DeviceConfigControlFactory.Create(device);
|
if (control == null)
|
{
|
// 未按命名规则找到对应配置控件
|
ConfigHost.Content = new TextBlock
|
{
|
Text = $"未找到 {device.GetType().Name}ConfigControl,无法显示该设备的配置界面。",
|
Margin = new Thickness(8),
|
TextWrapping = TextWrapping.Wrap,
|
TextAlignment = TextAlignment.Center,
|
VerticalAlignment = VerticalAlignment.Center
|
};
|
return;
|
}
|
|
control.DataContext = device;
|
ConfigHost.Content = control;
|
}
|
|
private void RefreshDeviceTree()
|
{
|
string? selectedId = (DeviceTree.SelectedItem as DeviceNode)?.Device.DeviceId;
|
|
_groups.Clear();
|
foreach (var group in DeviceManager.Devices
|
.GroupBy(d => d.Type)
|
.OrderBy(g => g.Key, StringComparer.Ordinal))
|
{
|
_groups.Add(new DeviceGroupNode(group.Key, group.Select(d => new DeviceNode(d))));
|
}
|
|
// 容器在本次布局之后才生成,延后展开,确保新增节点能显示出来
|
Dispatcher.BeginInvoke(new Action(ExpandAllGroups), DispatcherPriority.Loaded);
|
}
|
|
/// <summary>展开所有分组节点。</summary>
|
private void ExpandAllGroups()
|
{
|
if (DeviceTree.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
|
{
|
EventHandler? handler = null;
|
handler = (s, e) =>
|
{
|
if (DeviceTree.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
|
{
|
DeviceTree.ItemContainerGenerator.StatusChanged -= handler;
|
ExpandAllGroups();
|
}
|
};
|
DeviceTree.ItemContainerGenerator.StatusChanged += handler;
|
return;
|
}
|
|
for (int i = 0; i < DeviceTree.Items.Count; i++)
|
{
|
if (DeviceTree.ItemContainerGenerator.ContainerFromIndex(i) is TreeViewItem item)
|
{
|
item.IsExpanded = true;
|
}
|
}
|
}
|
}
|