2025-01-01 17:49:48 +08:00
|
|
|
|
using Avalonia;
|
|
|
|
|
|
using Avalonia.Controls;
|
|
|
|
|
|
using Avalonia.Media;
|
|
|
|
|
|
using Avalonia.VisualTree;
|
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
using Serein.Library;
|
|
|
|
|
|
using Serein.Library.Api;
|
|
|
|
|
|
using Serein.Library.Utils;
|
|
|
|
|
|
using Serein.NodeFlow;
|
|
|
|
|
|
using Serein.Workbench.Avalonia.Api;
|
|
|
|
|
|
using Serein.Workbench.Avalonia.Custom.Node.ViewModels;
|
|
|
|
|
|
using Serein.Workbench.Avalonia.Custom.Node.Views;
|
|
|
|
|
|
using Serein.Workbench.Avalonia.Custom.Views;
|
|
|
|
|
|
using Serein.Workbench.Avalonia.Extension;
|
|
|
|
|
|
using Serein.Workbench.Avalonia.Model;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2025-01-04 22:25:42 +08:00
|
|
|
|
using System.Diagnostics;
|
2025-01-01 17:49:48 +08:00
|
|
|
|
using System.Threading;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace Serein.Workbench.Avalonia.Api
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 提供节点操作的接口
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
internal interface INodeOperationService
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 连接数据
|
|
|
|
|
|
/// </summary>
|
2025-01-22 21:09:52 +08:00
|
|
|
|
ConnectingManage ConnectingManage { get; }
|
2025-01-01 17:49:48 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 主画布
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
Canvas MainCanvas { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 节点创建事件
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
|
|
|
|
event NodeViewCreateHandle OnNodeViewCreate;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建节点控件
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="nodeType">控件类型</param>
|
|
|
|
|
|
/// <param name="position">创建坐标</param>
|
|
|
|
|
|
/// <param name="methodDetailsInfo">节点方法信息</param>
|
|
|
|
|
|
public void CreateNodeView(MethodDetailsInfo methodDetailsInfo, PositionOfUI position);
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 尝试从连接控制点创建连接
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="startJunction"></param>
|
|
|
|
|
|
void TryCreateConnectionOnJunction(NodeJunctionView startJunction);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region 事件与事件参数
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建节点控件事件
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="eventArgs"></param>
|
|
|
|
|
|
|
|
|
|
|
|
internal delegate bool NodeViewCreateHandle(NodeViewCreateEventArgs eventArgs);
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建节点控件事件参数
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal class NodeViewCreateEventArgs : EventArgs
|
|
|
|
|
|
{
|
2025-01-04 22:25:42 +08:00
|
|
|
|
internal NodeViewCreateEventArgs(NodeControlBase nodeControl, PositionOfUI position)
|
2025-01-01 17:49:48 +08:00
|
|
|
|
{
|
|
|
|
|
|
this.NodeControl = nodeControl;
|
|
|
|
|
|
this.Position = position;
|
|
|
|
|
|
}
|
2025-01-04 22:25:42 +08:00
|
|
|
|
public NodeControlBase NodeControl { get; private set; }
|
2025-01-01 17:49:48 +08:00
|
|
|
|
public PositionOfUI Position { get; private set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
namespace Serein.Workbench.Avalonia.Services
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 节点操作相关服务
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
internal class NodeOperationService : INodeOperationService
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
public NodeOperationService(IFlowEnvironment flowEnvironment,
|
|
|
|
|
|
IFlowEEForwardingService feefService)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.flowEnvironment = flowEnvironment;
|
|
|
|
|
|
this.feefService = feefService;
|
|
|
|
|
|
feefService.OnNodeCreate += FeefService_OnNodeCreate; // 订阅运行环境创建节点事件
|
2025-01-04 22:25:42 +08:00
|
|
|
|
feefService.OnNodeConnectChange += FeefService_OnNodeConnectChange; // 订阅运行环境连接了节点事件
|
2025-03-18 21:01:15 +08:00
|
|
|
|
flowEnvironment.NodeMVVMManagement.RegisterUI(NodeControlType.Action, typeof(ActionNodeView), typeof(ActionNodeViewModel)); // 注册动作节点
|
2025-01-01 17:49:48 +08:00
|
|
|
|
// 手动加载项目
|
|
|
|
|
|
_ = Task.Run(async delegate
|
|
|
|
|
|
{
|
|
|
|
|
|
await Task.Delay(1000);
|
|
|
|
|
|
var flowEnvironment = App.GetService<IFlowEnvironment>();
|
|
|
|
|
|
var filePath = @"C:\Users\Az\source\repos\CLBanyunqiState\CLBanyunqiState\bin\debug\net8.0\project.dnf";
|
|
|
|
|
|
string content = System.IO.File.ReadAllText(filePath); // 读取整个文件内容
|
|
|
|
|
|
var projectData = JsonConvert.DeserializeObject<SereinProjectData>(content);
|
|
|
|
|
|
var projectDfilePath = System.IO.Path.GetDirectoryName(filePath)!;
|
|
|
|
|
|
flowEnvironment.LoadProject(new FlowEnvInfo { Project = projectData }, projectDfilePath);
|
|
|
|
|
|
}, CancellationToken.None);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-01-04 22:25:42 +08:00
|
|
|
|
#region 接口属性
|
2025-01-22 21:09:52 +08:00
|
|
|
|
public ConnectingManage ConnectingManage { get; private set; } = new ConnectingManage();
|
2025-01-04 22:25:42 +08:00
|
|
|
|
public Canvas MainCanvas { get; set; }
|
2025-01-01 17:49:48 +08:00
|
|
|
|
|
2025-01-04 22:25:42 +08:00
|
|
|
|
#endregion
|
2025-01-01 17:49:48 +08:00
|
|
|
|
|
|
|
|
|
|
#region 私有变量
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 存储所有与节点有关的控件
|
|
|
|
|
|
/// </summary>
|
2025-01-04 22:25:42 +08:00
|
|
|
|
private Dictionary<string, NodeControlBase> NodeControls { get; } = [];
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 存储所有连接
|
|
|
|
|
|
/// </summary>
|
2025-01-22 21:09:52 +08:00
|
|
|
|
private List<NodeConnectionLineControl> Connections { get; } = [];
|
2025-01-01 17:49:48 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 流程运行环境
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private readonly IFlowEnvironment flowEnvironment;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 流程运行环境事件转发
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private readonly IFlowEEForwardingService feefService;
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-01-04 22:25:42 +08:00
|
|
|
|
#region 节点操作事件
|
|
|
|
|
|
|
2025-01-01 17:49:48 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建了节点控件
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public event NodeViewCreateHandle OnNodeViewCreate;
|
|
|
|
|
|
|
2025-01-04 22:25:42 +08:00
|
|
|
|
#endregion
|
2025-01-01 17:49:48 +08:00
|
|
|
|
|
2025-01-04 22:25:42 +08:00
|
|
|
|
#region 转发事件的处理
|
2025-01-01 17:49:48 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 从工作台事件转发器监听节点创建事件
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="eventArgs"></param>
|
|
|
|
|
|
private void FeefService_OnNodeCreate(NodeCreateEventArgs eventArgs)
|
|
|
|
|
|
{
|
|
|
|
|
|
var nodeModel = eventArgs.NodeModel;
|
|
|
|
|
|
if (NodeControls.ContainsKey(nodeModel.Guid))
|
|
|
|
|
|
{
|
|
|
|
|
|
SereinEnv.WriteLine(InfoType.WARN, $"OnNodeCreate 事件意外触发,节点Guid重复 - {nodeModel.Guid}");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-03-18 21:01:15 +08:00
|
|
|
|
if (!flowEnvironment.NodeMVVMManagement.TryGetType(nodeModel.ControlType, out var nodeMVVM))
|
2025-01-01 17:49:48 +08:00
|
|
|
|
{
|
|
|
|
|
|
SereinEnv.WriteLine(InfoType.INFO, $"无法创建{nodeModel.ControlType}节点,节点类型尚未注册。");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (nodeMVVM.ControlType == null
|
|
|
|
|
|
|| nodeMVVM.ViewModelType == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
SereinEnv.WriteLine(InfoType.INFO, $"无法创建{nodeModel.ControlType}节点,UI类型尚未注册(请通过 NodeMVVMManagement.RegisterUI() 方法进行注册)。");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var isSuccessful = TryCreateNodeView(nodeMVVM.ControlType, // 控件UI类型
|
|
|
|
|
|
nodeMVVM.ViewModelType, // 控件VIewModel类型
|
|
|
|
|
|
nodeModel, // 控件数据实体
|
|
|
|
|
|
out var nodeControl); // 成功创建后传出的节点控件实体
|
|
|
|
|
|
if (!isSuccessful || nodeControl is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
SereinEnv.WriteLine(InfoType.INFO, $"无法创建{nodeModel.ControlType}节点,节点创建失败。");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var e = new NodeViewCreateEventArgs(nodeControl, eventArgs.Position);
|
|
|
|
|
|
if (OnNodeViewCreate?.Invoke(e) == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 成功创建
|
|
|
|
|
|
NodeControls.TryAdd(nodeModel.Guid, nodeControl); // 缓存起来,通知其它地方拿取这个控件
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-01-04 22:25:42 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 运行环境连接了节点事件
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="eventArgs"></param>
|
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
|
private void FeefService_OnNodeConnectChange(NodeConnectChangeEventArgs eventArgs)
|
|
|
|
|
|
{
|
|
|
|
|
|
string fromNodeGuid = eventArgs.FromNodeGuid;
|
|
|
|
|
|
string toNodeGuid = eventArgs.ToNodeGuid;
|
|
|
|
|
|
if (!TryGetControl(fromNodeGuid, out var fromNodeControl)
|
|
|
|
|
|
|| !TryGetControl(toNodeGuid, out var toNodeControl))
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-01-22 21:09:52 +08:00
|
|
|
|
|
2025-01-04 22:25:42 +08:00
|
|
|
|
if (eventArgs.JunctionOfConnectionType == JunctionOfConnectionType.Invoke)
|
|
|
|
|
|
{
|
|
|
|
|
|
ConnectionInvokeType connectionType = eventArgs.ConnectionInvokeType;
|
|
|
|
|
|
#region 创建/删除节点之间的调用关系
|
|
|
|
|
|
#region 创建连接
|
|
|
|
|
|
if (eventArgs.ChangeType == NodeConnectChangeEventArgs.ConnectChangeType.Create) // 添加连接
|
|
|
|
|
|
{
|
|
|
|
|
|
if (fromNodeControl is not INodeJunction IFormJunction || toNodeControl is not INodeJunction IToJunction)
|
|
|
|
|
|
{
|
|
|
|
|
|
SereinEnv.WriteLine(InfoType.INFO, "非预期的连接");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
var startJunction = IFormJunction.NextStepJunction;
|
|
|
|
|
|
var endJunction = IToJunction.ExecuteJunction;
|
|
|
|
|
|
|
2025-01-22 21:09:52 +08:00
|
|
|
|
NodeConnectionLineControl nodeConnectionLineControl = new NodeConnectionLineControl(MainCanvas, startJunction, endJunction);
|
|
|
|
|
|
|
|
|
|
|
|
//startJunction.TransformToVisual(MainCanvas);
|
|
|
|
|
|
|
|
|
|
|
|
//// 添加连接
|
|
|
|
|
|
//var shape = new ConnectionLineShape(
|
|
|
|
|
|
// FlowChartCanvas,
|
|
|
|
|
|
// connectionType,
|
|
|
|
|
|
// startJunction,
|
|
|
|
|
|
// endJunction
|
|
|
|
|
|
//);
|
|
|
|
|
|
|
2025-01-04 22:25:42 +08:00
|
|
|
|
|
2025-01-22 21:09:52 +08:00
|
|
|
|
//NodeConnectionLine nodeConnectionLine = new NodeConnectionLine(MainCanvas, shape);
|
2025-01-04 22:25:42 +08:00
|
|
|
|
|
|
|
|
|
|
//if (toNodeControl is FlipflopNodeControl flipflopControl
|
|
|
|
|
|
// && flipflopControl?.ViewModel?.NodeModel is NodeModelBase nodeModel) // 某个节点连接到了触发器,尝试从全局触发器视图中移除该触发器
|
|
|
|
|
|
//{
|
|
|
|
|
|
// NodeTreeViewer.RemoveGlobalFlipFlop(nodeModel); // 从全局触发器树树视图中移除
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
2025-01-22 21:09:52 +08:00
|
|
|
|
Connections.Add(nodeConnectionLineControl);
|
|
|
|
|
|
fromNodeControl.AddConnection(nodeConnectionLineControl);
|
|
|
|
|
|
toNodeControl.AddConnection(nodeConnectionLineControl);
|
2025-01-04 22:25:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
2025-01-22 21:09:52 +08:00
|
|
|
|
|
2025-01-04 22:25:42 +08:00
|
|
|
|
|
|
|
|
|
|
#region 移除连接
|
2025-01-22 21:09:52 +08:00
|
|
|
|
/* else if (eventArgs.ChangeType == NodeConnectChangeEventArgs.ConnectChangeType.Remove) // 移除连接
|
2025-01-04 22:25:42 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 需要移除连接
|
|
|
|
|
|
var removeConnections = Connections.Where(c =>
|
|
|
|
|
|
c.Start.MyNode.Guid.Equals(fromNodeGuid)
|
|
|
|
|
|
&& c.End.MyNode.Guid.Equals(toNodeGuid)
|
|
|
|
|
|
&& (c.Start.JunctionType.ToConnectyionType() == JunctionOfConnectionType.Invoke
|
|
|
|
|
|
|| c.End.JunctionType.ToConnectyionType() == JunctionOfConnectionType.Invoke))
|
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var connection in removeConnections)
|
|
|
|
|
|
{
|
|
|
|
|
|
Connections.Remove(connection);
|
|
|
|
|
|
fromNodeControl.RemoveConnection(connection); // 移除连接
|
|
|
|
|
|
toNodeControl.RemoveConnection(connection); // 移除连接
|
|
|
|
|
|
if (NodeControls.TryGetValue(connection.End.MyNode.Guid, out var control))
|
|
|
|
|
|
{
|
|
|
|
|
|
JudgmentFlipFlopNode(control); // 连接关系变更时判断
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-01-22 21:09:52 +08:00
|
|
|
|
}*/
|
2025-01-04 22:25:42 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-01-22 21:09:52 +08:00
|
|
|
|
|
2025-01-04 22:25:42 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
2025-01-22 21:09:52 +08:00
|
|
|
|
/*else
|
2025-01-04 22:25:42 +08:00
|
|
|
|
{
|
2025-01-22 21:09:52 +08:00
|
|
|
|
|
|
|
|
|
|
ConnectionArgSourceType connectionArgSourceType = eventArgs.ConnectionArgSourceType;
|
2025-01-04 22:25:42 +08:00
|
|
|
|
#region 创建/删除节点之间的参数传递关系
|
|
|
|
|
|
#region 创建连接
|
|
|
|
|
|
if (eventArgs.ChangeType == NodeConnectChangeEventArgs.ConnectChangeType.Create) // 添加连接
|
|
|
|
|
|
{
|
|
|
|
|
|
if (fromNodeControl is not INodeJunction IFormJunction || toNodeControl is not INodeJunction IToJunction)
|
|
|
|
|
|
{
|
|
|
|
|
|
SereinEnv.WriteLine(InfoType.INFO, "非预期的情况");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
JunctionControlBase startJunction = eventArgs.ConnectionArgSourceType switch
|
|
|
|
|
|
{
|
|
|
|
|
|
ConnectionArgSourceType.GetPreviousNodeData => IFormJunction.ReturnDataJunction, // 自身节点
|
|
|
|
|
|
ConnectionArgSourceType.GetOtherNodeData => IFormJunction.ReturnDataJunction, // 其它节点的返回值控制点
|
|
|
|
|
|
ConnectionArgSourceType.GetOtherNodeDataOfInvoke => IFormJunction.ReturnDataJunction, // 其它节点的返回值控制点
|
|
|
|
|
|
_ => throw new Exception("窗体事件 FlowEnvironment_NodeConnectChangeEvemt 创建/删除节点之间的参数传递关系 JunctionControlBase 枚举值错误 。非预期的枚举值。") // 应该不会触发
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (IToJunction.ArgDataJunction.Length <= eventArgs.ArgIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_ = Task.Run(async () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
await Task.Delay(500);
|
|
|
|
|
|
FlowEnvironment_NodeConnectChangeEvemt(eventArgs);
|
|
|
|
|
|
});
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
JunctionControlBase endJunction = IToJunction.ArgDataJunction[eventArgs.ArgIndex];
|
|
|
|
|
|
LineType lineType = LineType.Bezier;
|
|
|
|
|
|
// 添加连接
|
|
|
|
|
|
var connection = new ConnectionControl(
|
|
|
|
|
|
lineType,
|
|
|
|
|
|
FlowChartCanvas,
|
|
|
|
|
|
eventArgs.ArgIndex,
|
|
|
|
|
|
eventArgs.ConnectionArgSourceType,
|
|
|
|
|
|
startJunction,
|
|
|
|
|
|
endJunction,
|
|
|
|
|
|
IToJunction
|
|
|
|
|
|
);
|
|
|
|
|
|
Connections.Add(connection);
|
|
|
|
|
|
fromNodeControl.AddCnnection(connection);
|
|
|
|
|
|
toNodeControl.AddCnnection(connection);
|
|
|
|
|
|
EndConnection(); // 环境触发了创建节点连接事件
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region 移除连接
|
|
|
|
|
|
else if (eventArgs.ChangeType == NodeConnectChangeEventArgs.ConnectChangeType.Remove) // 移除连接
|
|
|
|
|
|
{
|
|
|
|
|
|
// 需要移除连接
|
|
|
|
|
|
var removeConnections = Connections.Where(c => c.Start.MyNode.Guid.Equals(fromNodeGuid)
|
|
|
|
|
|
&& c.End.MyNode.Guid.Equals(toNodeGuid))
|
|
|
|
|
|
.ToList(); // 获取这两个节点之间的所有连接关系
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var connection in removeConnections)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (connection.End is ArgJunctionControl junctionControl && junctionControl.ArgIndex == eventArgs.ArgIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 找到符合删除条件的连接线
|
|
|
|
|
|
Connections.Remove(connection); // 从本地记录中移除
|
|
|
|
|
|
fromNodeControl.RemoveConnection(connection); // 从节点持有的记录移除
|
|
|
|
|
|
toNodeControl.RemoveConnection(connection); // 从节点持有的记录移除
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//if (NodeControls.TryGetValue(connection.End.MyNode.Guid, out var control))
|
|
|
|
|
|
//{
|
|
|
|
|
|
// JudgmentFlipFlopNode(control); // 连接关系变更时判断
|
|
|
|
|
|
//}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#endregion
|
2025-01-22 21:09:52 +08:00
|
|
|
|
|
|
|
|
|
|
} */
|
|
|
|
|
|
|
2025-01-04 22:25:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 私有方法
|
|
|
|
|
|
|
2025-01-01 17:49:48 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建节点控件
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="viewType">节点控件视图控件类型</param>
|
|
|
|
|
|
/// <param name="viewModelType">节点控件ViewModel类型</param>
|
|
|
|
|
|
/// <param name="nodeModel">节点Model实例</param>
|
|
|
|
|
|
/// <param name="nodeView">返回的节点对象</param>
|
|
|
|
|
|
/// <returns>是否创建成功</returns>
|
|
|
|
|
|
/// <exception cref="Exception">无法创建节点控件</exception>
|
2025-01-04 22:25:42 +08:00
|
|
|
|
private bool TryCreateNodeView(Type viewType, Type viewModelType, NodeModelBase nodeModel, out NodeControlBase? nodeView)
|
2025-01-01 17:49:48 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(nodeModel.Guid))
|
|
|
|
|
|
{
|
|
|
|
|
|
nodeModel.Guid = Guid.NewGuid().ToString();
|
|
|
|
|
|
}
|
|
|
|
|
|
var t_ViewModel = Activator.CreateInstance(viewModelType);
|
|
|
|
|
|
if (t_ViewModel is not NodeViewModelBase viewModelBase)
|
|
|
|
|
|
{
|
|
|
|
|
|
nodeView = null;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
viewModelBase.NodeModelBase = nodeModel; // 设置节点对象
|
|
|
|
|
|
var controlObj = Activator.CreateInstance(viewType);
|
2025-01-04 22:25:42 +08:00
|
|
|
|
if (controlObj is NodeControlBase nodeControl)
|
2025-01-01 17:49:48 +08:00
|
|
|
|
{
|
2025-01-04 22:25:42 +08:00
|
|
|
|
nodeControl.DataContext = viewModelBase;
|
|
|
|
|
|
nodeView = nodeControl;
|
|
|
|
|
|
return true;
|
2025-01-01 17:49:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-01-04 22:25:42 +08:00
|
|
|
|
nodeView = null;
|
|
|
|
|
|
return false;
|
2025-01-01 17:49:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 在其它地方验证过了,所以注释
|
|
|
|
|
|
//if ((viewType is null)
|
|
|
|
|
|
// || viewModelType is null
|
|
|
|
|
|
// || nodeModel is null)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// nodeView = null;
|
|
|
|
|
|
// return false;
|
|
|
|
|
|
//}
|
|
|
|
|
|
//if (typeof(INodeControl).IsSubclassOf(viewType)
|
|
|
|
|
|
// || typeof(NodeViewModelBase).IsSubclassOf(viewModelType))
|
|
|
|
|
|
//{
|
|
|
|
|
|
// nodeView = null;
|
|
|
|
|
|
// return false;
|
|
|
|
|
|
//}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-01-04 22:25:42 +08:00
|
|
|
|
private bool TryGetControl(string nodeGuid, out NodeControlBase nodeControl)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(nodeGuid))
|
|
|
|
|
|
{
|
|
|
|
|
|
nodeControl = null;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!NodeControls.TryGetValue(nodeGuid, out nodeControl))
|
|
|
|
|
|
{
|
|
|
|
|
|
nodeControl = null;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (nodeControl is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 操作接口对外暴露的接口
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建节点控件
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="nodeType">控件类型</param>
|
|
|
|
|
|
/// <param name="position">创建坐标</param>
|
|
|
|
|
|
/// <param name="methodDetailsInfo">节点方法信息(基础节点传null)</param>
|
|
|
|
|
|
public void CreateNodeView(MethodDetailsInfo methodDetailsInfo, PositionOfUI position)
|
|
|
|
|
|
{
|
|
|
|
|
|
Task.Run(async () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (EnumHelper.TryConvertEnum<NodeControlType>(methodDetailsInfo.NodeType, out var nodeType))
|
|
|
|
|
|
{
|
|
|
|
|
|
await flowEnvironment.CreateNodeAsync(nodeType, position, methodDetailsInfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-01-01 17:49:48 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 尝试在连接控制点之间创建连接线
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void TryCreateConnectionOnJunction(NodeJunctionView startJunction)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (MainCanvas is not null)
|
|
|
|
|
|
{
|
2025-01-22 21:09:52 +08:00
|
|
|
|
ConnectingManage.Reset();
|
|
|
|
|
|
ConnectingManage.IsCreateing = true; // 表示开始连接
|
|
|
|
|
|
ConnectingManage.StartJunction = startJunction;
|
|
|
|
|
|
ConnectingManage.CurrentJunction = startJunction;
|
2025-01-04 22:25:42 +08:00
|
|
|
|
if(startJunction.JunctionType == JunctionType.NextStep || startJunction.JunctionType == JunctionType.ReturnData)
|
2025-01-01 17:49:48 +08:00
|
|
|
|
{
|
2025-01-04 22:25:42 +08:00
|
|
|
|
|
2025-01-22 21:09:52 +08:00
|
|
|
|
ConnectingManage.TempLine = new NodeConnectionLineControl(MainCanvas, startJunction, null);
|
2025-01-01 17:49:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-01-22 21:09:52 +08:00
|
|
|
|
ConnectingManage.TempLine = new NodeConnectionLineControl(MainCanvas,null ,startJunction);
|
2025-01-01 17:49:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-01-04 22:25:42 +08:00
|
|
|
|
/*var junctionOfConnectionType = startJunction.JunctionType.ToConnectyionType();
|
|
|
|
|
|
ConnectionLineShape bezierLine;
|
2025-01-01 17:49:48 +08:00
|
|
|
|
Brush brushColor; // 临时线的颜色
|
|
|
|
|
|
if (junctionOfConnectionType == JunctionOfConnectionType.Invoke)
|
|
|
|
|
|
{
|
|
|
|
|
|
brushColor = ConnectionInvokeType.IsSucceed.ToLineColor();
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (junctionOfConnectionType == JunctionOfConnectionType.Arg)
|
|
|
|
|
|
{
|
|
|
|
|
|
brushColor = ConnectionArgSourceType.GetOtherNodeData.ToLineColor();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
bezierLine = new ConnectionLineShape(myData.StartPoint,
|
|
|
|
|
|
myData.StartPoint,
|
|
|
|
|
|
brushColor,
|
|
|
|
|
|
isTop: true); // 绘制临时的线
|
2025-01-04 22:25:42 +08:00
|
|
|
|
*/
|
2025-01-01 17:49:48 +08:00
|
|
|
|
//Mouse.OverrideCursor = Cursors.Cross; // 设置鼠标为正在创建连线
|
2025-01-04 22:25:42 +08:00
|
|
|
|
|
2025-01-01 17:49:48 +08:00
|
|
|
|
}
|
2025-01-04 22:25:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
2025-01-01 17:49:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|