lnnovationHubTool,用prism+WPF编写的MVVM模式的快速上位机软件开发框架平台 - 教程

如果需要源代码请私信我

lnnovationHubTool 技术与功能说明文档

效果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

一、 引言

本文档详细介绍了 lnnovationHubTool 项目套件的各项功能、核心组件以及具体代码用法。该套件主要由三部分组成:

  • UllnnovationHub.ToolKIt: 一个WPF UI组件库,提供丰富的自定义控件和样式。
  • lnnovationHubTool.Core: 项目的核心库,提供基础服务如日志管理、参数持久化、通信接口等。
  • lnnovationHubTool: 主应用程序,集成核心功能和UI组件,实现具体的业务逻辑。

二、 UllnnovationHub.ToolKIt (UI组件库)

UllnnovationHub.ToolKIt 旨在提供一套美观、易用的WPF UI控件和样式。

2.1 如何使用

  1. 编译 UllnnovationHub.ToolKIt 项目,生成 UllnnovationHub.ToolKIt.dll

  2. 在您的WPF项目中添加对 UllnnovationHub.ToolKIt.dll 的引用。

  3. App.xaml 中引入资源字典:

    <!-- filepath: App.xaml -->
      <Application.Resources>
        <ResourceDictionary>
          <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/UllnnovationHub.ToolKIt;Component/Generic.xaml" />
          </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
      </Application.Resources>
  4. 在XAML页面中引用命名空间:

    xmlns:ui="clr-namespace:UllnnovationHub.ToolKIt.UI;assembly=UllnnovationHub.ToolKIt"

2.2 主要UI控件

2.2.1 UMessageBox (自定义消息框)

UMessageBox 是一个功能增强的自定义消息框,替代标准的 System.Windows.MessageBox

功能特性:

  • 支持多种消息类型:Info, Error, Warning, Question
  • 支持多种按钮组合:OK, OKCancel, YesNo, YesNoCancel
  • 提供同步 (ShowAndGetResult) 和异步 (Show 带回调) 的调用方式。
  • 可自定义标题和内容。
  • 窗口可拖动。
  • 自动作为活动窗口的子窗口。

C# 使用方法:

// filepath: ExampleViewModel.cs
using UllnnovationHub.ToolKIt.UI;
using System.Windows;
// For MessageBoxResult
using System.Threading.Tasks;
// ...
public void ShowInfoMessage()
{
var messageBox = new UMessageBox();
messageBox.Show("这是一条信息提示。", "提示", UMessageBox.MessageBoxType.Info, UMessageBox.ButtonType.OK, result =>
{
if (result == MessageBoxResult.OK)
{
// 用户点击了确定
System.Diagnostics.Debug.WriteLine("用户点击了确定。");
}
});
}
public void ShowErrorMessageSync()
{
var messageBox = new UMessageBox();
MessageBoxResult result = messageBox.ShowAndGetResult("发生了一个错误。", "错误", UMessageBox.MessageBoxType.Error, UMessageBox.ButtonType.OK);
if (result == MessageBoxResult.OK)
{
// 用户点击了确定
System.Diagnostics.Debug.WriteLine("错误消息框,用户点击了确定。");
}
}
public void ShowQuestionMessage()
{
var messageBox = new UMessageBox();
MessageBoxResult result = messageBox.ShowAndGetResult("您确定要执行此操作吗?", "请确认", UMessageBox.MessageBoxType.Question, UMessageBox.ButtonType.YesNo);
if (result == MessageBoxResult.Yes)
{
// 用户点击了“是”
System.Diagnostics.Debug.WriteLine("问题消息框,用户点击了是。");
}
else if (result == MessageBoxResult.No)
{
// 用户点击了“否”
System.Diagnostics.Debug.WriteLine("问题消息框,用户点击了否。");
}
else if (result == MessageBoxResult.Cancel)
{
// 用户点击了“取消”(如果按钮类型包含取消)
System.Diagnostics.Debug.WriteLine("问题消息框,用户点击了取消。");
}
}
// ...
2.2.2 Card (卡片控件)

Card 控件用于将内容分组显示在一个具有视觉吸引力的卡片界面中。

XAML 使用方法:

<!-- filepath: YourView.xaml -->
  <
    ui:Card Margin="10" Padding="15">
  <StackPanel>
    <TextBlock Text="卡片标题" FontSize="16" FontWeight="Bold"/>
    <TextBlock Text="这里是卡片的内容区域。"/>
  </StackPanel>
</ui:Card>
2.2.3 UTextBox (增强文本框)

