[Winform] 绘制网络拓扑关系图

放出效果图

 

一、布局结构
1. 采用行列式网格布局,行与行之间、列与列之间均设有线槽。
2. 设备必须放置在白色插槽上。
3. 设备间连线必须经过线槽。
4. 行列无限扩展:允许用户动态增加行列数量(初始 10×10)。
5. 初始每行/列间隔默认包含 4 条线槽;连线需求增加时,自动生成新线槽;无用时自动移除冗余线槽。

二、基础绘图组件
1. 设备插槽
  1. 白色网格节点,用于固定设备位置。
  2. 设备必须放置在插槽上,不可直接置于线槽或空白区域。
2. 线槽
  1. 位于行与行、列与列之间的通道,专用于布线。
  2. 连线必须沿行/列线槽路径连接设备,不可跨槽直连。
3. 设备
  1. 每个设备包含多协议端口(如协议A、协议B等)。
  2. 连接规则:
    1. 仅支持相同协议的端口互连(例如:设备1的协议A端口 → 设备2的协议A端口)。
    2. 能否实际连接需通过协议兼容性算法验证。
4. 连线
  1. 用于连接不同设备的端口,需严格经过线槽。
  2. 系统自动选择未被占用的线槽进行连接。
  3. 若无可用路径,则自动新增线槽并完成连线。
三、基础绘图元素类体系
1. 抽象基类 GraphicElement
  所有绘图元素的基类,包含以下通用属性:
  1. 几何属性:布局位置、尺寸、位移偏移量。
  2. 样式属性:背景色、外边距、字体、字体样式、透明度。
  3. 状态属性:可见性、鼠标悬浮、选中、超过是否裁剪。
  4. 层级关系:父元素、子元素集合、渲染层级。
2. 具体元素类
2.1 箱型元素BoxGraphicElement
    继承自GraphicElement,特有属性:
    1. 内边距
    2. 边框样式(大小、颜色、虚线/实线)
2.2 线型元素LineGraphicElement
    继承自GraphicElement,特有属性:
    1. 起点/终点坐标。
    2. 线宽/颜色/样式
2.3 文本元素LabelGraphicElement
    继承自BoxGraphicElement,特有属性:
    1. 文本内容
    2. 对齐方式
    3. 自动换行
    4. 文本超出裁剪方式
2.4 图像元素ImageGraphicElement
    继承自BoxGraphicElement,特有属性:
    1. 图像源
2.5 矢量路径元素PathGraphicElement
    继承自GraphicElement,特有属性:
    1. 路径数据
    2. 填充色
    3. 描边属性(大小、颜色、虚线/实线)
    4. 定位模式(绝对定位/相对定位、缩放模式)
2.6 流式布局元素StackPanelGraphicElement
    继承自BoxGraphicElement,特有属性:
    1. 布局方向:水平/垂直
    2. 是否反向布局
2.7 Dock布局元素DockPanelGraphicElement
    继承自BoxGraphicElement
3. 关键设计说明
  1. 样式继承:
    1. 所有可视化元素共享基类的通用样式属性
    2. 特殊样式(如边框、路径)由具体子类扩展
  2. 层级管理:
    1. 通过Parent/Children实现复合图形
    2. ZIndex控制渲染顺序
  3. 布局系统:
    1. StackPanel实现流式布局
    2. DockPanel实现堆叠布局
    3. 可扩展其他布局元素
  4. 状态管理:统一的状态属性(IsMouseHover/IsSelected等)便于交互控制
四、状态属性管理系统
1. 状态属性定义
  采用多状态样式管理机制,支持以下状态属性:
  1. 基础状态:默认背景色(BackgroundBrush)、边框颜色(BorderBrush)等
  2. 交互状态:
    1. 鼠标悬停状态
    2. 选中状态
    3. 自定义状态:通过继承扩展其他状态(如Capture、Connected等)
  3. 复合状态:如鼠标悬停且已连接状态
2. 优先级管理:匹配不同状态的属性,默认选中状态优先鼠标悬停状态,子类可重写优先级
3. 变更通知机制:
  1. 实现INotifyPropertyChanged接口,状态变更时自动触发属性变更事件
  2. 若属性影响渲染,自动触发延迟渲染
请参考GraphicElement的BackgroundBrush
五、核心交互功能说明
1. 设备添加:
  1. 双击添加:在右侧设备树双击设备节点,自动添加到画布中
  2. 拖拽放置:从设备树拖拽设备节点至画布指定坐标释放
2. 连线创建:
  1. 点击源设备的通信端口
  2. 拖拽至目标设备端口释放
  3. 系统自动沿最近线槽路径生成连接线
3. 连线调整:
  1. 拖动连线端点可更换连接的设备端口
  2. 系统实时更新连线路径并保持线槽约束
