前置

连接概述

连接是由两个点之间创建的。Source和Target依赖属性是Point类型,通常绑定到连接器的Anchor点。

基本连接

库中所有连接的基类是BaseConnection,它派生自Shape。在创建自定义连接时,可以不受任何限值地从BaseConnection派生。

它公开了两个命令及其对应的事件:

  • DisconnectCommand 及 DisconnectEvent - 当按住ALT点击连接时触发
  • SplitCommand 及 SplitEvent - 当双击连接时触发

Nodify 控件支持 Input 和 Output 连接器,您可以通过重写 InputConnectorTemplate 和 OutputConnectorTemplate 的默认模板来自定义这些连接器

Direction 的连接可以有两个值:

  • Forward

  • Backward

和 SourceOffset 与 TargetOffset 锚点一起工作 OffsetMode ,并将与锚点保持距离:

连接也有一个 Spacing ,它将使连接在距 Source 和 Target 点一定距离处断开角度:

  • With spacing: 带间距:

  • Without spacing: 无间距:

设置为 ArrowSize “0,0”将删除箭头。

连接样式

Nodify 自带3个连接器样式

  • Line connection 直线连接

  • Circuit connection 电路连接

  • Connection 贝塞尔曲线连接

Line connection 直线连接

从 Source 到 Target 的直线。

Circuit connection 电路连接

具有 Angle 依赖项属性,用于控制其中断位置。角度以度为单位。

Connection 贝塞尔曲线连接

和 Target 之间的 Source 贝塞尔曲线。

操作

我们先创建一个NotifyPropertyBase类 作为消息通知的基类

public class NotifyPropertyBase : INotifyPropertyChanged 
{ public event PropertyChangedEventHandler PropertyChanged; public void RaisePropertyChanged([CallerMemberName] string propName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
} public void Set<T>(ref T field, T value, Action action = null, [CallerMemberName] string propName = "")
{
if (EqualityComparer<T>.Default.Equals(field, value))
return; field = value;
RaisePropertyChanged(propName);
action?.Invoke();
}
}

然后我们创建连接器类ConnectionViewModel  管理连接源和目标源

public class ConnectionViewModel
{
public ConnectionViewModel(ConnectorViewModel source, ConnectorViewModel target)
{
Source = source;
Target = target; Source.IsConnected = true;
Target.IsConnected = true;
} public ConnectorViewModel Source { get; }
public ConnectorViewModel Target { get; }
}

在EditorViewModel 类添加

public ObservableCollection<ConnectionViewModel> Connections { get; } = new ObservableCollection<ConnectionViewModel>();

调整ConnectorViewModel的属性

    public class ConnectorViewModel: NotifyPropertyBase
{
public string Title { get; set; } private Point _anchor;
public Point Anchor
{
get => _anchor;
set => Set(ref _anchor, value);
} private bool _isConnected;
public bool IsConnected
{
get => _isConnected;
set => Set(ref _isConnected, value);
}
}

在编辑器添加连接器样式

  <nodify:NodifyEditor
x:Name="Editor"
Background="{StaticResource GridDrawingBrush}"
Connections="{Binding Connections}"
ItemsSource="{Binding Nodes}">
<nodify:NodifyEditor.DataContext>
<vm:EditorViewModel />
</nodify:NodifyEditor.DataContext>
<nodify:NodifyEditor.ItemTemplate>
<DataTemplate DataType="{x:Type mod:NodeViewModel}">
<nodify:Node
Header="{Binding Title}"
Input="{Binding Input}"
Output="{Binding Output}">
<nodify:Node.InputConnectorTemplate>
<DataTemplate DataType="{x:Type mod:ConnectorViewModel}">
<nodify:NodeInput
Anchor="{Binding Anchor, Mode=OneWayToSource}"
Header="{Binding Title}"
IsConnected="{Binding IsConnected}" />
</DataTemplate>
</nodify:Node.InputConnectorTemplate> <nodify:Node.OutputConnectorTemplate>
<DataTemplate DataType="{x:Type mod:ConnectorViewModel}">
<nodify:NodeOutput
Anchor="{Binding Anchor, Mode=OneWayToSource}"
Header="{Binding Title}"
IsConnected="{Binding IsConnected}" />
</DataTemplate>
</nodify:Node.OutputConnectorTemplate>
</nodify:Node>
</DataTemplate>
</nodify:NodifyEditor.ItemTemplate> <nodify:NodifyEditor.ConnectionTemplate>
<DataTemplate DataType="{x:Type mod:ConnectionViewModel}">
<nodify:Connection
Source="{Binding Source.Anchor}"
SourceOffsetMode="Rectangle"
Target="{Binding Target.Anchor}"
TargetOffsetMode="Rectangle" />
</DataTemplate>
</nodify:NodifyEditor.ConnectionTemplate>
</nodify:NodifyEditor>

然后添加一个新的节点看看 连接效果 这里我用了的

Connection连接样式
public class EditorViewModel
{
public ObservableCollection<NodeViewModel> Nodes { get; } = new ObservableCollection<NodeViewModel>();
public ObservableCollection<ConnectionViewModel> Connections { get; } = new ObservableCollection<ConnectionViewModel>();
public EditorViewModel()
{
var welcome = new NodeViewModel
{
Title = "我的第一个节点",
Input = new ObservableCollection<ConnectorViewModel>
{
new ConnectorViewModel
{
Title = "输入"
}
},
Output = new ObservableCollection<ConnectorViewModel>
{
new ConnectorViewModel
{
Title = "输出"
}
}
}; var nodify = new NodeViewModel
{
Title = "To Nodify",
Input = new ObservableCollection<ConnectorViewModel>
{
new ConnectorViewModel
{
Title = "In"
}
}
};
Nodes.Add(welcome);
Nodes.Add(nodify); Connections.Add(new ConnectionViewModel(welcome.Output[0], nodify.Input[0])); }
}

