Files
CapMachine/CapMachine.Wpf/CanDrive/CanDbcModel.cs
2026-03-02 11:20:08 +08:00

165 lines
6.4 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CapMachine.Wpf.CanDrive
{
/// <summary>
/// Dbc 信息
/// </summary>
public class CanDbcModel : BindableBase
{
/// <summary>
/// 消息Id
/// </summary>
public string? MsgId { get; set; }
/// <summary>
/// 配置的中文名称:速度,转速限制,使能等常用的信息数据
/// 但不是所有的SignalName都会配置一个Name只是需要时才会配置名称
/// 但是CanDbcModel集合会包括所有的SignalName名称的
/// </summary>
private string? _name;
/// <summary>
/// 配置的中文名称:速度,转速限制,使能等常用的信息数据
/// 但不是所有的SignalName都会配置一个Name只是需要时才会配置名称
/// 但是CanDbcModel集合会包括所有的SignalName名称的
/// </summary>
public string? Name
{
get { return _name; }
set
{
if (_name != value)
{
_name = value;
RaisePropertyChanged();
}
}
}
/// <summary>
/// 消息名称
/// </summary>
public string? MsgName { get; set; }
/// <summary>
/// 信号名称
/// </summary>
public string? SignalName { get; set; }
/// <summary>
/// 信号描述
/// </summary>
public string? SignalDesc { get; set; }
/// <summary>
/// 信号单位
/// </summary>
public string? SignalUnit { get; set; }
private string? _SignalRtValue = "--";
/// <summary>
/// 信号实时值(供 UI 绑定显示)。
/// </summary>
/// <remarks>
/// - 仅当文本发生变化时才触发通知,避免无谓 UI 刷新。
/// - 若期望进一步降低分配开销,建议在调用方(接收循环)先做“数值层去重”,
/// 即:仅在数值变化(可设置容差)时才调用 ToString() 格式化并赋值到本属性。
/// 这样可以显著减少字符串分配与 GC 压力。
/// </remarks>
/// <example>
/// // 示例:数值层去重后再格式化(接收循环中使用)
/// // if (Math.Abs(newVal - lastVal) > 1e-3) { model.SignalRtValue = newVal.ToString("F3"); lastVal = newVal; }
/// </example>
public string? SignalRtValue
{
get { return _SignalRtValue; }
set
{
if (_SignalRtValue != value)
{
_SignalRtValue = value;
RaisePropertyChanged();
}
}
}
private StringBuilder _SignalRtValueSb = new StringBuilder(16);
/// <summary>
/// 信号实时值的可变文本缓冲接口。
/// 设计目的:
/// - 避免外部传入的 StringBuilder 被直接保存(引用别名问题),统一复制文本到内部缓冲 _SignalRtValueSb
/// - 仅当文本内容变化时才更新 SignalRtValue 并 RaisePropertyChanged减少 UI 抖动与无谓刷新;
/// - 对 value == null 做防御:清空内部缓冲并置空显示文本(如需显示 “--” 可按需替换)。
/// 使用方式:
/// - 接收环路可重复复用同一个外部 StringBuilder 作为临时缓存,调用本属性进行更新不会产生实例共享风险。
/// </summary>
/// <remarks>
/// 注意事项:
/// 1) 本属性会复制文本,不会保存外部 StringBuilder 引用;这可避免多个模型共享同一实例导致的数据串扰和并发问题。
/// 2) 若你的 UI 需要统一的“空值占位符”,可将 setter 中的空字符串替换为 "--",与字段初始值保持一致。
/// 3) 线程模型:建议仍在 UI 线程更新以避免跨线程通知问题如需后台线程更新请确保有合适的调度Dispatcher/同步上下文)。
/// 4) 性能建议:结合 SignalRtValue 的备注,在进入本 setter 前尽量做数值层去重,进一步减少字符串分配。
/// </remarks>
/// <example>
/// // 示例:接收循环中复用临时缓存
/// // var tmp = new StringBuilder(32);
/// // ... 填充 tmp ...
/// // model.SignalRtValueSb = tmp; // 本属性会复制 tmp 的内容,安全且不会产生实例共享
/// </example>
public StringBuilder SignalRtValueSb
{
get { return _SignalRtValueSb; }
set
{
// 防御:若外部传入 null清空内部状态并复位显示文本
// 注意:此处将显示文本设为空字符串 "",如果希望与初始占位符 "--" 一致,可改为 SignalRtValue = "--"。
if (value == null)
{
if (_SignalRtValue != string.Empty)
{
_SignalRtValueSb.Clear();
SignalRtValue = string.Empty;
}
return;
}
// 复制策略:不保存外部 StringBuilder 的引用,改为复制其当前文本内容
// 这样可避免多个模型共享同一 StringBuilder 实例导致的数据串扰与线程安全问题
var str = value.ToString();
// 仅当文本内容确实发生变化时,才更新内部缓冲与绑定属性,减少无谓的 UI 刷新与字符串分配
if (!string.Equals(_SignalRtValue, str, StringComparison.Ordinal))
{
_SignalRtValueSb.Clear();
_SignalRtValueSb.Append(str);
SignalRtValue = str;
}
}
}
private int _IsSeletedInfo;
/// <summary>
/// 被选中的信息
/// 方便标注着色
/// </summary>
public int IsSeletedInfo
{
get { return _IsSeletedInfo; }
set { _IsSeletedInfo = value; RaisePropertyChanged(); }
}
/// <summary>
/// 发布者
/// </summary>
public string? Publisher { get; set; }
}
}