4. 设备移动:
  1. 拖动画布上设备至其他白色网络节点
  2. 关联连线自动跟随设备位置变化
  3. 保持所有连线符合线槽布线规范
5. 元素删除:
  1. 设备删除:移除设备时自动删除所有关联连线
  2. 连线删除:支持单独删除指定连接线
  3. 提供删除确认机制防止误操作
六、高级交互功能说明
1. 批量操作管理
  1. 选择模式:
    1. 框选:鼠标拖拽矩形区域选择元素
    2. 多选:Ctrl+点击实现离散选择
    3. 全选:Ctrl+A快捷操作
    4. 反选:Ctrl+点击(或框选)切换选择状态
  2. 批量处理:
    1. 支持对选中元素集进行统一删除/复制操作
    2. 粘贴时自动应用智能排列算法
2. 视图控制
  1. 平移控制:
    1. 鼠标滚轮纵向滚动
    2. 拖拽滚动条自由定位
    3. 空格键+拖拽实现画布平移
  2. 缩放控制:
    1. 工具栏按钮调节(显示当前缩放比例)
    2. Ctrl+滚轮动态缩放(以光标位置为视觉中心)
3. 操作历史管理(撤销/重做)
  1. 完整记录核心操作与批量操作
  2. 支持工具栏按钮与快捷键操作:
    1. 撤销:Ctrl+Z
    2. 重做:Ctrl+Y
4. 数据持久化
  1. 项目存储:
    1. XML格式保存拓扑数据
    2. 完整记录设备属性、连接关系及布局坐标
  2. 项目加载:
    1. 自动重建拓扑结构
    2. 动态扩展画布容纳所有元素
    3. 保持原始布局精度
5. 图像导出功能
  1. 智能区域捕获:自动计算设备与连线的最小包围矩形
  2. 图片生成:可选PNG/JPEG等格式
  3. PNG格式不包含背景网格线
6. 智能排列
  1. 自动排列:
    1. 基于设备类型的关系分析算法
    2. 一键优化布局(工具栏按钮触发)
    3. 粘贴操作时自动使用智能排列
  2. 排列策略:
    1. 层级结构构建:
      1. 根节点确定:
        1. 优先选择主站设备作为布局基准
        2. 无主站时自动选择首个从站设备
      2. 子节点组织:按通信协议类型排序(ETHERCAT→MODBUS→CAN等)
    2. 空间计算与分配:
      1. 递归计算每个子树所需空间(行×列)
      2. 从画布左上角开始寻找合适起始位置
      3. 空间不足时自动扩展画布区域
    3. 迭代布局方法:
      1. 对每个子树递归应用相同布局算法
      2. 保证每个子树不重叠
7. 渲染优化
  1. 虚拟画布:
    1. 动态计算可视区域
    2. 仅渲染可见元素
  2. 实时更新:
    1. 坐标变换时重算可见集合
    2. 视口变更时触发增量渲染
  3. 性能保障:
    1. 支持百级元素流畅操作,若不进行缩放等触发重新测量操作,千级元素可流程操作
    2. 内存占用低,渲染1280个设备仅占1400MB
七、连线算法
1. 连线基本规则
  1. 严格遵循"设备端口→线槽→设备端口"的连接路径
  2. 从源端口底部引出,目标端口底部接入
  3. 单一线槽同一线段仅允许一条连线通过
  4. 无可用通道时动态创建新线槽
2. 核心算法流程
  1. 路径规划阶段
    1. 端点分析:
      1. 确定起点(上方端口)和终点(下方端口)坐标
      2. 计算最小包围矩形确定布线区域
    2. 线槽扫描:
      1. 识别起点至终点间的所有水平/垂直线槽
      2. 识别布线区域内经过的连线,方便判断是否重叠
  2. 分层布线算法
    1. 水平通道处理:行优先策略,按行分组,从上至下逐行分析水平线槽
    2. 垂直通道优化:将垂直线槽按与终点距离升序排列,尽量使用最少折点连线
  3. 迭代验证流程:
    1. 水平连线验证:
      1. 按行顺序遍历水平线槽
      2. 对当前行:
        1. 计算与所有垂直线槽的交点
        2. 将交点与前一连接点连成水平线段
        3. 检测该水平线段是否与现有连线重叠
      3. 若当前行所有交点均导致重叠:
        1. 在下方新增水平线槽
        2. 从新线槽重新开始验证
    2. 垂直连线验证:
      1. 对通过水平验证的交点:
        1. 连接该点与下一行同列位置形成垂直线段
        2. 检测该垂直线段是否与现有连线重叠
        3. 将上一列与该行、上一行的交点连成垂直线段
        4. 检测该垂直线槽是否与现有连线重叠
      2. 若当前垂直线槽导致重叠:
        1. 尝试下一可用垂直线槽
        2. 若所有垂直线槽均不可用:在交点所在列新增垂直线槽
    3. 最终连接:
      1. 重复上述步骤直至最后一行
      2. 将最终交点与目标端口连成垂直线段
      3. 完成整条连线路径