UTextBox 是一个带有附加功能的文本框,例如水印提示 (Placeholder)。其样式定义在 Themes/UTextBox.xaml 中。

XAML 使用方法:

<!-- filepath: YourView.xaml -->
  <!-- 假设 UTextBox 通过其 Style 或附加属性支持 Placeholder -->
      <TextBox Margin="5" ui:ControlAttach.Placeholder="请输入用户名..." Text="{Binding Username}" Style="{StaticResource UTextBoxBaseStyle
    }" />
    <!-- 或者如果 UTextBox 是一个完全自定义的控件 -->
      <!-- <ui:UTextBox Margin="5" Placeholder="请输入用户名..." Text="{Binding Username}" /> -->

注意: ControlAttach.Placeholder 是一个常见的附加属性命名方式,具体请参照 UTextBox.xaml 或相关附加属性类的定义。如果 UTextBox 是一个派生控件,它可能有自己的 Placeholder 属性。

2.2.4 SwitchButton (开关按钮)

提供一个视觉上类似拨动开关的布尔型输入控件。

XAML 使用方法:

<!-- filepath: YourView.xaml -->
  <!-- 假设 SwitchButton 是一个自定义控件 -->
    <
      ui:SwitchButton Margin="5" IsChecked="{Binding IsFeatureEnabled}" />
2.2.5 SwitchRadioButton (开关单选按钮)

结合了开关和单选按钮的功能,通常用于一组选项中。

XAML 使用方法:

<!-- filepath: YourView.xaml -->
  <StackPanel>
    <
      ui:SwitchRadioButton Content="选项 A" GroupName="MyOptionsGroup" IsChecked="{Binding OptionASelected}" />
    <
      ui:SwitchRadioButton Content="选项 B" GroupName="MyOptionsGroup" IsChecked="{Binding OptionBSelected}" />
  </StackPanel>
2.2.6 其他控件样式

Generic.xaml 合并了多个资源字典,为WPF原生控件提供了自定义样式。

  • Button.xaml: 按钮样式 (e.g., BaseButtonStyle, PrimaryButtonStyle)
  • RadioButton.xaml: 单选按钮样式
  • TabControl.xaml: 选项卡控件样式
  • GroupBox.xaml: 分组框样式 (e.g., BaseGroupBoxStyle, SqureShadowHeaderGroupBoxStyle, RoundedShadowHeaderGroupBoxStyle)
  • Expander.xaml: 折叠面板样式
  • ComboBox.xaml: 下拉框样式
  • PasswordBox.xaml: 密码框样式
  • CheckBox.xaml: 复选框样式
  • ListBox.xaml: 列表框样式
  • TreeView.xaml & TreeViewItem.xaml: 树视图样式
  • MenuItem.xaml: 菜单项样式
  • ImageButton.xaml: 图像按钮样式
  • Slider.xaml: 滑动条样式
  • ListView.xaml: 列表视图样式
  • DataGrid.xaml: 数据网格样式
  • HorizontolSeparator.xaml & VerticalSeparator.xaml: 分隔线样式

XAML 使用方法 (应用样式):

<!-- filepath: YourView.xaml -->
  <Button Content="默认样式按钮" Margin="5" />
    <Button Content="主按钮样式" Margin="5" Style="{StaticResource PrimaryButton
  }" /> <!-- 假设样式Key为 PrimaryButton -->
      <GroupBox Header="测试基础样式" Margin="10" Style="{StaticResource BaseGroupBoxStyle
    }"/>
      <GroupBox Header="方形阴影标题" Margin="10" Style="{StaticResource SqureShadowHeaderGroupBoxStyle
    }"/>
      <GroupBox Header="圆形阴影标题" Margin="10" Style="{StaticResource RoundedShadowHeaderGroupBoxStyle
    }"/>
      <DataGrid Margin="5" Style="{StaticResource DataGridStyle1
    }"> <!-- 假设样式Key为 DataGridStyle1 -->
      <!-- Columns and ItemsSource -->
      </DataGrid>

