mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-18 05:46:35 +08:00
Workbench项目中,优化了节点的复制、粘贴,加载。
This commit is contained in:
@@ -28,7 +28,26 @@ namespace Serein.Library
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract partial class NodeModelBase : IDynamicFlowNode
|
public abstract partial class NodeModelBase : IDynamicFlowNode
|
||||||
{
|
{
|
||||||
#region 节点移除相关
|
#region 节点相关事件
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存自定义信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual NodeInfo SaveCustomData(NodeInfo nodeInfo)
|
||||||
|
{
|
||||||
|
return nodeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加载自定义数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nodeInfo"></param>
|
||||||
|
public virtual void LoadCustomData(NodeInfo nodeInfo)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 移除该节点
|
/// 移除该节点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -36,16 +55,52 @@ namespace Serein.Library
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 移除该节点
|
||||||
|
/// </summary>
|
||||||
|
public virtual void RemoveFromEnv()
|
||||||
|
{
|
||||||
|
if (this.DebugSetting.CancelInterruptCallback != null)
|
||||||
|
{
|
||||||
|
this.DebugSetting.CancelInterruptCallback?.Invoke();
|
||||||
|
}
|
||||||
|
this.DebugSetting.GetInterruptTask = null;
|
||||||
|
this.DebugSetting.NodeModel = null;
|
||||||
|
this.DebugSetting.CancelInterruptCallback = null;
|
||||||
|
this.DebugSetting = null;
|
||||||
|
foreach (var pd in this.MethodDetails.ParameterDetailss)
|
||||||
|
{
|
||||||
|
pd.DataValue = null;
|
||||||
|
pd.Items = null;
|
||||||
|
pd.NodeModel = null;
|
||||||
|
pd.ExplicitType = null;
|
||||||
|
pd.DataType = null;
|
||||||
|
pd.Name = null;
|
||||||
|
pd.ArgDataSourceNodeGuid = null;
|
||||||
|
pd.ExplicitTypeName = null;
|
||||||
|
}
|
||||||
|
this.MethodDetails.ParameterDetailss = null;
|
||||||
|
this.MethodDetails.ActingInstance = null;
|
||||||
|
this.MethodDetails.NodeModel = null;
|
||||||
|
this.MethodDetails.ReturnType = null;
|
||||||
|
this.MethodDetails.AssemblyName = null;
|
||||||
|
this.MethodDetails.MethodAnotherName = null;
|
||||||
|
this.MethodDetails.MethodLockName = null;
|
||||||
|
this.MethodDetails.MethodName = null;
|
||||||
|
this.MethodDetails.ActingInstanceType = null;
|
||||||
|
this.MethodDetails = null;
|
||||||
|
this.Position = null;
|
||||||
|
this.DisplayName = null;
|
||||||
|
|
||||||
#endregion
|
this.Env = null;
|
||||||
|
}
|
||||||
|
|
||||||
#region 导出/导入项目文件节点信息
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 输出方法参数信息
|
/// 输出方法参数信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual ParameterData[] SaveParameterInfo()
|
public ParameterData[] SaveParameterInfo()
|
||||||
{
|
{
|
||||||
if(MethodDetails.ParameterDetailss == null)
|
if(MethodDetails.ParameterDetailss == null)
|
||||||
{
|
{
|
||||||
@@ -69,20 +124,13 @@ namespace Serein.Library
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 保存自定义信息
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public virtual NodeInfo SaveCustomData(NodeInfo nodeInfo)
|
|
||||||
{
|
|
||||||
return nodeInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 导出为节点信息
|
/// 导出为节点信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual NodeInfo ToInfo()
|
public NodeInfo ToInfo()
|
||||||
{
|
{
|
||||||
// if (MethodDetails == null) return null;
|
// if (MethodDetails == null) return null;
|
||||||
|
|
||||||
@@ -110,25 +158,20 @@ namespace Serein.Library
|
|||||||
IsInterrupt = this.DebugSetting.IsInterrupt,
|
IsInterrupt = this.DebugSetting.IsInterrupt,
|
||||||
IsEnable = this.DebugSetting.IsEnable,
|
IsEnable = this.DebugSetting.IsEnable,
|
||||||
};
|
};
|
||||||
|
nodeInfo.Position.X = Math.Round(nodeInfo.Position.X, 1);
|
||||||
|
nodeInfo.Position.Y = Math.Round(nodeInfo.Position.Y, 1);
|
||||||
nodeInfo = SaveCustomData(nodeInfo);
|
nodeInfo = SaveCustomData(nodeInfo);
|
||||||
return nodeInfo;
|
return nodeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 加载自定义数据
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="nodeInfo"></param>
|
|
||||||
public virtual void LoadCustomData(NodeInfo nodeInfo)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 从节点信息加载节点
|
/// 从节点信息加载节点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="nodeInfo"></param>
|
/// <param name="nodeInfo"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual void LoadInfo(NodeInfo nodeInfo)
|
public void LoadInfo(NodeInfo nodeInfo)
|
||||||
{
|
{
|
||||||
this.Guid = nodeInfo.Guid;
|
this.Guid = nodeInfo.Guid;
|
||||||
this.Position = nodeInfo.Position ?? new PositionOfUI(0, 0);// 加载位置信息
|
this.Position = nodeInfo.Position ?? new PositionOfUI(0, 0);// 加载位置信息
|
||||||
@@ -520,33 +563,33 @@ namespace Serein.Library
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 入参存在取值转换器,调用对应的转换器获取入参数据,如果获取成功(不为null)会跳过循环
|
//#region 入参存在取值转换器,调用对应的转换器获取入参数据,如果获取成功(不为null)会跳过循环
|
||||||
if (pd.ExplicitType.IsEnum && !(pd.Convertor is null))
|
//if (pd.ExplicitType.IsEnum && !(pd.Convertor is null))
|
||||||
{
|
//{
|
||||||
//var resultEnum = Enum.ToObject(ed.ExplicitType, ed.DataValue);
|
// //var resultEnum = Enum.ToObject(ed.ExplicitType, ed.DataValue);
|
||||||
var resultEnum = Enum.Parse(pd.ExplicitType, pd.DataValue);
|
// var resultEnum = Enum.Parse(pd.ExplicitType, pd.DataValue);
|
||||||
var value = pd.Convertor(resultEnum);
|
// var value = pd.Convertor(resultEnum);
|
||||||
if (value is null)
|
// if (value is null)
|
||||||
{
|
// {
|
||||||
throw new InvalidOperationException("转换器调用失败");
|
// throw new InvalidOperationException("转换器调用失败");
|
||||||
|
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
if (hasParams)
|
// if (hasParams)
|
||||||
{
|
// {
|
||||||
paramsArgs.SetValue(value, paramsArgIndex++);
|
// paramsArgs.SetValue(value, paramsArgIndex++);
|
||||||
// 处理可选参数
|
// // 处理可选参数
|
||||||
//paramsArgs[paramsArgIndex++] = value;
|
// //paramsArgs[paramsArgIndex++] = value;
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
parameters[i] = value;
|
// parameters[i] = value;
|
||||||
}
|
// }
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
#endregion
|
//#endregion
|
||||||
|
|
||||||
#region 入参存在基于BinValue的类型转换器,获取枚举转换器中记录的类型,如果获取成功(不为null)会跳过循环
|
#region 入参存在基于BinValue的类型转换器,获取枚举转换器中记录的类型,如果获取成功(不为null)会跳过循环
|
||||||
// 入参存在基于BinValue的类型转换器,获取枚举转换器中记录的类型
|
// 入参存在基于BinValue的类型转换器,获取枚举转换器中记录的类型
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ namespace Serein.Library
|
|||||||
[PropertyInfo(IsNotification = true)]
|
[PropertyInfo(IsNotification = true)]
|
||||||
private bool _isExplicitData ;
|
private bool _isExplicitData ;
|
||||||
|
|
||||||
/// <summary>
|
///// <summary>
|
||||||
/// 转换器 IEnumConvertor<,>
|
///// 转换器 IEnumConvertor<,>
|
||||||
/// </summary>
|
///// </summary>
|
||||||
[PropertyInfo]
|
//[PropertyInfo]
|
||||||
private Func<object, object> _convertor ;
|
//private Func<object, object> _convertor ;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 方法入参若无相关转换器特性标注,则无需关注该变量。该变量用于需要用到枚举BinValue转换器时,指示相应的入参变量需要转为的类型。
|
/// 方法入参若无相关转换器特性标注,则无需关注该变量。该变量用于需要用到枚举BinValue转换器时,指示相应的入参变量需要转为的类型。
|
||||||
@@ -167,7 +167,7 @@ namespace Serein.Library
|
|||||||
IsExplicitData = this.IsExplicitData,
|
IsExplicitData = this.IsExplicitData,
|
||||||
ExplicitType = this.ExplicitType,
|
ExplicitType = this.ExplicitType,
|
||||||
ExplicitTypeName = this.ExplicitTypeName,
|
ExplicitTypeName = this.ExplicitTypeName,
|
||||||
Convertor = this.Convertor,
|
//Convertor = this.Convertor,
|
||||||
DataType = this.DataType,
|
DataType = this.DataType,
|
||||||
Name = this.Name,
|
Name = this.Name,
|
||||||
DataValue = string.IsNullOrEmpty(DataValue) ? string.Empty : DataValue,
|
DataValue = string.IsNullOrEmpty(DataValue) ? string.Empty : DataValue,
|
||||||
@@ -180,14 +180,6 @@ namespace Serein.Library
|
|||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
if(_convertor is null)
|
|
||||||
{
|
|
||||||
return $"[{this.Index}] {this.Name} : {this.DataType?.FullName}";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
return $"[{this.Index}] {this.Name} : {this.ExplicitType.FullName} -> {this.DataType.FullName}";
|
return $"[{this.Index}] {this.Name} : {this.ExplicitType.FullName} -> {this.DataType.FullName}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -918,7 +918,7 @@ namespace Serein.NodeFlow.Env
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 加载方法节点
|
// 加载方法节点
|
||||||
if (string.IsNullOrEmpty(nodeInfo.AssemblyName) && string.IsNullOrEmpty(nodeInfo.MethodName))
|
if (string.IsNullOrEmpty(nodeInfo.MethodName))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ namespace Serein.NodeFlow.Model
|
|||||||
ArgDataSourceNodeGuid = string.Empty,
|
ArgDataSourceNodeGuid = string.Empty,
|
||||||
ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData,
|
ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData,
|
||||||
NodeModel = this,
|
NodeModel = this,
|
||||||
Convertor = null,
|
//Convertor = null,
|
||||||
ExplicitTypeName = "Value",
|
ExplicitTypeName = "Value",
|
||||||
Items = null,
|
Items = null,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ namespace Serein.NodeFlow.Model
|
|||||||
ArgDataSourceNodeGuid = string.Empty,
|
ArgDataSourceNodeGuid = string.Empty,
|
||||||
ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData,
|
ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData,
|
||||||
NodeModel = this,
|
NodeModel = this,
|
||||||
Convertor = null,
|
//Convertor = null,
|
||||||
ExplicitTypeName = "Value",
|
ExplicitTypeName = "Value",
|
||||||
Items = null,
|
Items = null,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -215,13 +215,14 @@ public static class NodeMethodDetailsHelper
|
|||||||
ConvertorInstance[key] = (instance, convertMethod);
|
ConvertorInstance[key] = (instance, convertMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
object func(object enumValue)
|
//object func(object enumValue)
|
||||||
{
|
//{
|
||||||
(var obj, var methodInfo) = ConvertorInstance[key];
|
// (var obj, var methodInfo) = ConvertorInstance[key];
|
||||||
return methodInfo?.Invoke(obj, [enumValue]);
|
// return methodInfo?.Invoke(obj, [enumValue]);
|
||||||
}
|
//}
|
||||||
|
|
||||||
// 确保实例实现了所需接口
|
// 确保实例实现了所需接口
|
||||||
ParameterDetails ed = GetExplicitDataOfParameter(it, index, paremType, true, func); // 自定义的转换器 获取参数
|
ParameterDetails ed = GetExplicitDataOfParameter(it, index, paremType, true); // 自定义的转换器 获取参数
|
||||||
|
|
||||||
return ed;
|
return ed;
|
||||||
}
|
}
|
||||||
@@ -242,8 +243,7 @@ public static class NodeMethodDetailsHelper
|
|||||||
private static ParameterDetails GetExplicitDataOfParameter(ParameterInfo parameterInfo,
|
private static ParameterDetails GetExplicitDataOfParameter(ParameterInfo parameterInfo,
|
||||||
int index,
|
int index,
|
||||||
Type explicitParemType,
|
Type explicitParemType,
|
||||||
bool isExplicitData,
|
bool isExplicitData)
|
||||||
Func<object, object> func = null)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
bool hasParams = parameterInfo.IsDefined(typeof(ParamArrayAttribute)); // 判断是否为可变参数
|
bool hasParams = parameterInfo.IsDefined(typeof(ParamArrayAttribute)); // 判断是否为可变参数
|
||||||
@@ -269,7 +269,7 @@ public static class NodeMethodDetailsHelper
|
|||||||
Index = index, // 索引
|
Index = index, // 索引
|
||||||
ExplicitTypeName = explicitTypeName, // Select/Bool/Value
|
ExplicitTypeName = explicitTypeName, // Select/Bool/Value
|
||||||
ExplicitType = explicitParemType,// 显示的入参类型
|
ExplicitType = explicitParemType,// 显示的入参类型
|
||||||
Convertor = func, // 转换器
|
//Convertor = func, // 转换器
|
||||||
DataType = dataType, // 实际的入参类型
|
DataType = dataType, // 实际的入参类型
|
||||||
Name = parameterInfo.Name,
|
Name = parameterInfo.Name,
|
||||||
DataValue = parameterInfo.HasDefaultValue ? parameterInfo?.DefaultValue?.ToString() : "", // 如果存在默认值,则使用默认值
|
DataValue = parameterInfo.HasDefaultValue ? parameterInfo?.DefaultValue?.ToString() : "", // 如果存在默认值,则使用默认值
|
||||||
|
|||||||
@@ -102,17 +102,23 @@
|
|||||||
<GridSplitter Grid.Row="1" Grid.Column="1" Width="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ResizeBehavior="PreviousAndNext" Background="Gray" />
|
<GridSplitter Grid.Row="1" Grid.Column="1" Width="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ResizeBehavior="PreviousAndNext" Background="Gray" />
|
||||||
|
|
||||||
<Grid Grid.Row="1" Grid.Column="2" x:Name="FlowChartStackGrid">
|
<Grid Grid.Row="1" Grid.Column="2" x:Name="FlowChartStackGrid">
|
||||||
|
<ListBox ItemsSource="{Binding Nodes}" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
|
||||||
<StackPanel x:Name="FlowChartStackPanel"
|
<StackPanel x:Name="FlowChartStackPanel"
|
||||||
|
|
||||||
ClipToBounds="True">
|
ClipToBounds="True">
|
||||||
<!-- 虚拟化 VirtualizingStackPanel.IsVirtualizing="True" -->
|
<!-- 虚拟化 VirtualizingStackPanel.IsVirtualizing="True" -->
|
||||||
<Canvas
|
<Canvas
|
||||||
x:Name="FlowChartCanvas"
|
x:Name="FlowChartCanvas"
|
||||||
Background="#E1FBEA"
|
Background="#E1FBEA"
|
||||||
AllowDrop="True"
|
AllowDrop="True"
|
||||||
Width="2000"
|
Width="1920"
|
||||||
Height="2000"
|
Height="1080"
|
||||||
MouseLeftButtonDown ="FlowChartCanvas_MouseLeftButtonDown"
|
MouseLeftButtonDown ="FlowChartCanvas_MouseLeftButtonDown"
|
||||||
MouseLeftButtonUp="FlowChartCanvas_MouseLeftButtonUp"
|
MouseLeftButtonUp="FlowChartCanvas_MouseLeftButtonUp"
|
||||||
MouseDown="FlowChartCanvas_MouseDown"
|
MouseDown="FlowChartCanvas_MouseDown"
|
||||||
|
|||||||
@@ -14,11 +14,14 @@ using Serein.Workbench.Node.View;
|
|||||||
using Serein.Workbench.Node.ViewModel;
|
using Serein.Workbench.Node.ViewModel;
|
||||||
using Serein.Workbench.Themes;
|
using Serein.Workbench.Themes;
|
||||||
using Serein.Workbench.Tool;
|
using Serein.Workbench.Tool;
|
||||||
|
using SqlSugar.Extensions;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Controls.Primitives;
|
using System.Windows.Controls.Primitives;
|
||||||
@@ -188,11 +191,7 @@ namespace Serein.Workbench
|
|||||||
|
|
||||||
InitFlowEnvironmentEvent(); // 配置环境事件
|
InitFlowEnvironmentEvent(); // 配置环境事件
|
||||||
|
|
||||||
if (App.FlowProjectData is not null)
|
|
||||||
{
|
|
||||||
EnvDecorator.LoadProject(new FlowEnvInfo { Project = App.FlowProjectData }, App.FileDataPath); // 加载项目
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -253,6 +252,13 @@ namespace Serein.Workbench
|
|||||||
#region 窗体加载方法
|
#region 窗体加载方法
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (App.FlowProjectData is not null)
|
||||||
|
{
|
||||||
|
_ = Task.Run(() =>
|
||||||
|
{
|
||||||
|
EnvDecorator.LoadProject(new FlowEnvInfo { Project = App.FlowProjectData }, App.FileDataPath); // 加载项目
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -659,15 +665,17 @@ namespace Serein.Workbench
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FlowChartCanvas.Children.Remove(nodeControl);
|
FlowChartCanvas.Children.Remove(nodeControl);
|
||||||
nodeControl.RemoveAllConection();
|
nodeControl.RemoveAllConection();
|
||||||
NodeControls.Remove(nodeControl.ViewModel.NodeModel.Guid);
|
NodeControls.Remove(nodeControl.ViewModel.NodeModel.Guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 编辑项目时添加了节点
|
/// 添加节点事件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="nodeDataBase"></param>
|
/// <param name="eventArgs">添加节点事件参数</param>
|
||||||
/// <exception cref="NotImplementedException"></exception>
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
private void FlowEnvironment_NodeCreateEvent(NodeCreateEventArgs eventArgs)
|
private void FlowEnvironment_NodeCreateEvent(NodeCreateEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
@@ -738,6 +746,8 @@ namespace Serein.Workbench
|
|||||||
NodeTreeViewer.AddGlobalFlipFlop(EnvDecorator, node); // 新增的触发器节点添加到全局触发器
|
NodeTreeViewer.AddGlobalFlipFlop(EnvDecorator, node); // 新增的触发器节点添加到全局触发器
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GC.Collect();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -819,7 +829,10 @@ namespace Serein.Workbench
|
|||||||
//{
|
//{
|
||||||
// nodeControl.ViewModel.IsInterrupt = true;
|
// nodeControl.ViewModel.IsInterrupt = true;
|
||||||
//}
|
//}
|
||||||
|
if(nodeControl.ContextMenu == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
foreach (var menuItem in nodeControl.ContextMenu.Items)
|
foreach (var menuItem in nodeControl.ContextMenu.Items)
|
||||||
{
|
{
|
||||||
if (menuItem is MenuItem menu)
|
if (menuItem is MenuItem menu)
|
||||||
@@ -2669,147 +2682,16 @@ namespace Serein.Workbench
|
|||||||
#region 复制粘贴选择的节点
|
#region 复制粘贴选择的节点
|
||||||
if (Keyboard.Modifiers == ModifierKeys.Control)
|
if (Keyboard.Modifiers == ModifierKeys.Control)
|
||||||
{
|
{
|
||||||
#region 复制节点
|
|
||||||
if (e.Key == Key.C && selectNodeControls.Count > 0)
|
if (e.Key == Key.C && selectNodeControls.Count > 0)
|
||||||
{
|
{
|
||||||
// 处理复制操作
|
CpoyNodeInfo();
|
||||||
List<NodeInfo> selectNodeInfos = selectNodeControls.Select(control => control.ViewModel.NodeModel.ToInfo()).ToList();
|
|
||||||
|
|
||||||
/*foreach (var node in selectNodeInfos.ToArray())
|
|
||||||
{
|
|
||||||
// 遍历这些节点的子节点,获得完整的已选节点信息
|
|
||||||
foreach (var childNodeGuid in node.ChildNodeGuids)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(childNodeGuid)
|
|
||||||
&& NodeControls.TryGetValue(childNodeGuid, out var nodeControl))
|
|
||||||
{
|
|
||||||
|
|
||||||
var newNodeInfo = nodeControl.ViewModel.NodeModel.ToInfo();
|
|
||||||
selectNodeInfos.Add(newNodeInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
Dictionary<string, string> guids = new Dictionary<string, string>(); // 记录 Guid
|
|
||||||
// 遍历当前已选节点
|
|
||||||
foreach (var node in selectNodeInfos.ToArray())
|
|
||||||
{
|
|
||||||
if (!guids.ContainsKey(node.Guid))
|
|
||||||
{
|
|
||||||
// 如果是没出现过的Guid,则记录并新增对应的映射。
|
|
||||||
guids.TryAdd(node.Guid, Guid.NewGuid().ToString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 出现过的Guid,说明重复添加了。应该不会走到这。
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(node.ChildNodeGuids is null)
|
|
||||||
{
|
|
||||||
continue; // 跳过没有子节点的节点
|
|
||||||
}
|
|
||||||
|
|
||||||
// 遍历这些节点的子节点,获得完整的已选节点信息
|
|
||||||
foreach (var childNodeGuid in node.ChildNodeGuids)
|
|
||||||
{
|
|
||||||
if (!guids.ContainsKey(childNodeGuid))
|
|
||||||
{
|
|
||||||
// 如果是没出现过的Guid,则记录并新增对应的映射。
|
|
||||||
guids.TryAdd(node.Guid, Guid.NewGuid().ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(childNodeGuid)
|
|
||||||
&& NodeControls.TryGetValue(childNodeGuid, out var nodeControl))
|
|
||||||
{
|
|
||||||
|
|
||||||
var newNodeInfo = nodeControl.ViewModel.NodeModel.ToInfo();
|
|
||||||
selectNodeInfos.Add(newNodeInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var replacer = new GuidReplacer();
|
|
||||||
foreach(var kv in guids)
|
|
||||||
{
|
|
||||||
replacer.AddReplacement(kv.Key, kv.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
JObject json = new JObject()
|
|
||||||
{
|
|
||||||
["nodes"] = JArray.FromObject(selectNodeInfos)
|
|
||||||
};
|
|
||||||
var jsonText = json.ToString();
|
|
||||||
|
|
||||||
string result = replacer.Replace(jsonText);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Clipboard.SetDataObject(result, true); // 持久性设置
|
|
||||||
SereinEnv.WriteLine(InfoType.INFO, $"复制已选节点({selectNodeInfos.Count}个)");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
SereinEnv.WriteLine(InfoType.ERROR, $"复制失败:{ex.Message}");
|
|
||||||
}
|
|
||||||
|
|
||||||
//SereinEnv.WriteLine(InfoType.INFO, json.ToString());
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 粘贴节点
|
|
||||||
else if (e.Key == Key.V)
|
else if (e.Key == Key.V)
|
||||||
{
|
{
|
||||||
|
PasteNodeInfo();
|
||||||
if (Clipboard.ContainsText())
|
}
|
||||||
{
|
}
|
||||||
string clipboardText = Clipboard.GetText(TextDataFormat.Text);
|
|
||||||
|
|
||||||
List<NodeInfo> nodes = JsonConvert.DeserializeObject<List<NodeInfo>>(JObject.Parse(clipboardText)["nodes"].ToString());
|
|
||||||
if (nodes is not null && nodes.Count >= 0)
|
|
||||||
{
|
|
||||||
Point mousePosition = Mouse.GetPosition(FlowChartCanvas);
|
|
||||||
PositionOfUI positionOfUI = new PositionOfUI(mousePosition.X, mousePosition.Y); // 坐标数据
|
|
||||||
SereinEnv.WriteLine(InfoType.INFO, $"粘贴节点({nodes.Count}个)");
|
|
||||||
// 获取第一个节点的原始位置
|
|
||||||
var index0NodeX = nodes[0].Position.X;
|
|
||||||
var index0NodeY = nodes[0].Position.Y;
|
|
||||||
|
|
||||||
// 计算所有节点相对于第一个节点的偏移量
|
|
||||||
foreach (var node in nodes)
|
|
||||||
{
|
|
||||||
|
|
||||||
var offsetX = node.Position.X - index0NodeX;
|
|
||||||
var offsetY = node.Position.Y - index0NodeY;
|
|
||||||
|
|
||||||
// 根据鼠标位置平移节点
|
|
||||||
node.Position = new PositionOfUI(positionOfUI.X + offsetX, positionOfUI.Y + offsetY);
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = EnvDecorator.LoadNodeInfosAsync(nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//SereinEnv.WriteLine(InfoType.INFO, $"剪贴板文本内容: {clipboardText}");
|
|
||||||
}
|
|
||||||
else if (Clipboard.ContainsImage())
|
|
||||||
{
|
|
||||||
var image = Clipboard.GetImage();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SereinEnv.WriteLine(InfoType.INFO, "剪贴板中没有可识别的数据。");
|
|
||||||
}
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
if (e.KeyStates == Keyboard.GetKeyStates(Key.Escape))
|
if (e.KeyStates == Keyboard.GetKeyStates(Key.Escape))
|
||||||
{
|
{
|
||||||
IsControlDragging = false;
|
IsControlDragging = false;
|
||||||
@@ -2860,9 +2742,219 @@ namespace Serein.Workbench
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region 复制节点,粘贴节点
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 复制节点
|
||||||
|
/// </summary>
|
||||||
|
private void CpoyNodeInfo()
|
||||||
|
{
|
||||||
|
// 处理复制操作
|
||||||
|
var dictSelection = selectNodeControls
|
||||||
|
.Select(control => control.ViewModel.NodeModel.ToInfo())
|
||||||
|
.ToDictionary(kvp => kvp.Guid, kvp => kvp);
|
||||||
|
|
||||||
|
// 遍历当前已选节点
|
||||||
|
foreach (var node in dictSelection.Values.ToArray())
|
||||||
|
{
|
||||||
|
// 遍历这些节点的子节点,获得完整的已选节点信息
|
||||||
|
foreach (var childNodeGuid in node.ChildNodeGuids)
|
||||||
|
{
|
||||||
|
if(!dictSelection.ContainsKey(childNodeGuid) && NodeControls.TryGetValue(childNodeGuid,out var childNode))
|
||||||
|
{
|
||||||
|
dictSelection.Add(childNodeGuid, childNode.ViewModel.NodeModel.ToInfo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JObject json = new JObject()
|
||||||
|
{
|
||||||
|
["nodes"] = JArray.FromObject(dictSelection.Values)
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonText = json.ToString();
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//Clipboard.SetDataObject(result, true); // 持久性设置
|
||||||
|
Clipboard.SetDataObject(jsonText, true); // 持久性设置
|
||||||
|
SereinEnv.WriteLine(InfoType.INFO, $"复制已选节点({dictSelection.Count}个)");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
SereinEnv.WriteLine(InfoType.ERROR, $"复制失败:{ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 粘贴节点
|
||||||
|
/// </summary>
|
||||||
|
private void PasteNodeInfo()
|
||||||
|
{
|
||||||
|
if (Clipboard.ContainsText())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
string clipboardText = Clipboard.GetText(TextDataFormat.Text);
|
||||||
|
string jsonText = JObject.Parse(clipboardText)["nodes"].ToString();
|
||||||
|
List<NodeInfo> nodes = JsonConvert.DeserializeObject<List<NodeInfo>>(jsonText);
|
||||||
|
if (nodes is null || nodes.Count < 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 节点去重
|
||||||
|
Dictionary<string, string> guids = new Dictionary<string, string>(); // 记录 Guid
|
||||||
|
// 遍历当前已选节点
|
||||||
|
foreach (var node in nodes.ToArray())
|
||||||
|
{
|
||||||
|
if (NodeControls.ContainsKey(node.Guid) && !guids.ContainsKey(node.Guid))
|
||||||
|
{
|
||||||
|
// 如果是没出现过、且在当前记录中重复的Guid,则记录并新增对应的映射。
|
||||||
|
guids.TryAdd(node.Guid, Guid.NewGuid().ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 出现过的Guid,说明重复添加了。应该不会走到这。
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.ChildNodeGuids is null)
|
||||||
|
{
|
||||||
|
continue; // 跳过没有子节点的节点
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历这些节点的子节点,获得完整的已选节点信息
|
||||||
|
foreach (var childNodeGuid in node.ChildNodeGuids)
|
||||||
|
{
|
||||||
|
if (NodeControls.ContainsKey(node.Guid) && !NodeControls.ContainsKey(node.Guid))
|
||||||
|
{
|
||||||
|
// 当前Guid并不重复,跳过替换
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!guids.ContainsKey(childNodeGuid))
|
||||||
|
{
|
||||||
|
// 如果是没出现过的Guid,则记录并新增对应的映射。
|
||||||
|
guids.TryAdd(node.Guid, Guid.NewGuid().ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(childNodeGuid)
|
||||||
|
&& NodeControls.TryGetValue(childNodeGuid, out var nodeControl))
|
||||||
|
{
|
||||||
|
|
||||||
|
var newNodeInfo = nodeControl.ViewModel.NodeModel.ToInfo();
|
||||||
|
nodes.Add(newNodeInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//var flashText = new FlashText.NET.TextReplacer();
|
||||||
|
|
||||||
|
//var t = guids.Select(kvp => (kvp.Key, kvp.Value)).ToArray();
|
||||||
|
//var result = flashText.ReplaceWords(jsonText, t);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder(jsonText);
|
||||||
|
foreach (var kv in guids)
|
||||||
|
{
|
||||||
|
sb.Replace(kv.Key, kv.Value);
|
||||||
|
}
|
||||||
|
string result = sb.ToString();
|
||||||
|
|
||||||
|
|
||||||
|
/*var replacer = new GuidReplacer();
|
||||||
|
foreach (var kv in guids)
|
||||||
|
{
|
||||||
|
replacer.AddReplacement(kv.Key, kv.Value);
|
||||||
|
}
|
||||||
|
string result = replacer.Replace(jsonText);*/
|
||||||
|
|
||||||
|
|
||||||
|
//SereinEnv.WriteLine(InfoType.ERROR, result);
|
||||||
|
nodes = JsonConvert.DeserializeObject<List<NodeInfo>>(result);
|
||||||
|
|
||||||
|
if (nodes is null || nodes.Count < 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
Point mousePosition = Mouse.GetPosition(FlowChartCanvas);
|
||||||
|
PositionOfUI positionOfUI = new PositionOfUI(mousePosition.X, mousePosition.Y); // 坐标数据
|
||||||
|
|
||||||
|
// 获取第一个节点的原始位置
|
||||||
|
var index0NodeX = nodes[0].Position.X;
|
||||||
|
var index0NodeY = nodes[0].Position.Y;
|
||||||
|
|
||||||
|
// 计算所有节点相对于第一个节点的偏移量
|
||||||
|
foreach (var node in nodes)
|
||||||
|
{
|
||||||
|
|
||||||
|
var offsetX = node.Position.X - index0NodeX;
|
||||||
|
var offsetY = node.Position.Y - index0NodeY;
|
||||||
|
|
||||||
|
// 根据鼠标位置平移节点
|
||||||
|
node.Position = new PositionOfUI(positionOfUI.X + offsetX, positionOfUI.Y + offsetY);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = EnvDecorator.LoadNodeInfosAsync(nodes);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
SereinEnv.WriteLine(InfoType.ERROR, $"粘贴节点时发生异常:{ex}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SereinEnv.WriteLine(InfoType.INFO, $"剪贴板文本内容: {clipboardText}");
|
||||||
|
}
|
||||||
|
else if (Clipboard.ContainsImage())
|
||||||
|
{
|
||||||
|
// var image = Clipboard.GetImage();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SereinEnv.WriteLine(InfoType.INFO, "剪贴板中没有可识别的数据。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// 卸载DLL文件,清空当前项目
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void UnloadAllButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
EnvDecorator.ClearAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 卸载DLL文件,清空当前项目
|
||||||
|
/// </summary>
|
||||||
|
private void UnloadAllAssemblies()
|
||||||
|
{
|
||||||
|
DllStackPanel.Children.Clear();
|
||||||
|
FlowChartCanvas.Children.Clear();
|
||||||
|
Connections.Clear();
|
||||||
|
NodeControls.Clear();
|
||||||
|
//currentLine = null;
|
||||||
|
//startConnectNodeControl = null;
|
||||||
|
MessageBox.Show("所有DLL已卸载。", "信息", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* /// <summary>
|
||||||
/// 对象装箱测试
|
/// 对象装箱测试
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
@@ -2913,31 +3005,6 @@ namespace Serein.Workbench
|
|||||||
data = SerinExpressionEvaluator.Evaluate(exp,result!, out isChange);
|
data = SerinExpressionEvaluator.Evaluate(exp,result!, out isChange);
|
||||||
SereinEnv.WriteLine(InfoType.INFO, $"{exp} => {data}");
|
SereinEnv.WriteLine(InfoType.INFO, $"{exp} => {data}");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/// <summary>
|
|
||||||
/// 卸载DLL文件,清空当前项目
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
private void UnloadAllButton_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
EnvDecorator.ClearAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 卸载DLL文件,清空当前项目
|
|
||||||
/// </summary>
|
|
||||||
private void UnloadAllAssemblies()
|
|
||||||
{
|
|
||||||
DllStackPanel.Children.Clear();
|
|
||||||
FlowChartCanvas.Children.Clear();
|
|
||||||
Connections.Clear();
|
|
||||||
NodeControls.Clear();
|
|
||||||
//currentLine = null;
|
|
||||||
//startConnectNodeControl = null;
|
|
||||||
MessageBox.Show("所有DLL已卸载。", "信息", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
|
|
||||||
<Border BorderBrush="#8DE9FD" BorderThickness="4" >
|
<Border BorderBrush="#8DE9FD" BorderThickness="1">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ToolTip>
|
<Grid.ToolTip>
|
||||||
<ToolTip Background="LightYellow" Foreground="#071042" Content="{Binding NodeModel.MethodDetails}" />
|
<ToolTip Background="LightYellow" Foreground="#071042" Content="{Binding NodeModel.MethodDetails}" />
|
||||||
@@ -32,17 +32,14 @@
|
|||||||
<Border x:Name="InterruptBorder" Tag="{Binding NodeModel.DebugSetting.IsInterrupt}">
|
<Border x:Name="InterruptBorder" Tag="{Binding NodeModel.DebugSetting.IsInterrupt}">
|
||||||
<Border.Style>
|
<Border.Style>
|
||||||
<Style TargetType="Border">
|
<Style TargetType="Border">
|
||||||
<!--默认无边框-->
|
|
||||||
<Setter Property="BorderBrush" Value="Transparent" />
|
|
||||||
<Setter Property="BorderThickness" Value="0" />
|
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<!--NodeModel.DebugSetting.IsInterrupt-->
|
|
||||||
<!--<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:ActionNodeControl}}, Path=DataContext.DebugSetting.IsInterrupt}" Value="True">-->
|
|
||||||
<!--<DataTrigger Binding="{Binding DebugSetting.IsInterrupt, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="True">-->
|
|
||||||
<DataTrigger Binding="{Binding Path=Tag,RelativeSource={RelativeSource Mode=Self}}" Value="True">
|
<DataTrigger Binding="{Binding Path=Tag,RelativeSource={RelativeSource Mode=Self}}" Value="True">
|
||||||
<Setter Property="BorderBrush" Value="Red" />
|
<Setter Property="BorderBrush" Value="Red" />
|
||||||
<Setter Property="BorderThickness" Value="2" />
|
<Setter Property="BorderThickness" Value="2" />
|
||||||
<Setter Property="Background" Value="#80000000" />
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Path=Tag,RelativeSource={RelativeSource Mode=Self}}" Value="False">
|
||||||
|
<Setter Property="BorderBrush" Value="Transparent" />
|
||||||
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
@@ -50,9 +47,6 @@
|
|||||||
|
|
||||||
|
|
||||||
<Grid Background="#8DE9FD" >
|
<Grid Background="#8DE9FD" >
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
@@ -62,10 +56,6 @@
|
|||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<Grid Grid.Row="0" >
|
<Grid Grid.Row="0" >
|
||||||
<!--<Grid Grid.Row="0" >-->
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="*"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="auto"/>
|
<ColumnDefinition Width="auto"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
@@ -79,19 +69,11 @@
|
|||||||
<local:NextStepJunctionControl Grid.Column="2" MyNode="{Binding NodeModel}" x:Name="NextStepJunctionControl" HorizontalAlignment="Right" Grid.RowSpan="2"/>
|
<local:NextStepJunctionControl Grid.Column="2" MyNode="{Binding NodeModel}" x:Name="NextStepJunctionControl" HorizontalAlignment="Right" Grid.RowSpan="2"/>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<themes:MethodDetailsControl Grid.Row="2" x:Name="MethodDetailsControl" MethodDetails="{Binding NodeModel.MethodDetails}"/>
|
||||||
|
<Border Grid.Row="2" x:Name="ParameterProtectionMask" Background="LightBlue" Opacity="0.5" BorderThickness="0"
|
||||||
<!--<StackPanel Background="#8DE9FD" >
|
|
||||||
|
|
||||||
</StackPanel>-->
|
|
||||||
|
|
||||||
<themes:MethodDetailsControl x:Name="MethodDetailsControl" Grid.Row="2" MethodDetails="{Binding NodeModel.MethodDetails}"/>
|
|
||||||
<!-- ParameterProtectionMask 参数保护 -->
|
|
||||||
<!--取反 Visibility="{Binding DebugSetting.IsEnable, Converter={StaticResource InvertedBoolConverter}, ConverterParameter=Inverted}"-->
|
|
||||||
<Border Grid.Row="2" x:Name="ParameterProtectionMask" Background="LightBlue" Opacity="0.5" BorderBrush="#0A4651" BorderThickness="0"
|
|
||||||
Visibility="{Binding NodeModel.MethodDetails.IsProtectionParameter, Mode=TwoWay,
|
Visibility="{Binding NodeModel.MethodDetails.IsProtectionParameter, Mode=TwoWay,
|
||||||
Converter={StaticResource InvertedBoolConverter},ConverterParameter=Normal}" />
|
Converter={StaticResource InvertedBoolConverter}, ConverterParameter=Normal}" />
|
||||||
<Grid Grid.Row="3" Background="#D5F0FC" >
|
<Grid Grid.Row="3" Background="#D5F0FC" >
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="50"/>
|
<ColumnDefinition Width="50"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
@@ -110,20 +92,20 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<StackPanel Grid.Row="4" Background="Azure" Orientation="Horizontal" Margin="3">
|
<StackPanel Grid.Row="4" Background="Azure" Orientation="Horizontal" Margin="3">
|
||||||
<StackPanel Orientation="Horizontal" Margin="2,1,2,1">
|
<StackPanel Orientation="Horizontal">
|
||||||
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsEnable, Mode=TwoWay}"/>
|
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsEnable, Mode=TwoWay}"/>
|
||||||
<TextBlock Text="是否使能" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
<TextBlock Text="是否使能"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal" Margin="2,1,2,1">
|
<StackPanel Orientation="Horizontal">
|
||||||
<CheckBox IsChecked="{Binding NodeModel.MethodDetails.IsProtectionParameter, Mode=TwoWay}"/>
|
<CheckBox IsChecked="{Binding NodeModel.MethodDetails.IsProtectionParameter, Mode=TwoWay}"/>
|
||||||
<TextBlock Text="参数保护" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
<TextBlock Text="参数保护"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal" Margin="2,1,2,1">
|
<StackPanel Orientation="Horizontal">
|
||||||
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsInterrupt, Mode=TwoWay}"/>
|
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsInterrupt, Mode=TwoWay}"/>
|
||||||
<TextBlock Text="中断节点" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
<TextBlock Text="中断节点"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@@ -131,10 +113,6 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!--Visibility="{Binding IsEnable, Converter={StaticResource BoolToVisConverter}, ConverterParameter=False}"-->
|
|
||||||
|
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
</local:NodeControlBase>
|
</local:NodeControlBase>
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ namespace Serein.Workbench.Node.View
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,21 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace Serein.Workbench.Node.View
|
namespace Serein.Workbench.Node.View
|
||||||
{
|
{
|
||||||
|
internal static class MyUIFunc
|
||||||
|
{
|
||||||
|
public static Pen CreateAndFreezePen()
|
||||||
|
{
|
||||||
|
// 创建Pen
|
||||||
|
Pen pen = new Pen(Brushes.Black, 1);
|
||||||
|
|
||||||
|
// 冻结Pen
|
||||||
|
if (pen.CanFreeze)
|
||||||
|
{
|
||||||
|
pen.Freeze();
|
||||||
|
}
|
||||||
|
return pen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class ParamsArgControl: Shape
|
public class ParamsArgControl: Shape
|
||||||
{
|
{
|
||||||
@@ -27,8 +41,6 @@ namespace Serein.Workbench.Node.View
|
|||||||
this.MouseMove += ParamsArgControl_MouseMove;
|
this.MouseMove += ParamsArgControl_MouseMove;
|
||||||
this.MouseLeave += ParamsArgControl_MouseLeave;
|
this.MouseLeave += ParamsArgControl_MouseLeave;
|
||||||
AddOrRemoveParamsTask = AddAsync;
|
AddOrRemoveParamsTask = AddAsync;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -84,9 +96,9 @@ namespace Serein.Workbench.Node.View
|
|||||||
// 圆形部分
|
// 圆形部分
|
||||||
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
||||||
|
|
||||||
drawingContext.DrawGeometry(brush, new Pen(Brushes.Black, 1), ellipse);
|
drawingContext.DrawGeometry(brush, MyUIFunc.CreateAndFreezePen(), ellipse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private bool isMouseOver; // 鼠标悬停状态
|
private bool isMouseOver; // 鼠标悬停状态
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace Serein.Workbench.Node.View
|
|||||||
|
|
||||||
// 绘制连接器的圆形部分
|
// 绘制连接器的圆形部分
|
||||||
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
||||||
drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), ellipse);
|
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse);
|
||||||
|
|
||||||
// 定义三角形的间距
|
// 定义三角形的间距
|
||||||
double triangleOffsetX = 4; // 三角形与圆形的间距
|
double triangleOffsetX = 4; // 三角形与圆形的间距
|
||||||
@@ -66,7 +66,7 @@ namespace Serein.Workbench.Node.View
|
|||||||
context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false);
|
context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false);
|
||||||
context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false);
|
context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false);
|
||||||
}
|
}
|
||||||
drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), pathGeometry);
|
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), pathGeometry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace Serein.Workbench.Node.View
|
|||||||
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
||||||
|
|
||||||
|
|
||||||
drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), ellipse);
|
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ namespace Serein.Workbench.Node.View
|
|||||||
context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false);
|
context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false);
|
||||||
context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false);
|
context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false);
|
||||||
}
|
}
|
||||||
drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), pathGeometry);
|
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), pathGeometry);
|
||||||
|
|
||||||
// 绘制标签
|
// 绘制标签
|
||||||
//var formattedText = new FormattedText(
|
//var formattedText = new FormattedText(
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace Serein.Workbench.Node.View
|
|||||||
var circlePoint = new Point(circleCenterX, circleCenterY);
|
var circlePoint = new Point(circleCenterX, circleCenterY);
|
||||||
// 绘制连接器的圆形部分
|
// 绘制连接器的圆形部分
|
||||||
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
||||||
drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), ellipse);
|
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse);
|
||||||
|
|
||||||
// 绘制连接器的圆形部分
|
// 绘制连接器的圆形部分
|
||||||
//var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
//var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
||||||
@@ -54,7 +54,7 @@ namespace Serein.Workbench.Node.View
|
|||||||
context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false);
|
context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false);
|
||||||
context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false);
|
context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false);
|
||||||
}
|
}
|
||||||
drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), pathGeometry);
|
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), pathGeometry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace Serein.Workbench.Node.View
|
|||||||
|
|
||||||
// 绘制连接器的圆形部分
|
// 绘制连接器的圆形部分
|
||||||
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
|
||||||
drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), ellipse);
|
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse);
|
||||||
|
|
||||||
// 定义三角形的间距
|
// 定义三角形的间距
|
||||||
double triangleOffsetX = 4; // 三角形与圆形的间距
|
double triangleOffsetX = 4; // 三角形与圆形的间距
|
||||||
@@ -55,7 +55,7 @@ namespace Serein.Workbench.Node.View
|
|||||||
context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false);
|
context.LineTo(new Point(triangleCenterX, triangleCenterY + 4.5), true, false);
|
||||||
context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false);
|
context.LineTo(new Point(triangleCenterX, triangleCenterY - 4.5), true, false);
|
||||||
}
|
}
|
||||||
drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), pathGeometry);
|
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), pathGeometry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ namespace Serein.Workbench.Node.View
|
|||||||
|
|
||||||
public NodeControlViewModelBase ViewModel { get; set; }
|
public NodeControlViewModelBase ViewModel { get; set; }
|
||||||
|
|
||||||
|
|
||||||
protected NodeControlBase()
|
protected NodeControlBase()
|
||||||
{
|
{
|
||||||
this.Background = Brushes.Transparent;
|
this.Background = Brushes.Transparent;
|
||||||
|
|||||||
@@ -103,9 +103,6 @@ namespace Serein.Workbench.Node.View
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ConnectionControl
|
public class ConnectionControl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 所在的画布
|
/// 所在的画布
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user