源码

github:zt199510/NodifySamples (github.com)

Nodify学习 三:连接器的更多相关文章

  1. HTTP学习三:HTTPS

    HTTP学习三:HTTPS 1 HTTP安全问题 HTTP1.0/1.1在网络中是明文传输的,因此会被黑客进行攻击. 1.1 窃取数据 因为HTTP1.0/1.1是明文的,黑客很容易获得用户的重要数据 ...

  2. TweenMax动画库学习(三)

    目录               TweenMax动画库学习(一)            TweenMax动画库学习(二)            TweenMax动画库学习(三)           ...

  3. Struts2框架学习(三) 数据处理

    Struts2框架学习(三) 数据处理 Struts2框架框架使用OGNL语言和值栈技术实现数据的流转处理. 值栈就相当于一个容器,用来存放数据,而OGNL是一种快速查询数据的语言. 值栈:Value ...

  4. 4.机器学习——统计学习三要素与最大似然估计、最大后验概率估计及L1、L2正则化

    1.前言 之前我一直对于“最大似然估计”犯迷糊,今天在看了陶轻松.忆臻.nebulaf91等人的博客以及李航老师的<统计学习方法>后,豁然开朗,于是在此记下一些心得体会. “最大似然估计” ...

  5. DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件   本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...

  6. [ZZ] 深度学习三巨头之一来清华演讲了,你只需要知道这7点

    深度学习三巨头之一来清华演讲了,你只需要知道这7点 http://wemedia.ifeng.com/10939074/wemedia.shtml Yann LeCun还提到了一项FAIR开发的,用于 ...

  7. SVG 学习<三>渐变

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  8. Android JNI学习(三)——Java与Native相互调用

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  9. day91 DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件   本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...

  10. Django基础学习三_路由系统

    今天主要来学习一下Django的路由系统,视频中只学了一些皮毛,但是也做下总结,主要分为静态路由.动态路由.二级路由 一.先来看下静态路由 1.需要在project中的urls文件中做配置,然后将匹配 ...

随机推荐

  1. 【一步步开发AI运动小程序】十八、如何识别用户上传图片中的人体、运动、动作、姿态?

    [云智AI运动识别小程序插件],可以为您的小程序,赋于人体检测识别.运动检测识别.姿态识别检测AI能力.本地原生识别引擎,内置10余个运动,无需依赖任何后台或第三方服务,有着识别速度快.体验佳.扩展性 ...

  2. Linux下二维码识别库Zbar的安装与使用

    1. 安装Zbar sudo apt-get install libzbar-dev 2. 识别流程 读取图像并转换为Zbar内建图像类型 创建Zbar扫描器 设置扫描参数 扫描图像并获取结果 #in ...

  3. 玩转AI工作流:一步步搭建灵活的自动化流程

    我们之前搭建了许多不同类型的智能体,其中最受欢迎的就是在智能体中搭建各种工作流--这也是我最喜欢探索和玩的领域.那么,究竟什么是工作流?如何在后端实现一个工作流呢?今天我们就先简单了解下. 什么是工作 ...

  4. golang配置读取值viper

    viper简介 Viper是Go应用程序的完整配置解决方案,包括12-Factor应用程序.它旨在在应用程序中工作,并且可以处理所有类型的配置需求和格式.它支持: 设置默认值 从JSON.TOML.Y ...

  5. Python之pandas操作

    中文网:https://www.pypandas.cn/ Pandas 是 Python 的核心数据分析支持库,提供了快速.灵活.明确的数据结构,旨在简单.直观地处理关系型.标记型数据.Pandas ...

  6. Java设计模式——适配器模式的精妙应用:探秘 JDK 源码中的 Set 类

    在 Java 编程的世界里,JDK 源码犹如一座神秘的宝藏,其中的 Set 类更是我们日常开发中频繁使用的利器.今天,就让我们像勇敢的探险家一样,深入 JDK 源码,揭开 Set 类的神秘面纱,重点剖 ...

  7. canvas(七)绘制网格和坐标轴

    1.绘制网格 传入dom和分割线间隔进行渲染,网格线分为水平方向和垂直方向 <script> //绘制网格 function drwaGrid(dom = document.querySe ...

  8. Epicor 10 SaaS云登录

    随着云计算的普及,几乎所有的软件都可以云化了,但事实上,并没有.尤其是在管理软件领域起步较早的 ERP 似乎在云化的道路上一直步履蹒跚. 随着公共云的成熟,人们的观念已经改变.云计算和 SaaS 提供 ...

  9. JDK 18 及以上使用标准输出流中文输出乱码问题

    著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 链接:https://stazxr.cn/2024/12/05/JDK-18-以上使用标准输出流中文输出乱码问题/ 来源:終わり ...

  10. 时代新宠儿——HEIF图像格式:节省50%空间

    HEIF全称High Efficiency Image File Format(高效图像文件格式),是一种高效的图片封装格式,文件名通常为.heif或者.heic后缀.HEIF能够在保持画质不变的前提 ...