八、辅助设计
1. MVVM架构实现
  1. 数据绑定机制:
    1. 控制器统一实现INotifyPropertyChanged接口
    2. 支持多视图同步监听PropertyChanged事件
  2. 关系配置:
    1. 允许视图绑定多个控制器实例
    2. 典型应用场景:画布视图与工具栏视图共享控制器
  3. 架构优势:
    1. 实现数据驱动界面更新
    2. 业务逻辑与界面展示解耦
    3. 减少重复代码,提高可维护性
2. IOC依赖注入
  1. 基于Prism框架集成Unity容器实现依赖注入
  2. 支持插件独立容器与全局共享容器双模式

示例代码:

public UnityBootstrapper(bool setGlobal = false) {
    // 创建IOC容器
    if (setGlobal)
    {
        // 若已经存在全局I0C容器,这里不会覆盖,而是在其基础上维续注册依赖
        ContainerLocator. SetContainerExtension(() => new UnittyContainerExtension())
        _containerExtension = ContainerLocator.Current;
    }
    else
    {
        _containerExtension = new UnityContainerExtension();
    }
    //注册必须依赖
    RegisterRequiredTypes (_containerExtension);
    RegisterTypes (_containerExtension);
}

protected virtual void RegisterTypes(IContainerRegistry containerRegistry) {
    // TODO在此注册你的依赖
}

3. PubSub消息发布订阅
  1. 基于Prism Events构建发布订阅机制
  2. 支持消息状态标记,处理后自动终止传播

示例代码:

// 定义可处理事件
class MyPubSubEvent : PubSubEvent<HandledPubSubEventArgs> { }

// 事件参数,继承HandledPubSubEventArgs则消息可被处理,继承EventArgs就是普通消息
class MyPubSubEventArgs : HandledPubSubEventArgs {
    public object Arg1 { get; }
}

// 定义简单事件,参数是字符串,多个参数可用元组
class SimplePubSubEvent : PubSubEvent<string> { }

class A {
    public A(IEventAggregator eventAggregator){
        // 订阅事件
        eventAggregator.GetEvent<MyPubSubEvent>().Subscribe(HnadleMyPubSubEvent);
    }
}

class B {
    public void Func() {
        // 发布事件
        var args = new MyPubSubEventArgs();
        eventAggregator.GetEvent<MyPubSubEvent>.Publish(args)
    }
}

4. 属性绑定
  1. 绑定模式
    1. 双向绑定(TwoWay):要求源/目标均实现 INotifyPropertyChanged
    2. 单向绑定(OneWay/OneWayToSource):仅需源或目标单边实现接口
  2. 弱引用机制
    1. 源对象事件监听采用弱引用,避免内存泄漏
    2. 自动清理失效引用,确保源对象可被GC回收
  3. 类型转换:支持源/目标属性类型自动适配
  4. 嵌套属性路径:支持 A.B.C 格式绑定子属性
  5. 扩展方法SetBinding() 重载:提供预置参数快速配置绑定
  代码示例:

//撤销重做
undoManager = new UndoManager();
this.SetBinding(undoManager, q => q.CanUndo, (n, v) => n.CanUndo = v) // 单向绑定
this.SetBinding(undoManager, q => q.CanRedo, (n, v) => n.CanRedo = v) // 单向绑定
this.SetBinding(q => q. IsModify, undoManager, q => q.IsModify, (n, v) => n.IsModify = v, (n, v) => n.IsModify = v) // 双向绑定

5. 资源管理系统
5.1 共享资源管理
    1. 实现方式:采用字典结构存储资源,以资源特征作为键,同时维护引用计数
    2. 内存管理:当资源引用次数归零时自动释放
    3. 设计目的:避免重复创建相同资源,有效降低内存占用
5.2 临时资源管理
    1. 实现方式:使用字典结构存储弱引用资源,以资源特征作为键
    2. 内存管理:系统自动回收无引用的临时资源
    3. 设计目的:建立资源缓存机制,减少重复创建,优化内存使用
5.3 专属资源管理
    1. 实现方式:采用对象关联存储结构(ConditionalWeakTable),将资源与宿主对象绑定
    2. 内存管理:当宿主对象被销毁时,自动释放其关联的所有资源
    3. 设计目的:实现资源自动生命周期管理,彻底避免资源泄漏问题

posted @ 2025-07-25 17:26  孤独成派  阅读(22)  评论(0)    收藏  举报