注意: 具体的样式键名 (Style Key) 取决于各个 Themes/*.xaml 文件中的定义。

2.3 Helper

2.3.1 UllnnovationHub.ToolKIt.Helper.MessageBox

这是一个静态辅助类,封装了对 UMessageBox 的调用,简化了消息框的显示。

C# 使用方法:

// filepath: ExampleViewModel.cs
using MessageBox = UllnnovationHub.ToolKIt.Helper.MessageBox;
// 为方便使用设置别名
using System.Windows;
// For MessageBoxResult
// ...
public void ShowSimplifiedInfo()
{
// 假设 Helper.MessageBox 内部会创建和配置 UMessageBox 实例
MessageBox.Info("操作已成功完成。", "成功");
}
public void ShowSimplifiedError()
{
MessageBox.Error("保存配置时发生错误。", "错误");
}
public void ShowSimplifiedWarning()
{
MessageBox.Warning("这是一个警告信息。", "警告");
}
public MessageBoxResult ShowSimplifiedConfirm()
{
// 假设 Confirm 方法返回 MessageBoxResult
return MessageBox.Confirm("您确定要删除这条记录吗?", "请确认");
}
// 示例:如果 Helper.MessageBox 提供了直接返回 UMessageBox.MessageBoxType 的方法
public void ShowMessageWithSpecificType()
{
// 假设 Show 方法签名类似:
// static void Show(string message, string caption, UMessageBox.MessageBoxType type, UMessageBox.ButtonType buttonType)
// MessageBox.Show("这是一条询问消息", "询问", UMessageBox.MessageBoxType.Question, UMessageBox.ButtonType.YesNoCancel);
}
// ...

三、 lnnovationHubTool.Core (核心库)

lnnovationHubTool.Core 提供了应用程序的基础服务和核心逻辑。

3.1 日志管理 (IW.Core.Log)

3.1.1 LogManage

静态类,提供全局的日志记录功能。

功能特性:

  • 异步日志记录,避免阻塞主线程。
  • 支持多种日志级别: Info, Procedure, Warn, Error
  • 可自定义日志文件路径 (CustomLogPath) 和文件名 (CustomLogFileName)。
  • 可自定义日志格式 (LogFormatter)。
  • 自动清理旧日志文件 (可配置 SaveDays)。
  • 提供日志读取功能 (Read)。
  • 日志写入事件回调 (OnWriteLog),用于实时显示日志。
  • 可关联用户管理服务 (IUserManageService) 以记录操作员信息。

C# 初始化与配置:

// filepath: App.xaml.cs or a Bootstrapper class
using IW.Core.Log;
using IW.Core.CommonTool;
// For PathHelper
using IW.Core.Services.UserRoleConfigure.Services;
// For IUserManageService (假设接口路径)
using System;
using System.IO;
using System.Windows;
// For Application
public partial class App
: Application
{
private IUserManageService _userManageService;
// 示例:用户服务实例
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// 示例:初始化用户服务 (具体实现依赖于您的项目)
// _userManageService = new YourUserManageServiceImplementation();
// LogManage.SetUserManageService(_userManageService);
LogManage.Init();
// 应用默认配置和自定义格式化器
// 可选:在Init之后覆盖或补充配置
LogManage.CustomLogPath = () => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ApplicationLogs");
LogManage.CustomLogFileName = () =>
$"AppLog_{
DateTime.Now:yyyy-MM-dd
}.log";
LogManage.SaveDays = 60;
// 保留60天日志
// 示例:订阅日志写入事件 (LogManage.Init 中可能已有默认的控制台输出)
LogManage.OnWriteLog += (logItem) =>
{
// 在UI上显示日志,注意线程调度
Application.Current?.Dispatcher?.Invoke(() =>
{
// 例如:添加到ObservableCollection<LogItem> 以更新UI
  // LogViewModel.LogEntries.Add(logItem);
  });
  System.Diagnostics.Debug.WriteLine($"实时日志回调: [{
  logItem.Level
  }] {
  logItem.Message
  }");
  };
  }
  protected override void OnExit(ExitEventArgs e)
  {
  LogManage.Close(5);
  // 程序退出前关闭日志,等待最多5秒完成写入
  base.OnExit(e);
  }
  }

C# 日志记录方法:

// filepath: ExampleService.cs
using IW.Core.Log;
using System;
public class ExampleService
{
public void PerformDatabaseOperation(string connectionString)
{
LogManage.Info("数据库操作开始。");
try
{
LogManage.Procedure($"尝试连接到数据库: {
connectionString
}");
// ... 执行数据库操作 ...
if (string.IsNullOrEmpty(connectionString))
{
LogManage.Warn("连接字符串为空,操作可能失败。");
}
// 模拟操作
System.Threading.Thread.Sleep(100);
LogManage.Procedure("数据库操作步骤1完成。");
LogManage.Info("数据库操作成功完成。");
}
catch (TimeoutException tex)
{
LogManage.Error("数据库操作超时。", tex);
}
catch (Exception ex)
{
LogManage.Error($"数据库操作发生未知错误: {
ex.Message
}", ex);
}
}
}

C# 日志读取方法:

// filepath: LogViewModel.cs
using IW.Core.Log;
using System;
using System.Collections.Generic;
using System.Linq;
// using System.Collections.ObjectModel; // For ObservableCollection if binding to UI
public class LogViewModel
// : YourViewModelBaseClass
{
// public ObservableCollection<LogItem> DisplayedLogs { get; } = new ObservableCollection<LogItem>();
  public void LoadLogsForToday(LogLevel logLevelFilter)
  {
  DateTime startTime = DateTime.Today;
  DateTime endTime = DateTime.Now;
  // 或者 DateTime.Today.AddDays(1).AddTicks(-1) 表示到今天结束
  List<LogItem> logs = LogManage.Read(startTime, endTime, logLevelFilter);
    // DisplayedLogs.Clear();
    if (logs != null)
    {
    // foreach (var log in logs)
    // {
    // DisplayedLogs.Add(log);
    // }
    }
    }
    }
3.1.2 LogItem

表示单条日志记录的数据结构。

主要属性:

  • Time: string (在 LogManage.Read 中解析为 DateTime 前的原始字符串) - 日志记录时间。
  • Level: string - 日志级别 (如 “Info”, “Error”)。
  • ThreadId: string - 记录日志的线程ID。
  • UserName: string - 操作用户名。
  • UserRole: string - 操作用户角色。
  • Message: string - 日志消息内容。
3.1.3 LogLevel (枚举)

定义日志的严重级别,用于记录和筛选。

  • Info: 普通信息。
  • Warn: 警告信息。
  • Error: 错误信息。
  • Procedure: 流程/调试信息 (在 LogManage.Debug 方法中被映射为 LogLevel.Procedure 进行记录)。
  • All: 用于 LogManage.Read 时,表示读取所有级别的日志。

3.2 公共工具 (IW.Core.CommonTool)

3.2.1 PathHelper

静态类,用于管理应用程序中常用的路径。

主要属性 (示例):

  • G_LogPath: string - 日志文件的存储路径。由 LogManage.CustomLogPath 委托确定,PathHelper 可能提供默认值或被 LogManage 使用。
  • G_Parameters: string - 参数文件的存储路径 (基于 功能说明.md 推断)。

C# 使用方法:

// filepath: ConfigurationService.cs
using IW.Core.CommonTool;
// Assuming PathHelper is here
using System.IO;
public class ConfigurationService
{
public string GetParameterFilePath(string fileName)
{
// 假设 PathHelper.G_Parameters 提供了参数文件夹的根路径
// string parametersDirectory = PathHelper.G_Parameters;
// if (!Directory.Exists(parametersDirectory))
// {
// Directory.CreateDirectory(parametersDirectory);
// }
// return Path.Combine(parametersDirectory, fileName);
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Parameters", fileName);
// Fallback example
}
public string GetLogDirectory()
{
return PathHelper.G_LogPath;
// G_LogPath is set by LogManage.CustomLogPath
}
}

3.3 用户角色管理 (IW.Core.Services.UserRoleConfigure.Services)

3.3.1 IUserManageService

接口,定义用户登录、权限检查等用户管理相关操作。LogManage 通过 SetUserManageService 方法接收此接口的实例,以在日志中记录当前用户信息。

接口方法示例 (概念性):

// filepath: IUserManageService.cs (Conceptual)
// namespace IW.Core.Services.UserRoleConfigure.Services;
// public interface IUserManageService
// {
// CurrentUser CurrentUser { get; } // Represents the logged-in user's details
// bool Login(string username, string password);
// void Logout();
// bool HasPermission(string permissionKey);
// }
// public class CurrentUser
// {
// public string UserName { get; set; }
// public string Role { get; set; } // Or an enum for roles
// }

LogManage 中的使用:
LogManage 内部在格式化日志时,如果 _userManageService 实例不为空,会尝试调用 _userManageService.CurrentUser 来获取用户名和角色。

3.4 参数服务

3.4.1 IParameterService (接口)

定义参数持久化(保存和加载)的方法,通常使用XML或JSON序列化。

接口定义 (推断自 功能说明.md):

// filepath: IParameterService.cs (Conceptual, likely in IW.Core.Services namespace)
public interface IParameterService
{
void SaveParameter<T>(T parameter, string fileName) where T : class
  ;
  T LoadParameter<T>(string fileName) where T : class,
    new();
    }

C# 使用方法 (假设已实现并注入 _parameterService):

// filepath: SettingsViewModel.cs
// using IW.Core.Services; // For IParameterService
// public class AppSettings { /* ... properties ... */ }
// private IParameterService _parameterService;
// public AppSettings CurrentSettings { get; set; }
public void LoadApplicationSettings()
{
// CurrentSettings = _parameterService.LoadParameter<AppSettings>("ApplicationSettings.xml");
  // if (CurrentSettings == null)
  // {
  // CurrentSettings = new AppSettings(); // Load defaults or create new
  // }
  }
  public void SaveApplicationSettings()
  {
  // if (CurrentSettings != null)
  // {
  // _parameterService.SaveParameter(CurrentSettings, "ApplicationSettings.xml");
  // }
  }
