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

发布于:2025-06-08 ⋅ 阅读:(20) ⋅ 点赞:(0)

如果需要源代码请私信我

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 实现类内部管理。


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