mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-14 03:46:34 +08:00
恢复WPF项目代码
This commit is contained in:
118
Workbench/Node/View/ActionNodeControl.xaml
Normal file
118
Workbench/Node/View/ActionNodeControl.xaml
Normal file
@@ -0,0 +1,118 @@
|
||||
<local:NodeControlBase x:Class="Serein.Workbench.Node.View.ActionNodeControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Serein.Workbench.Node.View"
|
||||
xmlns:vm="clr-namespace:Serein.Workbench.Node.ViewModel"
|
||||
xmlns:converters="clr-namespace:Serein.Workbench.Tool.Converters"
|
||||
xmlns:themes="clr-namespace:Serein.Workbench.Themes"
|
||||
d:DataContext="{d:DesignInstance vm:ActionNodeControlViewModel}"
|
||||
mc:Ignorable="d"
|
||||
MaxWidth="300">
|
||||
|
||||
<UserControl.Resources>
|
||||
<!--<BooleanToVisibilityConverter x:Key="BoolToVisConverter" />-->
|
||||
<converters:InvertableBooleanToVisibilityConverter x:Key="InvertedBoolConverter"/>
|
||||
<!--<ResourceDictionary Source="/Serein.Workbench;Node/View/NodeExecuteJunctionControl.xaml" x:Key="NodeExecuteJunctionControl"/>-->
|
||||
|
||||
</UserControl.Resources>
|
||||
|
||||
|
||||
<Border BorderBrush="#8DE9FD" BorderThickness="1">
|
||||
<Grid>
|
||||
<Grid.ToolTip>
|
||||
<ToolTip Background="LightYellow" Foreground="#071042" Content="{Binding NodeModel.MethodDetails}" />
|
||||
</Grid.ToolTip>
|
||||
|
||||
<!--<TextBlock Text="{Binding NodelModel.DebugSetting.IsInterrupt}}"></TextBlock>-->
|
||||
<!--DataContext="{Binding}-->
|
||||
|
||||
|
||||
<Border x:Name="InterruptBorder" Tag="{Binding NodeModel.DebugSetting.IsInterrupt}">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Path=Tag,RelativeSource={RelativeSource Mode=Self}}" Value="True">
|
||||
<Setter Property="BorderBrush" Value="Red" />
|
||||
<Setter Property="BorderThickness" Value="2" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Path=Tag,RelativeSource={RelativeSource Mode=Self}}" Value="False">
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
|
||||
|
||||
<Grid Background="#8DE9FD" >
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0" >
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<local:ExecuteJunctionControl Grid.Column="0" MyNode="{Binding NodeModel}" x:Name="ExecuteJunctionControl" HorizontalAlignment="Left" Grid.RowSpan="2"/>
|
||||
<StackPanel Grid.Column="1" Grid.RowSpan="2" >
|
||||
<TextBlock Text="{Binding NodeModel.DisplayName, Mode=TwoWay}" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<local:NextStepJunctionControl Grid.Column="2" MyNode="{Binding NodeModel}" x:Name="NextStepJunctionControl" HorizontalAlignment="Right" Grid.RowSpan="2"/>
|
||||
|
||||
</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"
|
||||
Visibility="{Binding NodeModel.MethodDetails.IsProtectionParameter, Mode=TwoWay,
|
||||
Converter={StaticResource InvertedBoolConverter}, ConverterParameter=Normal}" />
|
||||
<Grid Grid.Row="3" Background="#D5F0FC" >
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="50"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.Column="0" BorderThickness="1">
|
||||
<TextBlock Text="result ->" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<Border Grid.Column="1" BorderThickness="1">
|
||||
<TextBlock Text="{Binding NodeModel.MethodDetails.ReturnType.FullName, Mode=OneTime}" TextTrimming="CharacterEllipsis" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Column="2" BorderThickness="1">
|
||||
<local:ResultJunctionControl Grid.Column="2" MyNode="{Binding NodeModel}" x:Name="ResultJunctionControl" HorizontalAlignment="Right"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Grid.Row="4" Background="Azure" Orientation="Horizontal" Margin="3">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsEnable, Mode=TwoWay}"/>
|
||||
<TextBlock Text="是否使能"/>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<CheckBox IsChecked="{Binding NodeModel.MethodDetails.IsProtectionParameter, Mode=TwoWay}"/>
|
||||
<TextBlock Text="参数保护"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsInterrupt, Mode=TwoWay}"/>
|
||||
<TextBlock Text="中断节点"/>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</local:NodeControlBase>
|
||||
110
Workbench/Node/View/ConditionNodeControl.xaml
Normal file
110
Workbench/Node/View/ConditionNodeControl.xaml
Normal file
@@ -0,0 +1,110 @@
|
||||
<local:NodeControlBase x:Class="Serein.Workbench.Node.View.ConditionNodeControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Serein.Workbench.Node.View"
|
||||
xmlns:vm="clr-namespace:Serein.Workbench.Node.ViewModel"
|
||||
xmlns:themes="clr-namespace:Serein.Workbench.Themes"
|
||||
d:DataContext="{d:DesignInstance vm:ConditionNodeControlViewModel}"
|
||||
mc:Ignorable="d"
|
||||
MaxWidth="300">
|
||||
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis" />
|
||||
</UserControl.Resources>
|
||||
|
||||
|
||||
<Grid>
|
||||
<Grid.ToolTip>
|
||||
<ToolTip Background="LightYellow" Foreground="Black" Content="{Binding NodeModel.MethodDetails.MethodAnotherName, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid.ToolTip>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0" Background="#E7EFF5" >
|
||||
<!--<Grid Grid.Row="0" >-->
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<local:ExecuteJunctionControl Grid.Column="0" MyNode="{Binding NodeModel}" x:Name="ExecuteJunctionControl" HorizontalAlignment="Left" Grid.RowSpan="2"/>
|
||||
<Border Grid.Column="1" BorderThickness="1" HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="条件节点" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<local:NextStepJunctionControl Grid.Column="2" MyNode="{Binding NodeModel}" x:Name="NextStepJunctionControl" HorizontalAlignment="Right" Grid.RowSpan="2"/>
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" Background="#FEFAF4" HorizontalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="20"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<local:ArgJunctionControl Grid.Column="0" x:Name="ArgJunctionControl" ArgIndex="0" MyNode="{Binding NodeModel}" />
|
||||
<CheckBox Grid.Column="1" IsChecked="{Binding NodeModel.IsExplicitData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center"/> <!--Converter={StaticResource BoolToVis}-->
|
||||
<TextBox Grid.Column="2" MinWidth="50" Text="{Binding NodeModel.ExplicitData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center">
|
||||
<TextBox.Style>
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding NodeModel.IsExplicitData}" Value="True">
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBox.Style>
|
||||
</TextBox>
|
||||
|
||||
<TextBlock Grid.Column="2" MinWidth="50" Text="上一节点数据" HorizontalAlignment="Stretch" VerticalAlignment="Center">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding NodeModel.IsExplicitData}" Value="False">
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
|
||||
|
||||
<Grid Grid.Row="1" Grid.ColumnSpan="3" Background="#FEFAF4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox Grid.Column="0" Background="#FEFAF4" MinWidth="100" Text="{Binding NodeModel.Expression, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
|
||||
|
||||
<local:ResultJunctionControl Grid.Column="1" MyNode="{Binding NodeModel}" x:Name="ResultJunctionControl" HorizontalAlignment="Right"/>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
<!--<themes:MethodDetailsControl Grid.Row="1" MethodDetails="{Binding MethodDetails}" />
|
||||
<Border Grid.Row="2" Background="#EAFFD0" BorderBrush="#EAFFD0" BorderThickness="1">
|
||||
<TextBlock Text="{Binding MethodDetails.MethodTips, Converter={StaticResource TypeToStringConverter}, StringFormat=return:{0}, UpdateSourceTrigger=PropertyChanged}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</Border>-->
|
||||
</Grid>
|
||||
</local:NodeControlBase>
|
||||
58
Workbench/Node/View/ConditionNodeControl.xaml.cs
Normal file
58
Workbench/Node/View/ConditionNodeControl.xaml.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using Serein.NodeFlow.Model;
|
||||
using Serein.Workbench.Node.ViewModel;
|
||||
|
||||
namespace Serein.Workbench.Node.View
|
||||
{
|
||||
/// <summary>
|
||||
/// ConditionNode.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ConditionNodeControl : NodeControlBase, INodeJunction
|
||||
{
|
||||
public ConditionNodeControl() : base()
|
||||
{
|
||||
// 窗体初始化需要
|
||||
base.ViewModel = new ConditionNodeControlViewModel (new SingleConditionNode(null));
|
||||
DataContext = ViewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public ConditionNodeControl(ConditionNodeControlViewModel viewModel):base(viewModel)
|
||||
{
|
||||
DataContext = viewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 入参控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.ExecuteJunction => this.ExecuteJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 下一个调用方法控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.NextStepJunction => this.NextStepJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 返回值控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.ReturnDataJunction => this.ResultJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 方法入参控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
private JunctionControlBase[] argDataJunction;
|
||||
/// <summary>
|
||||
/// 方法入参控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase[] INodeJunction.ArgDataJunction
|
||||
{
|
||||
get
|
||||
{
|
||||
argDataJunction = new JunctionControlBase[1];
|
||||
argDataJunction[0] = this.ArgJunctionControl;
|
||||
return argDataJunction;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
22
Workbench/Node/View/ConditionRegionControl.xaml
Normal file
22
Workbench/Node/View/ConditionRegionControl.xaml
Normal file
@@ -0,0 +1,22 @@
|
||||
<local:NodeControlBase x:Class="Serein.Workbench.Node.View.ConditionRegionControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Serein.Workbench.Node.View"
|
||||
xmlns:vm="clr-namespace:Serein.Workbench.Node.ViewModel"
|
||||
d:DataContext="{d:DesignInstance vm:ConditionRegionNodeControlViewModel}"
|
||||
mc:Ignorable="d"
|
||||
MaxWidth="300">
|
||||
<Grid>
|
||||
<Border BorderBrush="Black" BorderThickness="1" Padding="10">
|
||||
<StackPanel>
|
||||
<DockPanel Margin="2,2,2,5">
|
||||
<TextBlock Text="条件区域" FontWeight="Bold" HorizontalAlignment="Left" FontSize="14" Margin="0,1,0,0"/>
|
||||
<Button Content="编辑" FontWeight="Bold" HorizontalAlignment="Right"/>
|
||||
</DockPanel>
|
||||
<ListBox x:Name="ConditionsListBox" AllowDrop="True" Drop="ConditionsListBox_Drop"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</local:NodeControlBase>
|
||||
94
Workbench/Node/View/ConditionRegionControl.xaml.cs
Normal file
94
Workbench/Node/View/ConditionRegionControl.xaml.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using Serein.NodeFlow.Model;
|
||||
using Serein.Workbench.Node.ViewModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Serein.Workbench.Node.View
|
||||
{
|
||||
/// <summary>
|
||||
/// ConditionRegion.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ConditionRegionControl : NodeControlBase
|
||||
{
|
||||
public new CompositeConditionNode ViewModel => ViewModel;
|
||||
|
||||
public ConditionRegionControl() : base()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public ConditionRegionControl(ConditionRegionNodeControlViewModel viewModel) : base(viewModel)
|
||||
{
|
||||
DataContext = viewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加条件控件
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
public void AddCondition(NodeControlBase node)
|
||||
{
|
||||
|
||||
//((CompositeConditionNode)ViewModel.NodeModel).AddNode((SingleConditionNode)node.ViewModel.NodeModel);
|
||||
ViewModel.AddNode((SingleConditionNode)node.ViewModel.NodeModel);
|
||||
|
||||
this.Width += node.Width;
|
||||
this.Height += node.Height;
|
||||
ConditionsListBox.Items.Add(node);
|
||||
}
|
||||
|
||||
private void ConditionsListBox_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
// Mouse event handlers for dragging
|
||||
//private void TypeText_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
//{
|
||||
// _dragStartPoint = e.GetPosition(null);
|
||||
//}
|
||||
|
||||
//private void TypeText_MouseMove(object sender, MouseEventArgs e)
|
||||
//{
|
||||
// Point mousePos = e.GetPosition(null);
|
||||
// Vector diff = _dragStartPoint - mousePos;
|
||||
|
||||
// if (e.LeftButton == MouseButtonState.Pressed &&
|
||||
// (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
|
||||
// Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
|
||||
// {
|
||||
// if (sender is TextBlock typeText)
|
||||
// {
|
||||
// var dragData = new DataObject(MouseNodeType.RegionType, typeText.Tag);
|
||||
// DragDrop.DoDragDrop(typeText, dragData, DragDropEffects.Move);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
/*private void TypeText_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
Point mousePos = e.GetPosition(null);
|
||||
Vector diff = _dragStartPoint - mousePos;
|
||||
|
||||
if (e.LeftButton == MouseButtonState.Pressed &&
|
||||
(Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
|
||||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
|
||||
{
|
||||
TextBlock typeText = sender as TextBlock;
|
||||
if (typeText != null)
|
||||
{
|
||||
DataObject dragData = new DataObject("Type", typeText.Tag);
|
||||
DragDrop.DoDragDrop(typeText, dragData, DragDropEffects.Move);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
||||
297
Workbench/Node/View/ConnectionControl.cs
Normal file
297
Workbench/Node/View/ConnectionControl.cs
Normal file
@@ -0,0 +1,297 @@
|
||||
using Serein.Library;
|
||||
using Serein.Library.Api;
|
||||
using Serein.Workbench.Extension;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
using Color = System.Windows.Media.Color;
|
||||
using ColorConverter = System.Windows.Media.ColorConverter;
|
||||
using Point = System.Windows.Point;
|
||||
|
||||
namespace Serein.Workbench.Node.View
|
||||
{
|
||||
#region 连接点相关代码
|
||||
|
||||
|
||||
|
||||
public class ConnectionModelBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 起始节点
|
||||
/// </summary>
|
||||
public NodeModelBase StartNode { get; set; }
|
||||
/// <summary>
|
||||
/// 目标节点
|
||||
/// </summary>
|
||||
public NodeModelBase EndNode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源于起始节点的(控制点)类型
|
||||
/// </summary>
|
||||
public JunctionType JoinTypeOfStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接到目标节点的(控制点)类型
|
||||
/// </summary>
|
||||
public JunctionType JoinTypeOfEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接类型
|
||||
/// </summary>
|
||||
public ConnectionInvokeType Type { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public interface IJunctionNode
|
||||
{
|
||||
string BoundNodeGuid { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接点
|
||||
/// </summary>
|
||||
public class JunctionNode : IJunctionNode
|
||||
{
|
||||
/// <summary>
|
||||
/// 连接点类型
|
||||
/// </summary>
|
||||
public JunctionType JunctionType { get; }
|
||||
/// <summary>
|
||||
/// 对应的视图对象
|
||||
/// </summary>
|
||||
public NodeModelBase NodeModel { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string BoundNodeGuid { get => NodeModel.Guid; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 连接控件,表示控件的连接关系
|
||||
/// </summary>
|
||||
public class ConnectionControl
|
||||
{
|
||||
/// <summary>
|
||||
/// 所在的画布
|
||||
/// </summary>
|
||||
public Canvas Canvas { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 调用方法类型,连接类型
|
||||
/// </summary>
|
||||
public ConnectionInvokeType InvokeType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标节点控制点
|
||||
/// </summary>
|
||||
private INodeJunction EndNode;
|
||||
|
||||
/// <summary>
|
||||
/// 获取参数类型,第几个参数
|
||||
/// </summary>
|
||||
public int ArgIndex { get; set; } = -1;
|
||||
|
||||
/// <summary>
|
||||
/// 参数来源(决定了连接线的样式)
|
||||
/// </summary>
|
||||
public ConnectionArgSourceType ArgSourceType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始控制点
|
||||
/// </summary>
|
||||
public JunctionControlBase Start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标控制点
|
||||
/// </summary>
|
||||
public JunctionControlBase End { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接线
|
||||
/// </summary>
|
||||
private ConnectionLineShape BezierLine;
|
||||
|
||||
|
||||
|
||||
private LineType LineType;
|
||||
|
||||
/// <summary>
|
||||
/// 关于调用
|
||||
/// </summary>
|
||||
/// <param name="Canvas"></param>
|
||||
/// <param name="invokeType"></param>
|
||||
public ConnectionControl(Canvas Canvas,
|
||||
ConnectionInvokeType invokeType,
|
||||
JunctionControlBase Start,
|
||||
JunctionControlBase End)
|
||||
{
|
||||
this.LineType = LineType.Bezier;
|
||||
this.Canvas = Canvas;
|
||||
this.InvokeType = invokeType;
|
||||
this.Start = Start;
|
||||
this.End = End;
|
||||
InitElementPoint();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关于入参
|
||||
/// </summary>
|
||||
/// <param name="Canvas"></param>
|
||||
/// <param name="Type"></param>
|
||||
public ConnectionControl(LineType LineType,
|
||||
Canvas Canvas,
|
||||
int argIndex,
|
||||
ConnectionArgSourceType argSourceType,
|
||||
JunctionControlBase Start,
|
||||
JunctionControlBase End,
|
||||
INodeJunction nodeJunction)
|
||||
{
|
||||
this.LineType = LineType;
|
||||
this.Canvas = Canvas;
|
||||
this.ArgIndex = argIndex;
|
||||
this.ArgSourceType = argSourceType;
|
||||
this.Start = Start;
|
||||
this.End = End;
|
||||
this.EndNode = nodeJunction;
|
||||
InitElementPoint();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绘制
|
||||
/// </summary>
|
||||
public void InitElementPoint()
|
||||
{
|
||||
leftCenterOfEndLocation = Start.MyCenterPoint;
|
||||
rightCenterOfStartLocation = End.MyCenterPoint;
|
||||
|
||||
(Point startPoint, Point endPoint) = RefreshPoint(Canvas, Start, End);
|
||||
var connectionType = Start.JunctionType.ToConnectyionType();
|
||||
bool isDotted;
|
||||
Brush brush;
|
||||
if(connectionType == JunctionOfConnectionType.Invoke)
|
||||
{
|
||||
brush = InvokeType.ToLineColor();
|
||||
isDotted = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
brush = ArgSourceType.ToLineColor();
|
||||
isDotted = true; // 如果为参数,则绘制虚线
|
||||
}
|
||||
BezierLine = new ConnectionLineShape(LineType, startPoint, endPoint, brush, isDotted);
|
||||
Grid.SetZIndex(BezierLine, -9999999); // 置底
|
||||
Canvas.Children.Add(BezierLine);
|
||||
|
||||
ConfigureLineContextMenu(); //配置右键菜单
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 配置连接曲线的右键菜单
|
||||
/// </summary>
|
||||
private void ConfigureLineContextMenu()
|
||||
{
|
||||
var contextMenu = new ContextMenu();
|
||||
contextMenu.Items.Add(MainWindow.CreateMenuItem("删除连线", (s, e) => Remote()));
|
||||
contextMenu.Items.Add(MainWindow.CreateMenuItem("于父节点调用顺序中置顶", (s, e) => Topping()));
|
||||
BezierLine.ContextMenu = contextMenu;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 删除该连线
|
||||
/// </summary>
|
||||
public void Remote()
|
||||
{
|
||||
Canvas.Children.Remove(BezierLine);
|
||||
var env = Start.MyNode.Env;
|
||||
if (Start.JunctionType.ToConnectyionType() == JunctionOfConnectionType.Invoke)
|
||||
{
|
||||
env.RemoveConnectInvokeAsync(Start.MyNode.Guid, End.MyNode.Guid, InvokeType);
|
||||
}
|
||||
else if (Start.JunctionType.ToConnectyionType() == JunctionOfConnectionType.Arg)
|
||||
{
|
||||
env.RemoveConnectArgSourceAsync(Start.MyNode.Guid, End.MyNode.Guid, ArgIndex) ;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 置顶调用关系
|
||||
/// </summary>
|
||||
public void Topping()
|
||||
{
|
||||
var env = Start.MyNode.Env;
|
||||
if (Start.JunctionType.ToConnectyionType() == JunctionOfConnectionType.Invoke)
|
||||
{
|
||||
env.SetConnectPriorityInvoke(Start.MyNode.Guid, End.MyNode.Guid, InvokeType);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重新绘制
|
||||
/// </summary>
|
||||
public void RefreshLine()
|
||||
{
|
||||
if(ArgIndex > -1)
|
||||
{
|
||||
End = EndNode.GetJunctionOfArgData(ArgIndex) ?? End;
|
||||
}
|
||||
(Point startPoint, Point endPoint) = RefreshPoint(Canvas, Start, End);
|
||||
BezierLine.UpdatePoints(startPoint, endPoint);
|
||||
}
|
||||
|
||||
|
||||
private Point rightCenterOfStartLocation; // 目标节点选择左侧边缘中心
|
||||
private Point leftCenterOfEndLocation; // 起始节点选择右侧边缘中心
|
||||
/// <summary>
|
||||
/// 刷新坐标
|
||||
/// </summary>
|
||||
|
||||
private (Point startPoint, Point endPoint) RefreshPoint(Canvas canvas, FrameworkElement startElement, FrameworkElement endElement)
|
||||
{
|
||||
var startPoint = startElement.TranslatePoint(rightCenterOfStartLocation, canvas); // 获取起始节点的中心位置
|
||||
var endPoint = endElement.TranslatePoint(leftCenterOfEndLocation, canvas); // 计算终点位置
|
||||
return (startPoint, endPoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
34
Workbench/Node/View/DllControlControl.xaml
Normal file
34
Workbench/Node/View/DllControlControl.xaml
Normal file
@@ -0,0 +1,34 @@
|
||||
<UserControl x:Class="Serein.Workbench.Node.View.DllControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Serein.Workbench.Node.View"
|
||||
>
|
||||
<DockPanel>
|
||||
<StackPanel DockPanel.Dock="Top" >
|
||||
<TextBlock Text="{Binding Path=Header, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
FontWeight="Bold" FontSize="14" Margin="5" Background="#dbe2ef"/>
|
||||
</StackPanel>
|
||||
<DockPanel>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<GroupBox x:Name="ActionNodeGroupBox" Grid.Row="0" Header="动作" Margin="5" >
|
||||
<ListBox x:Name="ActionsListBox" Background="#D0F1F9"/>
|
||||
</GroupBox>
|
||||
<GroupBox x:Name="FlipflopNodeGroupBox" Grid.Row="1" Header="触发器" Margin="5">
|
||||
<ListBox x:Name="FlipflopsListBox" Background="#FACFC1"/>
|
||||
</GroupBox>
|
||||
</Grid>
|
||||
|
||||
|
||||
</DockPanel>
|
||||
</DockPanel>
|
||||
</UserControl>
|
||||
164
Workbench/Node/View/DllControlControl.xaml.cs
Normal file
164
Workbench/Node/View/DllControlControl.xaml.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
using Serein.Library;
|
||||
using Serein.Library.Utils;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Serein.Workbench.Node.View
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// UserControl1.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class DllControl : UserControl
|
||||
{
|
||||
private readonly NodeLibraryInfo nodeLibraryInfo;
|
||||
|
||||
public DllControl()
|
||||
{
|
||||
Header = "DLL文件"; // 设置初始值
|
||||
InitializeComponent();
|
||||
}
|
||||
public DllControl(NodeLibraryInfo nodeLibraryInfo)
|
||||
{
|
||||
this.nodeLibraryInfo = nodeLibraryInfo;
|
||||
Header = "DLL name : " + nodeLibraryInfo.AssemblyName;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Header 依赖属性,用于绑定标题
|
||||
/// </summary>
|
||||
public string Header
|
||||
{
|
||||
get { return (string)GetValue(HeaderProperty); }
|
||||
set { SetValue(HeaderProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty HeaderProperty =
|
||||
DependencyProperty.Register("Header", typeof(string), typeof(DllControl), new PropertyMetadata(string.Empty));
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 向动作面板添加类型的文本块
|
||||
/// </summary>
|
||||
/// <param name="type">要添加的类型</param>
|
||||
public void AddAction(MethodDetailsInfo mdInfo)
|
||||
{
|
||||
AddTypeToListBox(mdInfo, ActionsListBox);
|
||||
ActionNodeGroupBox.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向触发器面板添加类型的文本块
|
||||
/// </summary>
|
||||
/// <param name="type">要添加的类型</param>
|
||||
public void AddFlipflop(MethodDetailsInfo mdInfo)
|
||||
{
|
||||
AddTypeToListBox(mdInfo, FlipflopsListBox);
|
||||
FlipflopNodeGroupBox.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向指定面板添加类型的文本块
|
||||
/// </summary>
|
||||
/// <param name="mdInfo">要添加的方法信息</param>
|
||||
/// <param name="listBox">要添加到的面板</param>
|
||||
private void AddTypeToListBox(MethodDetailsInfo mdInfo, ListBox listBox)
|
||||
{
|
||||
// 创建一个新的 TextBlock 并设置其属性
|
||||
TextBlock typeText = new TextBlock
|
||||
{
|
||||
Text = $"{mdInfo.MethodAnotherName} - {mdInfo.MethodName}",
|
||||
Margin = new Thickness(10, 2, 0, 0),
|
||||
Tag = mdInfo
|
||||
};
|
||||
// 为 TextBlock 添加鼠标左键按下事件处理程序
|
||||
typeText.MouseLeftButtonDown += TypeText_MouseLeftButtonDown;
|
||||
// 为 TextBlock 添加鼠标移动事件处理程序
|
||||
typeText.MouseMove += TypeText_MouseMove;
|
||||
// 将 TextBlock 添加到指定的面板
|
||||
listBox.Items.Add(typeText);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 存储拖拽开始时的鼠标位置
|
||||
/// </summary>
|
||||
private Point _dragStartPoint;
|
||||
|
||||
/// <summary>
|
||||
/// 处理 TextBlock 的鼠标左键按下事件
|
||||
/// </summary>
|
||||
/// <param name="sender">事件源</param>
|
||||
/// <param name="e">事件参数</param>
|
||||
private void TypeText_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
// 记录鼠标按下时的位置
|
||||
_dragStartPoint = e.GetPosition(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理 TextBlock 的鼠标移动事件
|
||||
/// </summary>
|
||||
/// <param name="sender">事件源</param>
|
||||
/// <param name="e">事件参数</param>
|
||||
private void TypeText_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
// 获取当前鼠标位置
|
||||
Point mousePos = e.GetPosition(null);
|
||||
// 计算鼠标移动的距离
|
||||
Vector diff = _dragStartPoint - mousePos;
|
||||
|
||||
// 判断是否符合拖拽的最小距离要求
|
||||
if (e.LeftButton == MouseButtonState.Pressed &&
|
||||
(Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
|
||||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
|
||||
{
|
||||
// 获取触发事件的 TextBlock
|
||||
|
||||
|
||||
if (sender is TextBlock typeText && typeText.Tag is MethodDetailsInfo mdInfo)
|
||||
{
|
||||
if (!EnumHelper.TryConvertEnum<Library.NodeType>(mdInfo.NodeType, out var nodeType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MoveNodeData moveNodeData = new MoveNodeData
|
||||
{
|
||||
|
||||
NodeControlType = nodeType switch
|
||||
{
|
||||
NodeType.Action => NodeControlType.Action,
|
||||
NodeType.Flipflop => NodeControlType.Flipflop,
|
||||
_ => NodeControlType.None,
|
||||
},
|
||||
MethodDetailsInfo = mdInfo,
|
||||
};
|
||||
if(moveNodeData.NodeControlType == NodeControlType.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建一个 DataObject 用于拖拽操作,并设置拖拽效果
|
||||
DataObject dragData = new DataObject(MouseNodeType.CreateDllNodeInCanvas, moveNodeData);
|
||||
DragDrop.DoDragDrop(typeText, dragData, DragDropEffects.Move);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
47
Workbench/Node/View/ExpOpNodeControl.xaml
Normal file
47
Workbench/Node/View/ExpOpNodeControl.xaml
Normal file
@@ -0,0 +1,47 @@
|
||||
<local:NodeControlBase x:Class="Serein.Workbench.Node.View.ExpOpNodeControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Serein.Workbench.Node.View"
|
||||
xmlns:vm="clr-namespace:Serein.Workbench.Node.ViewModel"
|
||||
d:DataContext="{d:DesignInstance vm:ExpOpNodeViewModel}"
|
||||
mc:Ignorable="d"
|
||||
MaxWidth="300">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0" Background="#E7EFF5" >
|
||||
<!--<Grid Grid.Row="0" >-->
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<local:ExecuteJunctionControl Grid.Column="0" MyNode="{Binding NodeModel}" x:Name="ExecuteJunctionControl" HorizontalAlignment="Left" Grid.RowSpan="2"/>
|
||||
<Border Grid.Column="1" BorderThickness="1" HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="表达式" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<local:NextStepJunctionControl Grid.Column="2" MyNode="{Binding NodeModel}" x:Name="NextStepJunctionControl" HorizontalAlignment="Right" Grid.RowSpan="2"/>
|
||||
|
||||
</Grid>
|
||||
<Grid Grid.Row="1" Background="#FEFAF4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<local:ArgJunctionControl Grid.Column="0" x:Name="ArgJunctionControl" ArgIndex="0" MyNode="{Binding NodeModel}" />
|
||||
<TextBox Grid.Column="1" Text="{Binding NodeModel.Expression, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch"></TextBox>
|
||||
<local:ResultJunctionControl Grid.Column="2" MyNode="{Binding NodeModel}" x:Name="ResultJunctionControl" HorizontalAlignment="Right"/>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</local:NodeControlBase>
|
||||
56
Workbench/Node/View/ExpOpNodeControl.xaml.cs
Normal file
56
Workbench/Node/View/ExpOpNodeControl.xaml.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using Serein.NodeFlow.Model;
|
||||
using Serein.Workbench.Node.ViewModel;
|
||||
|
||||
namespace Serein.Workbench.Node.View
|
||||
{
|
||||
/// <summary>
|
||||
/// ExprOpNodeControl.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ExpOpNodeControl : NodeControlBase, INodeJunction
|
||||
{
|
||||
public ExpOpNodeControl() : base()
|
||||
{
|
||||
// 窗体初始化需要
|
||||
ViewModel = new ExpOpNodeControlViewModel(new SingleExpOpNode(null));
|
||||
DataContext = ViewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
public ExpOpNodeControl(ExpOpNodeControlViewModel viewModel) :base(viewModel)
|
||||
{
|
||||
DataContext = viewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 入参控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.ExecuteJunction => this.ExecuteJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 下一个调用方法控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.NextStepJunction => this.NextStepJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 返回值控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.ReturnDataJunction => this.ResultJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 方法入参控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
private JunctionControlBase[] argDataJunction;
|
||||
/// <summary>
|
||||
/// 方法入参控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase[] INodeJunction.ArgDataJunction
|
||||
{
|
||||
get
|
||||
{
|
||||
argDataJunction = new JunctionControlBase[1];
|
||||
argDataJunction[0] = this.ArgJunctionControl;
|
||||
return argDataJunction;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
110
Workbench/Node/View/FlipflopNodeControl.xaml
Normal file
110
Workbench/Node/View/FlipflopNodeControl.xaml
Normal file
@@ -0,0 +1,110 @@
|
||||
<local:NodeControlBase x:Class="Serein.Workbench.Node.View.FlipflopNodeControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:Converters="clr-namespace:Serein.Workbench.Tool.Converters"
|
||||
xmlns:local="clr-namespace:Serein.Workbench.Node.View"
|
||||
xmlns:vm="clr-namespace:Serein.Workbench.Node.ViewModel"
|
||||
xmlns:themes="clr-namespace:Serein.Workbench.Themes"
|
||||
d:DataContext="{d:DesignInstance vm:FlipflopNodeControlViewModel}"
|
||||
mc:Ignorable="d"
|
||||
MaxWidth="300">
|
||||
|
||||
<UserControl.Resources>
|
||||
<vm:TypeToStringConverter x:Key="TypeToStringConverter"/>
|
||||
<!--<themes:ConditionControl x:Key="ConditionControl"/>-->
|
||||
<Converters:InvertableBooleanToVisibilityConverter x:Key="InvertedBoolConverter"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Border BorderBrush="#FCB334" BorderThickness="1">
|
||||
|
||||
|
||||
<Grid>
|
||||
<Grid.ToolTip>
|
||||
<ToolTip Background="LightYellow" Foreground="#071042" Content="{Binding NodeModel.MethodDetails, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid.ToolTip>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0" Background="#FCB334" >
|
||||
<!--<Grid Grid.Row="0" >-->
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="3*"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<local:ExecuteJunctionControl Grid.Column="0" MyNode="{Binding NodeModel}" x:Name="ExecuteJunctionControl" HorizontalAlignment="Left" Grid.RowSpan="2"/>
|
||||
<StackPanel Grid.Column="1" Grid.RowSpan="2" >
|
||||
<TextBlock Text="{Binding NodeModel.DisplayName, Mode=TwoWay}" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<local:NextStepJunctionControl Grid.Column="2" MyNode="{Binding NodeModel}" x:Name="NextStepJunctionControl" HorizontalAlignment="Right" Grid.RowSpan="2"/>
|
||||
|
||||
</Grid>
|
||||
|
||||
<!--<StackPanel Grid.Row="0" Orientation="Horizontal" Background="#FCB334">
|
||||
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsEnable, Mode=TwoWay}" VerticalContentAlignment="Center"/>
|
||||
<CheckBox IsChecked="{Binding NodeModel.MethodDetails.IsProtectionParameter, Mode=TwoWay}" VerticalContentAlignment="Center"/>
|
||||
|
||||
<TextBlock Text="{Binding NodeModel.MethodDetails.MethodTips, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</StackPanel>-->
|
||||
|
||||
<themes:MethodDetailsControl x:Name="MethodDetailsControl" Grid.Row="1" MethodDetails="{Binding NodeModel.MethodDetails}" />
|
||||
|
||||
<Border Grid.Row="2" x:Name="ParameterProtectionMask" Background="LightBlue" Opacity="0.5" BorderBrush="#0A4651" BorderThickness="0"
|
||||
Visibility="{Binding NodeModel.MethodDetails.IsProtectionParameter, Converter={StaticResource InvertedBoolConverter},ConverterParameter=Normal}" />
|
||||
<!--<Border Grid.Row="0" Background="#FCB334" >
|
||||
|
||||
</Border>-->
|
||||
<!--<themes:ExplicitDataControl Grid.Row="1" ExplicitDatas="{Binding ExplicitDatas}" />-->
|
||||
<Grid Grid.Row="3" Background="#D5F0FC" >
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="50"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.Column="0" BorderThickness="1">
|
||||
<TextBlock Text="result ->" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<Border Grid.Column="1" BorderThickness="1">
|
||||
<TextBlock Text="{Binding NodeModel.MethodDetails.ReturnType.FullName, Mode=OneTime}" TextTrimming="CharacterEllipsis" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Column="2" BorderThickness="1">
|
||||
<local:ResultJunctionControl Grid.Column="2" MyNode="{Binding NodeModel}" x:Name="ResultJunctionControl" HorizontalAlignment="Right"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Grid.Row="4" Background="Azure" Orientation="Horizontal" Margin="3">
|
||||
<StackPanel Orientation="Horizontal" Margin="2,1,2,1">
|
||||
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsEnable, Mode=TwoWay}"/>
|
||||
<TextBlock Text="是否使能" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
<StackPanel Orientation="Horizontal" Margin="2,1,2,1">
|
||||
<CheckBox IsChecked="{Binding NodeModel.MethodDetails.IsProtectionParameter, Mode=TwoWay}"/>
|
||||
<TextBlock Text="参数保护" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Margin="2,1,2,1">
|
||||
<CheckBox IsChecked="{Binding NodeModel.DebugSetting.IsInterrupt, Mode=TwoWay}"/>
|
||||
<TextBlock Text="中断节点" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
<!--<themes:ConditionControl Grid.Row="2" ></themes:ConditionControl>-->
|
||||
</Grid>
|
||||
</Border>
|
||||
</local:NodeControlBase>
|
||||
72
Workbench/Node/View/FlipflopNodeControl.xaml.cs
Normal file
72
Workbench/Node/View/FlipflopNodeControl.xaml.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using Serein.NodeFlow.Model;
|
||||
using Serein.Workbench.Node.ViewModel;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows;
|
||||
|
||||
namespace Serein.Workbench.Node.View
|
||||
{
|
||||
/// <summary>
|
||||
/// StateNode.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class FlipflopNodeControl : NodeControlBase, INodeJunction
|
||||
{
|
||||
public FlipflopNodeControl(FlipflopNodeControlViewModel viewModel) : base(viewModel)
|
||||
{
|
||||
DataContext = viewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 入参控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.ExecuteJunction => this.ExecuteJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 下一个调用方法控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.NextStepJunction => this.NextStepJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 返回值控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.ReturnDataJunction => this.ResultJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 方法入参控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase[] INodeJunction.ArgDataJunction
|
||||
{
|
||||
get
|
||||
{
|
||||
// 获取 MethodDetailsControl 实例
|
||||
var methodDetailsControl = this.MethodDetailsControl;
|
||||
var itemsControl = FindVisualChild<ItemsControl>(methodDetailsControl); // 查找 ItemsControl
|
||||
if (itemsControl != null)
|
||||
{
|
||||
var argDataJunction = new JunctionControlBase[base.ViewModel.NodeModel.MethodDetails.ParameterDetailss.Length];
|
||||
var controls = new List<JunctionControlBase>();
|
||||
|
||||
for (int i = 0; i < itemsControl.Items.Count; i++)
|
||||
{
|
||||
var container = itemsControl.ItemContainerGenerator.ContainerFromIndex(i) as FrameworkElement;
|
||||
if (container != null)
|
||||
{
|
||||
var argControl = FindVisualChild<ArgJunctionControl>(container);
|
||||
if (argControl != null)
|
||||
{
|
||||
controls.Add(argControl); // 收集 ArgJunctionControl 实例
|
||||
}
|
||||
}
|
||||
}
|
||||
return argDataJunction = controls.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
87
Workbench/Node/View/GlobalDataControl.xaml
Normal file
87
Workbench/Node/View/GlobalDataControl.xaml
Normal file
@@ -0,0 +1,87 @@
|
||||
<local:NodeControlBase x:Class="Serein.Workbench.Node.View.GlobalDataControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Serein.Workbench.Node.View"
|
||||
xmlns:vm="clr-namespace:Serein.Workbench.Node.ViewModel"
|
||||
d:DataContext="{d:DesignInstance vm:GlobalDataNodeControlViewModel}"
|
||||
mc:Ignorable="d"
|
||||
MaxWidth="300">
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis" />
|
||||
</UserControl.Resources>
|
||||
|
||||
|
||||
<Grid Background="#FEFAF4">
|
||||
<!--<Grid.ToolTip>
|
||||
<ToolTip Background="LightYellow" Foreground="Black" Content="{Binding NodeModel.MethodDetails.MethodAnotherName, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid.ToolTip>-->
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0" Background="#E7EFF5" >
|
||||
<!--<Grid Grid.Row="0" >-->
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<local:ExecuteJunctionControl Grid.Column="0" MyNode="{Binding NodeModel}" x:Name="ExecuteJunctionControl" HorizontalAlignment="Left" Grid.RowSpan="2"/>
|
||||
<Border Grid.Column="1" BorderThickness="1" HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="全局数据节点" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<local:NextStepJunctionControl Grid.Column="2" MyNode="{Binding NodeModel}" x:Name="NextStepJunctionControl" HorizontalAlignment="Right" Grid.RowSpan="2"/>
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" HorizontalAlignment="Stretch" Margin="4">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal">
|
||||
<TextBlock Text="全局数据名称" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
|
||||
<TextBox MinWidth="50" Margin="2" Text="{Binding NodeModel.KeyName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Center">
|
||||
</TextBox>
|
||||
<Button Content="EXP" Command="{Binding CommandCopyDataExp}" Height="17.2"></Button>
|
||||
<!--<Button Content="刷新 " Command="{Binding CommandCopyDataExp}" Height="17.2" Margin="2,0,0,0"></Button>-->
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel x:Name="GlobalDataPanel"
|
||||
Grid.Row="1"
|
||||
Grid.ColumnSpan="2"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Center"
|
||||
>
|
||||
|
||||
</StackPanel>
|
||||
<!--<StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<local:ResultJunctionControl Grid.Column="2" MyNode="{Binding NodelModel}" x:Name="ResultJunctionControl" HorizontalAlignment="Right"/>
|
||||
<TextBlock Text="设置数据源" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
|
||||
</StackPanel>-->
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
<!--<themes:MethodDetailsControl Grid.Row="1" MethodDetails="{Binding MethodDetails}" />
|
||||
<Border Grid.Row="2" Background="#EAFFD0" BorderBrush="#EAFFD0" BorderThickness="1">
|
||||
<TextBlock Text="{Binding MethodDetails.MethodTips, Converter={StaticResource TypeToStringConverter}, StringFormat=return:{0}, UpdateSourceTrigger=PropertyChanged}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</Border>-->
|
||||
</Grid>
|
||||
</local:NodeControlBase>
|
||||
87
Workbench/Node/View/GlobalDataControl.xaml.cs
Normal file
87
Workbench/Node/View/GlobalDataControl.xaml.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using Serein.NodeFlow.Model;
|
||||
using Serein.Workbench.Node.ViewModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Serein.Workbench.Node.View
|
||||
{
|
||||
/// <summary>
|
||||
/// UserControl1.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class GlobalDataControl : NodeControlBase, INodeJunction, INodeContainerControl
|
||||
{
|
||||
public GlobalDataControl() : base()
|
||||
{
|
||||
// 窗体初始化需要
|
||||
base.ViewModel = new GlobalDataNodeControlViewModel(new SingleGlobalDataNode(null));
|
||||
DataContext = ViewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public GlobalDataControl(GlobalDataNodeControlViewModel viewModel) : base(viewModel)
|
||||
{
|
||||
DataContext = viewModel;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 入参控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.ExecuteJunction => this.ExecuteJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 下一个调用方法控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.NextStepJunction => this.NextStepJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 返回值控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.ReturnDataJunction => throw new NotImplementedException();
|
||||
|
||||
/// <summary>
|
||||
/// 方法入参控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase[] INodeJunction.ArgDataJunction => throw new NotImplementedException();
|
||||
|
||||
|
||||
public bool PlaceNode(NodeControlBase nodeControl)
|
||||
{
|
||||
if (GlobalDataPanel.Children.Contains(nodeControl))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GlobalDataPanel.Children.Add(nodeControl);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TakeOutNode(NodeControlBase nodeControl)
|
||||
{
|
||||
if (!GlobalDataPanel.Children.Contains(nodeControl))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GlobalDataPanel.Children.Remove(nodeControl);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void TakeOutAll()
|
||||
{
|
||||
GlobalDataPanel.Children.Clear();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
93
Workbench/Node/View/ScriptNodeControl.xaml
Normal file
93
Workbench/Node/View/ScriptNodeControl.xaml
Normal file
@@ -0,0 +1,93 @@
|
||||
<local:NodeControlBase x:Class="Serein.Workbench.Node.View.ScriptNodeControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Serein.Workbench.Node.View"
|
||||
xmlns:vm="clr-namespace:Serein.Workbench.Node.ViewModel"
|
||||
xmlns:themes="clr-namespace:Serein.Workbench.Themes"
|
||||
d:DataContext="{d:DesignInstance vm:ScriptNodeControlViewModel}"
|
||||
mc:Ignorable="d"
|
||||
MinWidth="50">
|
||||
|
||||
<Grid Background="#FEFAF4">
|
||||
<!--<Grid.ToolTip>
|
||||
<ToolTip Background="LightYellow" Foreground="Black" Content="{Binding NodeModel.MethodDetails.MethodAnotherName, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid.ToolTip>-->
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0" Background="#E7EFF5" >
|
||||
<!--<Grid Grid.Row="0" >-->
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<local:ExecuteJunctionControl Grid.Column="0" MyNode="{Binding NodeModel}" x:Name="ExecuteJunctionControl" HorizontalAlignment="Left" Grid.RowSpan="2"/>
|
||||
<Border Grid.Column="1" BorderThickness="1" HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="脚本节点" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<local:NextStepJunctionControl Grid.Column="2" MyNode="{Binding NodeModel}" x:Name="NextStepJunctionControl" HorizontalAlignment="Right" Grid.RowSpan="2"/>
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" HorizontalAlignment="Stretch" Margin="4">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal">
|
||||
<TextBlock Text="脚本代码:" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
|
||||
|
||||
<Button Content="加载" Margin="3,0,1,0" Command="{Binding CommandLoadScript}" Height="17.2"></Button>
|
||||
<Button Content="执行" Margin="3,0,1,0" Command="{Binding CommandExecuting}" Height="17.2"></Button>
|
||||
<!--<Button Content="刷新 " Command="{Binding CommandCopyDataExp}" Height="17.2" Margin="2,0,0,0"></Button>-->
|
||||
</StackPanel>
|
||||
<themes:MethodDetailsControl Grid.Row="1" x:Name="MethodDetailsControl" MethodDetails="{Binding NodeModel.MethodDetails}"/>
|
||||
<TextBox Grid.Row="2" MinHeight="20" MinWidth="100" MaxWidth="270" TextWrapping="Wrap" AcceptsReturn="True" Text="{Binding Script}"></TextBox>
|
||||
<Grid Grid.Row="3" >
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="50"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.Column="0" BorderThickness="1">
|
||||
<TextBlock Text="result ->" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<Border Grid.Column="1" BorderThickness="1">
|
||||
<TextBlock Text="{Binding NodeModel.MethodDetails.ReturnType.FullName, Mode=OneTime}" TextTrimming="CharacterEllipsis" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Column="2" BorderThickness="1">
|
||||
<local:ResultJunctionControl Grid.Column="2" MyNode="{Binding NodeModel}" x:Name="ResultJunctionControl" HorizontalAlignment="Right"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
<!--<RichTextBox x:Name="richTextBox" VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
|
||||
TextChanged="RichTextBox_TextChanged"/>-->
|
||||
|
||||
|
||||
<!--<StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<local:ResultJunctionControl Grid.Column="2" MyNode="{Binding NodelModel}" x:Name="ResultJunctionControl" HorizontalAlignment="Right"/>
|
||||
<TextBlock Text="设置数据源" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
|
||||
</StackPanel>-->
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
</local:NodeControlBase>
|
||||
162
Workbench/Node/View/ScriptNodeControl.xaml.cs
Normal file
162
Workbench/Node/View/ScriptNodeControl.xaml.cs
Normal file
@@ -0,0 +1,162 @@
|
||||
using Serein.NodeFlow.Model;
|
||||
using Serein.Workbench.Node.ViewModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace Serein.Workbench.Node.View
|
||||
{
|
||||
/// <summary>
|
||||
/// ScriptNodeControl.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ScriptNodeControl : NodeControlBase , INodeJunction
|
||||
{
|
||||
private ScriptNodeControlViewModel viewModel => (ScriptNodeControlViewModel)ViewModel;
|
||||
private DispatcherTimer _debounceTimer; // 用于延迟更新
|
||||
private bool _isUpdating = false; // 防止重复更新
|
||||
|
||||
public ScriptNodeControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
public ScriptNodeControl(ScriptNodeControlViewModel viewModel) : base(viewModel)
|
||||
{
|
||||
DataContext = viewModel;
|
||||
InitializeComponent();
|
||||
|
||||
#if false
|
||||
// 初始化定时器
|
||||
_debounceTimer = new DispatcherTimer();
|
||||
_debounceTimer.Interval = TimeSpan.FromMilliseconds(500); // 停止输入 500ms 后更新
|
||||
_debounceTimer.Tick += DebounceTimer_Tick;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 入参控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.ExecuteJunction => this.ExecuteJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 下一个调用方法控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.NextStepJunction => this.NextStepJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 返回值控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase INodeJunction.ReturnDataJunction => this.ResultJunctionControl;
|
||||
|
||||
/// <summary>
|
||||
/// 方法入参控制点(可能有,可能没)
|
||||
/// </summary>
|
||||
JunctionControlBase[] INodeJunction.ArgDataJunction
|
||||
{
|
||||
get
|
||||
{
|
||||
// 获取 MethodDetailsControl 实例
|
||||
var methodDetailsControl = this.MethodDetailsControl;
|
||||
var itemsControl = FindVisualChild<ItemsControl>(methodDetailsControl); // 查找 ItemsControl
|
||||
if (itemsControl != null)
|
||||
{
|
||||
var argDataJunction = new JunctionControlBase[base.ViewModel.NodeModel.MethodDetails.ParameterDetailss.Length];
|
||||
var controls = new List<JunctionControlBase>();
|
||||
|
||||
for (int i = 0; i < itemsControl.Items.Count; i++)
|
||||
{
|
||||
var container = itemsControl.ItemContainerGenerator.ContainerFromIndex(i) as FrameworkElement;
|
||||
if (container != null)
|
||||
{
|
||||
var argControl = FindVisualChild<ArgJunctionControl>(container);
|
||||
if (argControl != null)
|
||||
{
|
||||
controls.Add(argControl); // 收集 ArgJunctionControl 实例
|
||||
}
|
||||
}
|
||||
}
|
||||
return argDataJunction = controls.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if false
|
||||
// 每次输入时重置定时器
|
||||
private void RichTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
_debounceTimer.Stop();
|
||||
_debounceTimer.Start();
|
||||
}
|
||||
|
||||
// 定时器事件,用户停止输入后触发
|
||||
private async void DebounceTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
_debounceTimer.Stop();
|
||||
|
||||
if (_isUpdating)
|
||||
return;
|
||||
|
||||
// 开始后台处理语法分析和高亮
|
||||
_isUpdating = true;
|
||||
await Task.Run(() => HighlightKeywordsAsync(viewModel.Script));
|
||||
}
|
||||
|
||||
// 异步执行语法高亮操作
|
||||
private async Task HighlightKeywordsAsync(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// 模拟语法分析和高亮(可以替换为实际逻辑)
|
||||
var highlightedText = text;
|
||||
|
||||
// 在 UI 线程中更新 RichTextBox 的内容
|
||||
await Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
var range = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
|
||||
range.Text = highlightedText;
|
||||
});
|
||||
|
||||
_isUpdating = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user