3.4.2 StringWrapper

用于序列化单个字符串值,当需要将字符串作为独立的XML文件内容或者需要一个对象根进行序列化时使用。

类定义 ():

// filepath: StringWrapper.cs (Conceptual, likely in IW.Core.Models or Common namespace)
using System;
[Serializable]
public class StringWrapper
{
public string Value {
get;
set;
}
public StringWrapper() { Value = string.Empty;
}
public StringWrapper(string value) { Value = value;
}
public static implicit operator string(StringWrapper wrapper) => wrapper?.Value;
public static implicit operator StringWrapper(string value) =>
new StringWrapper(value);
}

C# 使用方法:

// filepath: DeviceConfigurationService.cs
// using IW.Core.Services; // For IParameterService
// using IW.Core.Models; // For StringWrapper
// private IParameterService _parameterService;
public void SaveDeviceIdentifier(string deviceId)
{
// StringWrapper wrapper = deviceId; // Implicit conversion from string
// _parameterService.SaveParameter(wrapper, "DeviceIdentifier.xml");
}
public string LoadDeviceIdentifier()
{
// StringWrapper wrapper = _parameterService.LoadParameter<StringWrapper>("DeviceIdentifier.xml");
  // string deviceId = wrapper; // Implicit conversion to string
  // return deviceId ?? "DefaultDeviceID";
  return "DefaultDeviceID_Placeholder";
  // Placeholder
  }

3.5 通信功能 ()

3.5.1 Modbus通信 (ModbusTCP)

用于与支持Modbus TCP协议的设备(如PLC)通信。

C# 使用方法 (概念性, 基于 功能说明.md):

// filepath: ModbusDeviceService.cs
// Assuming a ModbusTCP class exists, e.g., from a third-party library or custom implementation
// Example: using EasyModbus; // If using EasyModbusTCP .NET package
public class ModbusDeviceService
{
// private ModbusClient _modbusClient; // Example using EasyModbus
public ModbusDeviceService(string ipAddress, int port)
{
// _modbusClient = new ModbusClient(ipAddress, port);
}
public bool Connect()
{
// try
// {
// _modbusClient.Connect();
// return _modbusClient.Connected;
// }
// catch (Exception ex)
// {
// LogManage.Error("Modbus连接失败", ex);
// return false;
// }
return false;
// Placeholder
}
public int[] ReadHoldingRegisters(int startAddress, int quantity)
{
// if (!_modbusClient.Connected) return null;
// try
// {
// return _modbusClient.ReadHoldingRegisters(startAddress, quantity);
// }
// catch (Exception ex)
// {
// LogManage.Error($"读取Modbus保持寄存器失败 (地址:{startAddress},数量:{quantity})", ex);
// return null;
// }
return null;
// Placeholder
}
public bool WriteSingleRegister(int address, int value)
{
// if (!_modbusClient.Connected) return false;
// try
// {
// _modbusClient.WriteSingleRegister(address, value);
// return true;
// }
// catch (Exception ex)
// {
// LogManage.Error($"写入Modbus单个寄存器失败 (地址:{address},值:{value})", ex);
// return false;
// }
return false;
// Placeholder
}
public void Disconnect()
{
// _modbusClient?.Disconnect();
}
}
3.5.2 TCP/IP 通信 ()

通用的TCP客户端通信实现。

C# 使用方法 (概念性, 基于 功能说明.md):

// filepath: GenericTcpDeviceService.cs
// Assuming TCPCommunicate class exists
// public class GenericTcpDeviceService
// {
// private TCPCommunicate _tcpComm;
// public event EventHandler<byte[]> DataReceived;
  // public GenericTcpDeviceService(string ipAddress, int port)
  // {
  // _tcpComm = new TCPCommunicate(ipAddress, port);
  // _tcpComm.DataReceivedEvent += OnRawDataReceived;
  // }
  // private void OnRawDataReceived(object sender, byte[] data)
  // {
  // DataReceived?.Invoke(this, data); // Forward the event
  // string receivedString = System.Text.Encoding.UTF8.GetString(data);
  // LogManage.Procedure($"TCP收到数据: {receivedString}");
  // }
  // public bool OpenConnection()
  // {
  // try
  // {
  // _tcpComm.Open();
  // return true; // Assuming Open() throws on failure or returns status
  // }
  // catch (Exception ex)
  // {
  // LogManage.Error("TCP连接打开失败", ex);
  // return false;
  // }
  // }
  // public bool SendMessage(string message)
  // {
  // try
  // {
  // _tcpComm.SendMessage(message);
  // return true;
  // }
  // catch (Exception ex)
  // {
  // LogManage.Error("TCP发送消息失败", ex);
  // return false;
  // }
  // }
  // public void CloseConnection()
  // {
  // _tcpComm?.Close();
  // }
  // }
3.5.3 串口通信 ()

用于与通过串口连接的设备通信。

C# 使用方法 (概念性, 基于 功能说明.md):

// filepath: PowerSupplyService.cs
// Assuming SerialPortData, PowerManager, and an ICommunication (or similar) serial port class exist
// public enum PowerChannel { Power1, Power2 } // Example enum
// public class PowerSupplyService
// {
// private PowerManager _powerManager; // Manages power supply communication instances
// public PowerSupplyService()
// {
// _powerManager = new PowerManager(); // Initialize PowerManager
// }
// public bool ConfigureSerialPort(PowerChannel channel, SerialPortData portConfig)
// {
// // _powerManager.Setting(portConfig, channel); // Configures the serial port for the given channel
// // ICommunication serialComm = channel == PowerChannel.Power1 ? _powerManager.powerComunication1 : _powerManager.powerComunication2;
// // try
// // {
// // serialComm?.Open();
// // return serialComm?.IsOpen ?? false;
// // }
// // catch (Exception ex)
// // {
// // LogManage.Error($"配置并打开串口 {portConfig.PortName} 失败 (通道: {channel})", ex);
// // return false;
// // }
// return false; // Placeholder
// }
// public bool SendSerialCommand(PowerChannel channel, string command)
// {
// // ICommunication serialComm = channel == PowerChannel.Power1 ? _powerManager.powerComunication1 : _powerManager.powerComunication2;
// // if (serialComm == null || !serialComm.IsOpen)
// // {
// // LogManage.Warn($"串口未打开或未配置 (通道: {channel}),无法发送命令: {command}");
// // return false;
// // }
// // try
// // {
// // serialComm.SendMessage(command);
// // return true;
// // }
// // catch (Exception ex)
// // {
// // LogManage.Error($"通过串口发送命令失败 (通道: {channel}, 命令: {command})", ex);
// // return false;
// // }
// return false; // Placeholder
// }
// }

3.6 TaskManager 流程管理器 ()

用于管理和执行定义好的工艺流程或任务序列。

功能特性:

  • 初始化工作站列表 (IniStationList)。
  • 控制流程的初始化 (Init)、自动运行 (AutoRun)、暂停 (Pause)、继续 (Continue)、停止 (Stop)。
  • 通过 OnStationStatusChange 事件回调监控工作站状态变化。

C# 使用方法 (概念性, 基于 功能说明.md):

// filepath: ProductionControlViewModel.cs
// Assuming TaskManager is a singleton or static accessible class
// using System.Collections.ObjectModel; // For UI binding
// using System.Linq;
// using System.Windows; // For Application.Current.Dispatcher
// public class StationUIModel { public string Id { get; set; } public string Status { get; set; } public string Message { get; set; } }
// public class ProductionControlViewModel // : YourViewModelBase
// {
// // public ObservableCollection<StationUIModel> Stations { get; } = new ObservableCollection<StationUIModel>();
  // public ProductionControlViewModel()
  // {
  // // TaskManager.Instance.OnStationStatusChange += OnStationStatusChanged;
  // }
  // public void InitializeWorkflow(string deviceType)
  // {
  // // TaskManager.IniStationList(deviceType); // Initializes stations based on device type
  // // TaskManager.Instance.Init(); // Initializes the overall task manager/workflow
  // // PopulateStationsFromTaskManager(); // Helper to initially populate UI
  // }
  // private void OnStationStatusChanged(StationData station) // Assuming StationData is the type from TaskManager
  // {
  // // Application.Current.Dispatcher.Invoke(() =>
  // // {
  // // var uiStation = Stations.FirstOrDefault(s => s.Id == station.Id);
  // // if (uiStation != null)
  // // {
  // // uiStation.Status = station.Status;
  // // uiStation.Message = station.Message;
  // // }
  // // else
  // // {
  // // // Stations.Add(new StationUIModel { Id = station.Id, Status = station.Status, Message = station.Message });
  // // }
  // // });
  // }
  // public void StartAutoMode() => TaskManager.Instance.AutoRun();
  // public void PauseAutoMode() => TaskManager.Instance.Pause();
  // public void ContinueAutoMode() => TaskManager.Instance.Continue();
  // public void StopAutoMode() => TaskManager.Instance.Stop();
  // // private void PopulateStationsFromTaskManager() { /* ... */ }
  // }

四、 lnnovationHubTool (主应用程序)

主应用程序集成了 UllnnovationHub.ToolKItlnnovationHubTool.Core,并使用 Prism 框架构建模块化的WPF应用。

4.1 主要视图 (Views)

  • MainView: 应用程序的主窗口或主内容区域,通常包含导航和内容区域。
  • LogView: 显示系统日志,提供筛选和查看功能。
  • AlarmView: 显示系统报警信息。
  • UserManageView: 用户管理界面 (推断)。
  • SettingView: 系统设置界面。
  • CameraView: 相机图像显示和控制界面。
  • DeBugView: 包含各种调试工具和相机调试功能的视图。
  • ParameterView: 参数配置界面。
  • CustomControls Views (AxisSettingView, DebugCameraView, RecipeView): 特定功能的自定义控件或组合视图,用于更复杂的交互。

4.2 Prism 框架集成

4.2.1 模块注册 (Bootstrapper or App class)

Prism应用通常有一个引导程序(Bootstrapper)或在 App.xaml.cs 中配置模块。

// filepath: App.xaml.cs or YourBootstrapper.cs
// using Prism.DryIoc; // Or Prism.Unity, Prism.Ninject etc.
// using Prism.Ioc;
// using Prism.Modularity;
// using System.Windows;
// using YourMainModule; // Namespace of your module
// public class YourBootstrapper : PrismBootstrapper
// {
// protected override DependencyObject CreateShell()
// {
// return Container.Resolve<ShellWindow>(); // Your main window
  // }
  // protected override void RegisterTypes(IContainerRegistry containerRegistry)
  // {
  // // Register global services, etc.
  // }
  // protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
  // {
  // moduleCatalog.AddModule<MainModule>(); // Example: Main application module
    // moduleCatalog.AddModule<LoggingModule.LoggingModule>(); // Example: A dedicated logging module
      // // ... other modules
      // }
      // }
4.2.2 视图注册与导航

视图和视图模型在模块中注册,并通过区域管理器 (RegionManager) 进行导航。

// filepath: MainModule.cs (Example Prism Module)
// using Prism.Ioc;
// using Prism.Modularity;
// using Prism.Regions;
// using YourApp.Views; // Namespace for views
// using YourApp.ViewModels; // Namespace for viewmodels
// public class MainModule : IModule
// {
// public void OnInitialized(IContainerProvider containerProvider)
// {
// var regionManager = containerProvider.Resolve<IRegionManager>();
  // // Initial navigation if needed
  // regionManager.RequestNavigate("ContentRegionNameInShell", nameof(MainView));
  // }
  // public void RegisterTypes(IContainerRegistry containerRegistry)
  // {
  // // Register views for navigation
  // containerRegistry.RegisterForNavigation<MainView, MainViewModel>();
    // containerRegistry.RegisterForNavigation<LogView, LogViewModel>();
      // containerRegistry.RegisterForNavigation<AlarmView, AlarmViewModel>();
        // // ... register other views and their viewmodels
        // }
        // }

在 ViewModel 中导航:

// filepath: ShellViewModel.cs or AnyViewModelWithNavigation.cs
// using Prism.Commands;
// using Prism.Mvvm;
// using Prism.Regions;
// public class ShellViewModel : BindableBase
// {
// private readonly IRegionManager _regionManager;
// public DelegateCommand<string> NavigateCommand { get; private set; }
  // public ShellViewModel(IRegionManager regionManager)
  // {
  // _regionManager = regionManager;
  // NavigateCommand = new DelegateCommand<string>(Navigate);
    // }
    // private void Navigate(string navigationPath)
    // {
    // // navigationPath would be the name of the view registered for navigation, e.g., "LogView"
    // _regionManager.RequestNavigate("ContentRegionNameInShell", navigationPath, navigationResult =>
    // {
    // if (navigationResult.Result == false)
    // {
    // LogManage.Error($"导航到 {navigationPath} 失败: {navigationResult.Error?.Message}");
    // }
    // });
    // }
    // }

4.3 相机集成 (DeBugView 相关)

系统支持多种品牌相机(海康、Basler、大恒),通过工厂模式创建相机实例。

4.3.1 ICamera (接口) 和 CamFactory
  • ICamera: 定义相机操作的通用接口 (如初始化、枚举设备、打开/关闭设备、开始/停止抓图、获取/设置参数、注册图像回调)。
  • CamFactory: 工厂类,用于根据品牌 (CameraBrand 枚举) 创建具体的相机实例。
  • CameraBrand (枚举): HIK, Basler, DaHeng

C# 使用方法 ():

// filepath: CameraControlService.cs or DebugCameraViewModel.cs
// using IW.Camera; // Assuming camera related classes are in this namespace (ICamera, CamFactory, CameraBrand, ImageEventArgs)
// using System.Collections.Generic;
// using System.Linq;
// using System.Windows.Media.Imaging; // For BitmapSource if image is converted
// public class CameraControlService
// {
// private ICamera _activeCamera;
// public event EventHandler<BitmapSource> NewImageReceived; // Example event for UI
  // public List<string> EnumerateDevices(CameraBrand brand)
    // {
    // // This might be a static method on CamFactory or require a temporary instance
    // // return CamFactory.GetDeviceEnum(brand);
    // // Or, if GetListEnum is instance-based after CreatCamera:
    // ICamera tempCam = CamFactory.CreatCamera(brand);
    // return tempCam?.GetListEnum(); // Ensure to handle tempCam disposal if it opens resources
    // }
    // public bool InitializeCamera(CameraBrand brand, string deviceIdentifier) // deviceIdentifier could be SN or UserDefinedName
    // {
    // if (_activeCamera != null && _activeCamera.IsDeviceOpen())
    // {
    // _activeCamera.CloseDevice();
    // _activeCamera.ImageGrabbed -= OnCameraImageGrabbed; // Unsubscribe
    // }
    // _activeCamera = CamFactory.CreatCamera(brand);
    // if (_activeCamera == null)
    // {
    // LogManage.Error($"创建相机实例失败: {brand}");
    // return false;
    // }
    // if (!_activeCamera.InitDevice(deviceIdentifier)) // InitDevice might take SN or index
    // {
    // LogManage.Error($"初始化相机设备失败: {deviceIdentifier} ({brand})");
    // return false;
    // }
    // _activeCamera.ImageGrabbed += OnCameraImageGrabbed; // Subscribe to image event
    // LogManage.Info($"相机 {deviceIdentifier} ({brand}) 初始化成功。");
    // return true;
    // }
    // public void StartGrabbing()
    // {
    // _activeCamera?.StartGrabbing();
    // }
    // public void StopGrabbing()
    // {
    // _activeCamera?.StopGrabbing();
    // }
    // public void CloseCamera()
    // {
    // if (_activeCamera != null)
    // {
    // _activeCamera.StopGrabbing(); // Ensure grabbing is stopped
    // _activeCamera.CloseDevice(); // This should handle unregistering/releasing resources
    // _activeCamera.ImageGrabbed -= OnCameraImageGrabbed;
    // _activeCamera = null;
    // LogManage.Info("相机已关闭。");
    // }
    // }
    // private void OnCameraImageGrabbed(object sender, ImageEventArgs e) // Assuming ImageEventArgs contains image data
    // {
    // // Process e.Bitmap or e.RawImageData
    // // Example: Convert to BitmapSource for WPF UI
    // // BitmapSource bmpSource = ConvertToBitmapSource(e.Bitmap);
    // // NewImageReceived?.Invoke(this, bmpSource);
    // }
    // // public BitmapSource ConvertToBitmapSource(System.Drawing.Bitmap bitmap) { /* ... conversion logic ... */ return null; }
    // }

心跳机制:
为解决调试时直接中断程序导致相机未注销的问题,网口相机增加了心跳检测。若连接断开超过预设时间(如1000ms),相机会自动注销,方便下次直接连接。此功能通常在相机SDK的特定实现中处理,或由 ICamera 实现类内部管理。


>如果需要源代码请私信我

posted @ 2025-07-22 21:50  yjbjingcha  阅读(47)  评论(0)    收藏  举报