删除不必要的数据

This commit is contained in:
fengjiayi
2025-01-04 22:21:07 +08:00
72 changed files with 0 additions and 10200 deletions

View File

@@ -1,22 +0,0 @@
<Application x:Class="Serein.Workbench.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Serein.Workbench"
StartupUri="MainWindow.xaml"
Startup="Application_Startup">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!--<ResourceDictionary Source="/Themes/ExplicitDataControl.xaml" />-->
<ResourceDictionary Source="/Themes/MethodDetailsControl.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type TextBlock }">
<!--<Setter Property="FontFamily" Value="Comic Sans MS"/>-->
<Setter Property="Foreground" Value="#071042"/>
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@@ -1,75 +0,0 @@
using Newtonsoft.Json;
using Serein.Library;
using Serein.Library.Utils;
using System.Diagnostics;
using System.IO;
using System.Windows;
namespace Serein.Workbench
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private async Task LoadLocalProjectAsync()
{
#if DEBUG
if (1 == 1)
{
// 这里是测试代码,可以删除
string filePath;
filePath = @"C:\Users\Az\source\repos\CLBanyunqiState\CLBanyunqiState\bin\Release\net8.0\PLCproject.dnf";
filePath = @"C:\Users\Az\source\repos\CLBanyunqiState\CLBanyunqiState\bin\Release\banyunqi\project.dnf";
filePath = @"C:\Users\Az\source\repos\CLBanyunqiState\CLBanyunqiState\bin\debug\net8.0\project.dnf";
//filePath = @"C:\Users\Az\source\repos\CLBanyunqiState\CLBanyunqiState\bin\debug\net8.0\test.dnf";
string content = System.IO.File.ReadAllText(filePath); // 读取整个文件内容
App.FlowProjectData = JsonConvert.DeserializeObject<SereinProjectData>(content);
App.FileDataPath = System.IO.Path.GetDirectoryName(filePath)!; // filePath;//
var dir = Path.GetDirectoryName(filePath);
}
#endif
}
public static SereinProjectData? FlowProjectData { get; set; }
public static string FileDataPath { get; set; } = "";
private async void Application_Startup(object sender, StartupEventArgs e)
{
// 检查是否传入了参数
if (e.Args.Length == 1)
{
// 获取文件路径
string filePath = e.Args[0];
// 检查文件是否存在
if (!System.IO.File.Exists(filePath))
{
MessageBox.Show($"文件未找到:{filePath}");
Shutdown(); // 关闭应用程序
return;
}
try
{
// 读取文件内容
string content = System.IO.File.ReadAllText(filePath); // 读取整个文件内容
FlowProjectData = JsonConvert.DeserializeObject<SereinProjectData>(content);
FileDataPath = System.IO.Path.GetDirectoryName(filePath) ?? "";
}
catch (Exception ex)
{
MessageBox.Show($"读取文件时发生错误:{ex.Message}");
Shutdown(); // 关闭应用程序
}
}
await this.LoadLocalProjectAsync();
}
}
}

View File

@@ -1,10 +0,0 @@
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]

View File

@@ -1,24 +0,0 @@
<Window x:Class="Serein.Workbench.LogWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Serein.Workbench"
mc:Ignorable="d"
Topmost="True"
Title="LogWindow" Height="600" Width="400"
Closing="Window_Closing">
<Grid>
<TextBox x:Name="LogTextBox"
FontSize="14"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
IsReadOnly="True"
TextWrapping="Wrap"/>
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Clear Log" Click="ClearLog_Click"/>
</ContextMenu>
</Grid.ContextMenu>
</Grid>
</Window>

View File

@@ -1,162 +0,0 @@
using System.Windows;
namespace Serein.Workbench
{
/// <summary>
/// DebugWindow.xaml 的交互逻辑
/// </summary>
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
/// <summary>
/// LogWindow.xaml 的交互逻辑
/// </summary>
public partial class LogWindow : Window
{
private StringBuilder logBuffer = new StringBuilder();
private int logUpdateInterval = 200; // 批量更新的时间间隔(毫秒)
private Timer logUpdateTimer;
private const int MaxLines = 1000; // 最大显示的行数
private bool autoScroll = true; // 自动滚动标识
private int flushThreshold = 5; // 设置日志刷新阈值
private const int maxFlushSize = 1000; // 每次最大刷新字符数
public LogWindow()
{
InitializeComponent();
// 初始化定时器,用于批量更新日志
logUpdateTimer = new Timer(logUpdateInterval);
logUpdateTimer.Elapsed += (s, e) => FlushLog(); // 定时刷新日志
logUpdateTimer.Start();
// 添加滚动事件处理,判断用户是否手动滚动
// LogTextBox.ScrollChanged += LogTextBox_ScrollChanged;
}
/// <summary>
/// 添加日志到缓冲区
/// </summary>
public void AppendText(string text)
{
lock (logBuffer)
{
logBuffer.Append(text);
// 异步写入日志到文件
// Task.Run(() => File.AppendAllText("log.txt", text));
//FlushLog();
// 如果日志达到阈值,立即刷新
if (logBuffer.Length > flushThreshold)
{
FlushLog();
}
}
}
/// <summary>
/// 清空日志缓冲区并更新到 TextBox 中
/// </summary>
private void FlushLog()
{
if (logBuffer.Length == 0) return;
Dispatcher.InvokeAsync(() =>
{
lock (logBuffer)
{
// 仅追加部分日志,避免一次更新过多内容
string logContent = logBuffer.Length > maxFlushSize
? logBuffer.ToString(0, maxFlushSize)
: logBuffer.ToString();
logBuffer.Remove(0, logContent.Length); // 清空已更新的部分
LogTextBox.Dispatcher.Invoke(() =>
{
LogTextBox.AppendText(logContent);
});
}
// 不必每次都修剪日志当行数超过限制20%时再修剪
if (LogTextBox.LineCount > MaxLines * 1.2)
{
TrimLog();
}
ScrollToEndIfNeeded(); // 根据是否需要自动滚动来决定
}, System.Windows.Threading.DispatcherPriority.Background);
}
/// <summary>
/// 限制日志输出的最大行数,超出时删除旧日志
/// </summary>
private void TrimLog()
{
if (LogTextBox.LineCount > MaxLines)
{
// 删除最早的多余行
LogTextBox.Text = LogTextBox.Text.Substring(
LogTextBox.GetCharacterIndexFromLineIndex(LogTextBox.LineCount - MaxLines));
}
}
/// <summary>
/// 检测用户是否手动滚动了文本框
/// </summary>
private void LogTextBox_ScrollChanged(object sender, System.Windows.Controls.ScrollChangedEventArgs e)
{
if (e.ExtentHeightChange == 0) // 用户手动滚动时
{
// 判断是否滚动到底部
//autoScroll = LogTextBox.VerticalOffset == LogTextBox.ScrollableHeight;
}
}
/// <summary>
/// 根据 autoScroll 标志决定是否滚动到末尾
/// </summary>
private void ScrollToEndIfNeeded()
{
if (autoScroll)
{
LogTextBox.ScrollToEnd(); // 仅在需要时滚动到末尾
}
}
/// <summary>
/// 清空日志
/// </summary>
public void Clear()
{
Dispatcher.BeginInvoke(() =>
{
LogTextBox.Clear();
});
}
/// <summary>
/// 点击清空日志按钮时触发
/// </summary>
private void ClearLog_Click(object sender, RoutedEventArgs e)
{
LogTextBox.Clear();
}
/// <summary>
/// 窗口关闭事件,隐藏窗体而不是关闭
/// </summary>
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
logBuffer?.Clear();
Clear();
e.Cancel = true; // 取消关闭操作
this.Hide(); // 隐藏窗体而不是关闭
}
}
}

View File

@@ -1,259 +0,0 @@
<Window x:Class="Serein.Workbench.MainWindow"
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"
xmlns:tool="clr-namespace:Serein.Workbench.Tool.Converters"
xmlns:nodeView="clr-namespace:Serein.Workbench.Node.View"
xmlns:themes="clr-namespace:Serein.Workbench.Themes"
xmlns:converters="clr-namespace:Serein.Workbench.Tool.Converters"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:MainWindowViewModel}"
Title="Dynamic Node Flow" Height="900" Width="1400"
AllowDrop="True"
Drop="Window_Drop"
DragOver="Window_DragOver"
Loaded="Window_Loaded"
ContentRendered="Window_ContentRendered"
PreviewKeyDown="Window_PreviewKeyDown"
Closing="Window_Closing">
<Window.Resources>
<converters:InvertableBooleanToVisibilityConverter x:Key="InvertedBoolConverter"/>
<tool:RightThumbPositionConverter x:Key="RightThumbPositionConverter" />
<tool:BottomThumbPositionConverter x:Key="BottomThumbPositionConverter" />
<tool:VerticalCenterThumbPositionConverter x:Key="VerticalCenterThumbPositionConverter" />
<tool:HorizontalCenterThumbPositionConverter x:Key="HorizontalCenterThumbPositionConverter" />
</Window.Resources>
<Window.InputBindings>
<!--<KeyBinding Key="Escape" Command="{Binding CancelConnectionCommand}"/>-->
</Window.InputBindings>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Menu DockPanel.Dock="Top" Grid.Row="0" Grid.ColumnSpan="5" Height="20">
<MenuItem Header="项目">
<!--菜单项为MenuItem文字使用属性 Header-->
<MenuItem Header="保存项目" Click="ButtonSaveFile_Click" ></MenuItem>
<MenuItem Header="打开本地文件" Click="ButtonOpenLocalProject_Click"></MenuItem>
</MenuItem>
<MenuItem Header="调试">
<MenuItem Header="运行(从起始节点)" Click="ButtonDebugRun_Click"></MenuItem>
<MenuItem Header="运行(从选定节点)" Click="ButtonStartFlowInSelectNode_Click"></MenuItem>
<MenuItem Header="结束流程" Click="ButtonDebugFlipflopNode_Click"></MenuItem>
</MenuItem>
<MenuItem Header="视图">
<MenuItem Header="输出窗口" Click="ButtonOpenConsoleOutWindow_Click"></MenuItem>
<MenuItem Header="重置画布" Click="ButtonResetCanvas_Click"></MenuItem>
<MenuItem Header="定位节点" Click="ButtonLocationNode_Click"></MenuItem>
</MenuItem>
<MenuItem Header="远程">
<MenuItem Header="启动远程服务" Click="ButtonStartRemoteServer_Click"></MenuItem>
<MenuItem Header="连接远程环境" Click="ButtonConnectionRemoteEnv_Click"></MenuItem>
</MenuItem>
<!--<MenuItem Header="说明"></MenuItem>-->
</Menu>
<DockPanel Grid.Row="1" Grid.Column="0" Background="#F5F5F5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<!--<RowDefinition Height="3"></RowDefinition>-->
<!--<RowDefinition Height="3*"></RowDefinition>-->
</Grid.RowDefinitions>
<!--暂时隐藏基础面板 Visibility="Collapsed" -->
<ScrollViewer Grid.Row="0" HorizontalScrollBarVisibility="Auto">
<StackPanel Orientation="Horizontal">
<nodeView:ScriptNodeControl x:Name="ScriptNodeControl" Margin="10" AllowDrop="True" PreviewMouseMove="BaseNodeControl_PreviewMouseMove"/>
<nodeView:GlobalDataControl x:Name="GlobalDataControl" Margin="10" AllowDrop="True" PreviewMouseMove="BaseNodeControl_PreviewMouseMove"/>
<nodeView:ExpOpNodeControl x:Name="ExpOpNodeControl" Margin="10" AllowDrop="True" PreviewMouseMove="BaseNodeControl_PreviewMouseMove"/>
<nodeView:ConditionNodeControl x:Name="ConditionNodeControl" Margin="10" AllowDrop="True" PreviewMouseMove="BaseNodeControl_PreviewMouseMove"/>
<!--<nodeView:ConditionRegionControl x:Name="ConditionRegionControl" Margin="10" AllowDrop="True" PreviewMouseMove="BaseNodeControl_PreviewMouseMove"/>-->
</StackPanel>
</ScrollViewer>
<ScrollViewer VerticalAlignment="Top" Grid.Row="1" VerticalScrollBarVisibility="Auto" Grid.RowSpan="2">
<StackPanel x:Name="DllStackPanel" Margin="5"/>
</ScrollViewer>
<!--<GridSplitter Grid.Row="3" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Center" ResizeBehavior="PreviousAndNext" Background="Gray"/>-->
</Grid>
</DockPanel>
<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">
<ListBox ItemsSource="{Binding Nodes}" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling">
<ListBox.ItemTemplate>
<DataTemplate>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel x:Name="FlowChartStackPanel"
ClipToBounds="True">
<!-- 虚拟化 VirtualizingStackPanel.IsVirtualizing="True" -->
<Canvas
x:Name="FlowChartCanvas"
Background="#E1FBEA"
AllowDrop="True"
Width="1920"
Height="1080"
MouseLeftButtonDown ="FlowChartCanvas_MouseLeftButtonDown"
MouseLeftButtonUp="FlowChartCanvas_MouseLeftButtonUp"
MouseDown="FlowChartCanvas_MouseDown"
MouseUp="FlowChartCanvas_MouseUp"
MouseMove="FlowChartCanvas_MouseMove"
MouseWheel="FlowChartCanvas_MouseWheel"
Drop="FlowChartCanvas_Drop"
DragOver="FlowChartCanvas_DragOver"
>
<Rectangle x:Name="SelectionRectangle"
Stroke="Blue"
StrokeThickness="2"
Fill="LightBlue"
Opacity="0.2"
Panel.ZIndex="999999"
Visibility="Collapsed"/>
<!-- Top-Left Thumb -->
<!--<Thumb x:Name="TopLeftThumb"
Width="10" Height="10"
DragDelta="Thumb_DragDelta_TopLeft"
Cursor="SizeNWSE"
Canvas.Left="0" Canvas.Top="0"/>-->
<!-- Top-Right Thumb -->
<!--<Thumb x:Name="TopRightThumb"
Width="10" Height="10"
DragDelta="Thumb_DragDelta_TopRight"
Cursor="SizeNESW"
Canvas.Left="{Binding ActualWidth, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource RightThumbPositionConverter}}"
Canvas.Top="0"/>-->
<!-- Bottom-Left Thumb -->
<!--<Thumb x:Name="BottomLeftThumb"
Width="10" Height="10"
DragDelta="Thumb_DragDelta_BottomLeft"
Cursor="SizeNESW"
Canvas.Left="0"
Canvas.Top="{Binding ActualHeight, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource BottomThumbPositionConverter}}"/>-->
<!-- Left Thumb -->
<!--<Thumb x:Name="LeftThumb"
Width="10" Height="10"
DragDelta="Thumb_DragDelta_Left"
Cursor="SizeWE"
Canvas.Left="0"
Canvas.Top="{Binding ActualHeight, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource VerticalCenterThumbPositionConverter}}"/>-->
<!-- Right Thumb -->
<!-- Top Thumb -->
<!--<Thumb x:Name="TopThumb"
Width="10" Height="10"
DragDelta="Thumb_DragDelta_Top"
Cursor="SizeNS"
Canvas.Left="{Binding ActualWidth, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource HorizontalCenterThumbPositionConverter}}"
Canvas.Top="0"/>-->
<!-- Bottom Thumb -->
<!-- Bottom-Right Thumb -->
<Thumb x:Name="BottomRightThumb"
Width="15" Height="15"
DragDelta="Thumb_DragDelta_BottomRight"
Cursor="SizeNWSE"
Canvas.Left="{Binding ActualWidth, Converter={StaticResource RightThumbPositionConverter}, ElementName=FlowChartCanvas, Mode=OneWay}"
Canvas.Top="{Binding ActualHeight, Converter={StaticResource BottomThumbPositionConverter}, ElementName=FlowChartCanvas, Mode=OneWay}"/>
<!--Canvas.Left="{Binding ActualWidth, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource RightThumbPositionConverter}}"
Canvas.Top="{Binding ActualHeight, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource VerticalCenterThumbPositionConverter}}"-->
<Thumb x:Name="RightThumb" Width="5" Cursor="SizeWE" Canvas.Top="0" Canvas.Right="0" DragDelta="Thumb_DragDelta_Right">
<Thumb.Template>
<ControlTemplate>
<Border Background="#B1B9F8" Width="5" Height="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}" />
</ControlTemplate>
</Thumb.Template>
</Thumb>
<!--Canvas.Left="{Binding ActualWidth, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource HorizontalCenterThumbPositionConverter}}"
Canvas.Top="{Binding ActualHeight, ElementName=FlowChartCanvas, Mode=OneWay, Converter={StaticResource BottomThumbPositionConverter}}"-->
<Thumb x:Name="BottomThumb" Height="5" Cursor="SizeNS" Canvas.Bottom="0" Canvas.Left="0" DragDelta="Thumb_DragDelta_Bottom">
<Thumb.Template>
<ControlTemplate>
<Border Background="#B1B9F8" Height="5" Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}" />
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Canvas>
</StackPanel>
<StackPanel>
<StackPanel x:Name="CreateNodeInvoke"
Margin="14" Width="auto" HorizontalAlignment="Left" Background="White" Opacity="0.8"
Visibility="{Binding IsConnectionInvokeNode,
Converter={StaticResource InvertedBoolConverter},ConverterParameter=Normal}" >
<TextBlock Margin="8,2,8,0" Foreground="#FF2727" FontSize="14" Text="正在设置方法调用关系 按 Ecs 退出连线状态 )"/>
<TextBlock Margin="8,0,8,0" Foreground="#4A82E4" FontSize="14" Text=" 按 1 切换:上游分支(运行本节点前,优先执行目标节点)"/>
<TextBlock Margin="8,0,8,0" Foreground="#04FC10" FontSize="14" Text=" 按 2 切换Succeed 分支(本节点运行完成,将会运行目标节点)"/>
<TextBlock Margin="8,0,8,0" Foreground="#F18905" FontSize="14" Text=" 按 3 切换Fail 分支条件节点的false分支"/>
<TextBlock Margin="8,0,8,2" Foreground="#FE1343" FontSize="14" Text=" 按 4 切换:异常分支(本节点运行发生异常时执行目标节点)"/>
</StackPanel>
<StackPanel Margin="14" Width="auto" HorizontalAlignment="Left" Background="White" Opacity="0.8"
Visibility="{Binding IsConnectionArgSourceNode,
Converter={StaticResource InvertedBoolConverter},ConverterParameter=Normal}" >
<TextBlock Margin="8,2,8,0" Foreground="#FF2727" FontSize="14" Text="正在设置参数传递关系 按 Ecs 退出连线状态 )"/>
<TextBlock Margin="8,0,8,0" Foreground="#56CEF6" FontSize="14" Text=" 按 1 切换使用返回值作为当前上下文的入参参数当前上下文下如果未曾运行过该节点将会返回null"/>
<TextBlock Margin="8,0,8,2" Foreground="#B06BBB" FontSize="14" Text=" 按 2 切换:立刻调用节点,取其返回值作为当前上下文的入参参数"/>
</StackPanel>
</StackPanel>
</Grid>
<GridSplitter Grid.Row="1" Grid.Column="3" Width="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ResizeBehavior="PreviousAndNext" Background="Gray" />
<!--IOC容器属性-->
<Grid Grid.Row="1" Grid.Column="4" >
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" >
<!--<themes:LazyTreeView x:Name="lazyTreeView" />-->
<themes:NodeTreeViewControl x:Name="NodeTreeViewer"></themes:NodeTreeViewControl>
</Grid>
<Grid Grid.Row="1" >
<themes:IOCObjectViewControl x:Name="IOCObjectViewer">
<!--<x:Arguments>
<x:String>Apple</x:String>
</x:Arguments>-->
</themes:IOCObjectViewControl>
</Grid>
<Grid Grid.Row="3" Margin="0,3,0,0" Grid.RowSpan="2">
<themes:ObjectViewerControl x:Name="ViewObjectViewer"></themes:ObjectViewerControl>
</Grid>
</Grid>
</Grid>
</Window>

File diff suppressed because it is too large Load Diff

View File

@@ -1,101 +0,0 @@
using Serein.Library.Api;
using Serein.Library.Utils;
using Serein.NodeFlow.Env;
using System.ComponentModel;
using System.Windows;
namespace Serein.Workbench
{
/// <summary>
/// 工作台数据视图
/// </summary>
/// <param name="window"></param>
public class MainWindowViewModel: INotifyPropertyChanged
{
private readonly MainWindow window ;
/// <summary>
/// 运行环境
/// </summary>
public IFlowEnvironment FlowEnvironment { get; set; }
/// <summary>
/// 工作台数据视图
/// </summary>
/// <param name="window"></param>
public MainWindowViewModel(MainWindow window)
{
UIContextOperation? uIContextOperation = null;
Application.Current.Dispatcher.Invoke(() =>
{
SynchronizationContext? uiContext = SynchronizationContext.Current; // 在UI线程上获取UI线程上下文信息
if (uiContext != null)
{
uIContextOperation = new UIContextOperation(uiContext); // 封装一个调用UI线程的工具类
}
});
if (uIContextOperation is null)
{
throw new Exception("无法封装 UIContextOperation ");
}
else
{
FlowEnvironment = new FlowEnvironmentDecorator(uIContextOperation);
//_ = FlowEnvironment.StartRemoteServerAsync();
this.window = window;
}
}
private bool _isConnectionInvokeNode = false;
/// <summary>
/// 是否正在连接节点的方法调用关系
/// </summary>
public bool IsConnectionInvokeNode { get => _isConnectionInvokeNode; set
{
if (_isConnectionInvokeNode != value)
{
SetProperty<bool>(ref _isConnectionInvokeNode, value);
}
}
}
private bool _isConnectionArgSouceNode = false;
/// <summary>
/// 是否正在连接节点的参数传递关系
/// </summary>
public bool IsConnectionArgSourceNode { get => _isConnectionArgSouceNode; set
{
if (_isConnectionArgSouceNode != value)
{
SetProperty<bool>(ref _isConnectionArgSouceNode, value);
}
}
}
/// <summary>
/// 略
/// <para>此事件为自动生成</para>
/// </summary>
public event PropertyChangedEventHandler? PropertyChanged;
/// <summary>
/// 通知属性变更
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="storage">绑定的变量</param>
/// <param name="value">新的数据</param>
/// <param name="propertyName"></param>
protected void SetProperty<T>(ref T storage, T value, [System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
{
if (Equals(storage, value))
{
return;
}
storage = value;
PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -1,48 +0,0 @@
using System.ComponentModel;
using Serein.Library;
using System.Runtime.CompilerServices;
using System.Windows.Controls;
using System.Windows.Data;
using System;
namespace Serein.Workbench.Node.ViewModel
{
public abstract class NodeControlViewModelBase
{
///// <summary>
///// 对应的节点实体类
///// </summary>
public NodeModelBase NodeModel { get; }
public NodeControlViewModelBase(NodeModelBase nodeModel)
{
NodeModel = nodeModel;
}
private bool isInterrupt;
///// <summary>
///// 控制中断状态的视觉效果
///// </summary>
public bool IsInterrupt
{
get => NodeModel.DebugSetting.IsInterrupt;
set
{
NodeModel.DebugSetting.IsInterrupt = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -1,118 +0,0 @@
<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>

View File

@@ -1,110 +0,0 @@
<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>

View File

@@ -1,58 +0,0 @@
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;
}
}
}
}

View File

@@ -1,22 +0,0 @@
<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>

View File

@@ -1,94 +0,0 @@
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);
}
}
}*/
}
}

View File

@@ -1,34 +0,0 @@
<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>

View File

@@ -1,164 +0,0 @@
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);
}
}
}
}
}

View File

@@ -1,47 +0,0 @@
<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>

View File

@@ -1,56 +0,0 @@
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;
}
}
}
}

View File

@@ -1,110 +0,0 @@
<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>

View File

@@ -1,72 +0,0 @@
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 [];
}
}
}
}
}

View File

@@ -1,13 +0,0 @@
using Serein.NodeFlow.Model;
using Serein.Workbench.Node.View;
namespace Serein.Workbench.Node.ViewModel
{
public class ActionNodeControlViewModel : NodeControlViewModelBase
{
public ActionNodeControlViewModel(SingleActionNode node) : base(node)
{
// this.NodelModel = node;
}
}
}

View File

@@ -1,54 +0,0 @@
using Serein.NodeFlow.Model;
using Serein.Workbench.Node.View;
namespace Serein.Workbench.Node.ViewModel
{
/// <summary>
/// 条件节点
/// </summary>
public class ConditionNodeControlViewModel : NodeControlViewModelBase
{
public new SingleConditionNode NodeModel { get; }
/// <summary>
/// 是否为自定义参数
/// </summary>
public bool IsCustomData
{
get => NodeModel.IsExplicitData;
set { NodeModel.IsExplicitData = value; OnPropertyChanged(); }
}
/// <summary>
/// 自定义参数值
/// </summary>
public string? CustomData
{
get => NodeModel.ExplicitData;
set { NodeModel.ExplicitData = value ; OnPropertyChanged(); }
}
/// <summary>
/// 表达式
/// </summary>
public string Expression
{
get => NodeModel.Expression;
set { NodeModel.Expression = value; OnPropertyChanged(); }
}
/// <summary>
/// 条件节点
/// </summary>
/// <param name="node"></param>
public ConditionNodeControlViewModel(SingleConditionNode node) : base(node)
{
this.NodeModel = node;
if(node is null)
{
IsCustomData = false;
CustomData = "";
Expression = "PASS";
}
}
}
}

View File

@@ -1,18 +0,0 @@
using Serein.NodeFlow.Model;
using Serein.Workbench.Node.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serein.Workbench.Node.ViewModel
{
public class ConditionRegionNodeControlViewModel : NodeControlViewModelBase
{
public ConditionRegionNodeControlViewModel(CompositeConditionNode node):base(node)
{
}
}
}

View File

@@ -1,14 +0,0 @@
using Serein.NodeFlow.Model;
using Serein.Workbench.Node.View;
namespace Serein.Workbench.Node.ViewModel
{
public class FlipflopNodeControlViewModel : NodeControlViewModelBase
{
public new SingleFlipflopNode NodelModel { get;}
public FlipflopNodeControlViewModel(SingleFlipflopNode node) : base(node)
{
this.NodelModel = node;
}
}
}

View File

@@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace Serein.Workbench.Node.ViewModel
{
public class TypeToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is Type type)
{
return type.ToString();
}
return string.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,74 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>True</UseWPF>
<BaseOutputPath>D:\Project\C#\DynamicControl\SereinFlow\.Output</BaseOutputPath>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<!--<IsRoslynComponent>true</IsRoslynComponent>-->
</PropertyGroup>
<ItemGroup>
<Compile Remove="Node\NodeModel\**" />
<Compile Remove="Themes\Condition\**" />
<EmbeddedResource Remove="Node\NodeModel\**" />
<EmbeddedResource Remove="Themes\Condition\**" />
<None Remove="Node\NodeModel\**" />
<None Remove="Themes\Condition\**" />
<Page Remove="Node\NodeModel\**" />
<Page Remove="Themes\Condition\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Node\FlipflopRegionControl.xaml.cs" />
<Compile Remove="Node\Junction\NodeJunctionViewBase.cs" />
<Compile Remove="Node\NodeBase.cs" />
<Compile Remove="Node\View\ActionRegionControl.xaml.cs" />
<Compile Remove="Themes\ConditionControl.xaml.cs" />
<Compile Remove="Themes\ConditionControlModel.cs" />
<Compile Remove="Themes\ConnectionControl.xaml.cs" />
<Compile Remove="Themes\ExplicitDataControl.xaml.cs" />
<Compile Remove="Themes\ObjectViewerControl1.xaml.cs" />
</ItemGroup>
<ItemGroup>
<Page Remove="Node\FlipflopRegionControl.xaml" />
<Page Remove="Node\View\ActionRegionControl.xaml" />
<Page Remove="Themes\ConditionControl.xaml" />
<Page Remove="Themes\ConnectionControl.xaml" />
<Page Remove="Themes\ExplicitDataControl.xaml" />
<Page Remove="Themes\MultiConditionConverter.xaml" />
<Page Remove="Themes\ObjectViewerControl1.xaml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Library.Core\Serein.Library.Core.csproj" />
<ProjectReference Include="..\Library.Framework\Serein.Library.Framework.csproj" />
<ProjectReference Include="..\Library\Serein.Library.csproj" />
<ProjectReference Include="..\NodeFlow\Serein.NodeFlow.csproj" />
<ProjectReference Include="..\Serein.Script\Serein.Script.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<!--<PackageReference Include="MySqlConnector" Version="2.4.0" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.170" />
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.171" />-->
<!--<PackageReference Include="LivetCask2" Version="4.0.2" />-->
<!--<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />-->
</ItemGroup>
<ItemGroup>
<Compile Update="Themes\MethodDetailsControl.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
</Project>

View File

@@ -1,288 +0,0 @@
<Project>
<PropertyGroup>
<AssemblyName>Serein.WorkBench</AssemblyName>
<IntermediateOutputPath>obj\Release\</IntermediateOutputPath>
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
<MSBuildProjectExtensionsPath>D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\</MSBuildProjectExtensionsPath>
<_TargetAssemblyProjectName>Serein.WorkBench</_TargetAssemblyProjectName>
</PropertyGroup>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>True</UseWPF>
<BaseOutputPath>D:\Project\C#\DynamicControl\SereinFlow\.Output</BaseOutputPath>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Node\NodeModel\**" />
<Compile Remove="Themes\Condition\**" />
<EmbeddedResource Remove="Node\NodeModel\**" />
<EmbeddedResource Remove="Themes\Condition\**" />
<None Remove="Node\NodeModel\**" />
<None Remove="Themes\Condition\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Node\FlipflopRegionControl.xaml.cs" />
<Compile Remove="Node\NodeBase.cs" />
<Compile Remove="Themes\ConditionControl.xaml.cs" />
<Compile Remove="Themes\ConditionControlModel.cs" />
<Compile Remove="Themes\ExplicitDataControl.xaml.cs" />
<Compile Remove="Themes\ObjectViewerControl1.xaml.cs" />
</ItemGroup>
<ItemGroup>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Library.Core\Serein.Library.Core.csproj" />
<ProjectReference Include="..\Library.Framework\Serein.Library.Framework.csproj" />
<ProjectReference Include="..\Library\Serein.Library.csproj" />
<ProjectReference Include="..\NodeFlow\Serein.NodeFlow.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<Compile Update="Themes\MethodDetailsControl.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\Accessibility.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\Microsoft.CSharp.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\Microsoft.VisualBasic.Core.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\Microsoft.VisualBasic.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\Microsoft.Win32.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\Microsoft.Win32.Registry.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\Microsoft.Win32.Registry.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\Microsoft.Win32.SystemEvents.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\mscorlib.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\netstandard.dll" />
<ReferencePath Include="C:\Users\Az\.nuget\packages\newtonsoft.json\13.0.3\lib\net6.0\Newtonsoft.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\PresentationCore.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\PresentationFramework.Aero.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\PresentationFramework.Aero2.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\PresentationFramework.AeroLite.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\PresentationFramework.Classic.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\PresentationFramework.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\PresentationFramework.Luna.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\PresentationFramework.Royale.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\PresentationUI.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\ReachFramework.dll" />
<ReferencePath Include="D:\Project\C#\DynamicControl\SereinFlow\.Output\Release\net8.0\Serein.Library.Core.dll" />
<ReferencePath Include="D:\Project\C#\DynamicControl\SereinFlow\.Output\Release\net8\Serein.Library.dll" />
<ReferencePath Include="D:\Project\C#\DynamicControl\SereinFlow\Library.Framework\bin\Release\Serein.Library.Framework.dll" />
<ReferencePath Include="D:\Project\C#\DynamicControl\SereinFlow\.Output\Release\net8.0\Serein.NodeFlow.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.AppContext.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Buffers.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.CodeDom.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Collections.Concurrent.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Collections.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Collections.Immutable.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Collections.NonGeneric.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Collections.Specialized.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.ComponentModel.Annotations.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.ComponentModel.DataAnnotations.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.ComponentModel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.ComponentModel.EventBasedAsync.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.ComponentModel.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.ComponentModel.TypeConverter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Configuration.ConfigurationManager.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Configuration.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Console.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Core.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Data.Common.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Data.DataSetExtensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Data.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Diagnostics.Contracts.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Diagnostics.Debug.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Diagnostics.DiagnosticSource.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Diagnostics.EventLog.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Diagnostics.FileVersionInfo.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Diagnostics.PerformanceCounter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Diagnostics.Process.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Diagnostics.StackTrace.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Diagnostics.TextWriterTraceListener.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Diagnostics.Tools.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Diagnostics.TraceSource.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Diagnostics.Tracing.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.DirectoryServices.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Drawing.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Drawing.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Dynamic.Runtime.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Formats.Asn1.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Formats.Tar.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Globalization.Calendars.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Globalization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Globalization.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.Compression.Brotli.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.Compression.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.Compression.FileSystem.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.Compression.ZipFile.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.FileSystem.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.FileSystem.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.FileSystem.DriveInfo.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.FileSystem.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.FileSystem.Watcher.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.IsolatedStorage.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.MemoryMappedFiles.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.IO.Packaging.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.Pipes.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.Pipes.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.IO.UnmanagedMemoryStream.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Linq.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Linq.Expressions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Linq.Parallel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Linq.Queryable.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Memory.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.Http.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.Http.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.HttpListener.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.Mail.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.NameResolution.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.NetworkInformation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.Ping.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.Quic.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.Requests.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.Security.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.ServicePoint.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.Sockets.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.WebClient.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.WebHeaderCollection.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.WebProxy.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.WebSockets.Client.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Net.WebSockets.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Numerics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Numerics.Vectors.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.ObjectModel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Printing.dll" />
<ReferencePath Include="C:\Users\Az\.nuget\packages\system.reactive\6.0.1\lib\net6.0\System.Reactive.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Reflection.DispatchProxy.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Reflection.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Reflection.Emit.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Reflection.Emit.ILGeneration.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Reflection.Emit.Lightweight.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Reflection.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Reflection.Metadata.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Reflection.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Reflection.TypeExtensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Resources.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Resources.Reader.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Resources.ResourceManager.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Resources.Writer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.CompilerServices.Unsafe.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.CompilerServices.VisualC.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.Handles.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.InteropServices.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.InteropServices.JavaScript.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.InteropServices.RuntimeInformation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.Intrinsics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.Loader.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.Numerics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.Serialization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.Serialization.Formatters.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.Serialization.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.Serialization.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Runtime.Serialization.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.Claims.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.Cryptography.Algorithms.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.Cryptography.Cng.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.Cryptography.Csp.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.Cryptography.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.Cryptography.Encoding.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.Cryptography.OpenSsl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Security.Cryptography.Pkcs.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.Cryptography.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Security.Cryptography.ProtectedData.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.Cryptography.X509Certificates.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Security.Cryptography.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Security.Permissions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.Principal.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.Principal.Windows.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Security.SecureString.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.ServiceModel.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.ServiceProcess.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Text.Encoding.CodePages.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Text.Encoding.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Text.Encoding.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Text.Encodings.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Text.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Text.RegularExpressions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Threading.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Threading.Channels.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Threading.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Threading.Overlapped.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Threading.Tasks.Dataflow.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Threading.Tasks.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Threading.Tasks.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Threading.Tasks.Parallel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Threading.Thread.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Threading.ThreadPool.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Threading.Timer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Transactions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Transactions.Local.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.ValueTuple.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Web.HttpUtility.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Windows.Controls.Ribbon.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Windows.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Windows.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Windows.Input.Manipulations.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Windows.Presentation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\System.Xaml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Xml.Linq.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Xml.ReaderWriter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Xml.Serialization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Xml.XDocument.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Xml.XmlDocument.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Xml.XmlSerializer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Xml.XPath.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\ref\net8.0\System.Xml.XPath.XDocument.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\UIAutomationClient.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\UIAutomationClientSideProviders.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\UIAutomationProvider.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\UIAutomationTypes.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.7\ref\net8.0\WindowsBase.dll" />
</ItemGroup>
<ItemGroup>
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\LogWindow.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\MainWindow.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\ActionNodeControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\ActionRegionControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\ConditionNodeControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\ConditionRegionControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\DllControlControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\ExpOpNodeControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\FlipflopNodeControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Themes\InputDialog.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Themes\IOCObjectViewControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Themes\NodeTreeItemViewControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Themes\NodeTreeViewControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Themes\ObjectViewerControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Themes\TypeViewerWindow.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\App.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\GeneratedInternalTypeHelper.g.cs" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="C:\Program Files\dotnet\sdk\8.0.303\Sdks\Microsoft.NET.Sdk\targets\..\analyzers\Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll" />
<Analyzer Include="C:\Program Files\dotnet\sdk\8.0.303\Sdks\Microsoft.NET.Sdk\targets\..\analyzers\Microsoft.CodeAnalysis.NetAnalyzers.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\analyzers/dotnet/cs/Microsoft.Interop.ComInterfaceGenerator.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\analyzers/dotnet/cs/Microsoft.Interop.JavaScript.JSImportGenerator.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\analyzers/dotnet/cs/Microsoft.Interop.LibraryImportGenerator.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\analyzers/dotnet/cs/Microsoft.Interop.SourceGeneration.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\analyzers/dotnet/cs/System.Text.Json.SourceGeneration.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.7\analyzers/dotnet/cs/System.Text.RegularExpressions.Generator.dll" />
</ItemGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>

View File

@@ -1,28 +0,0 @@
<UserControl x:Class="Serein.Workbench.Themes.IOCObjectViewControl"
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.Themes"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<!--<RowDefinition Height="*"/>
<RowDefinition Height="*"/>-->
</Grid.RowDefinitions>
<GroupBox Grid.Row="1" Header="实例视图" Margin="5">
<ListBox x:Name="DependenciesListBox" Background="#E3FAE9"/>
</GroupBox>
<!--<GroupBox Grid.Row="0" Header="正在注册的类型" Margin="5">
<ListBox x:Name="TypeListBox" Background="#E3F6FA"/>
</GroupBox>-->
<!--<GroupBox Grid.Row="1" Header="实例视图" Margin="5">
<ListBox x:Name="DependenciesListBox" Background="#E3FAE9"/>
</GroupBox>-->
<!--<GroupBox Grid.Row="3" Header="未完成注入的实例" Margin="5">
<ListBox x:Name="UnfinishedDependenciesListBox" Background="#FFE9D7"/>
</GroupBox>-->
</Grid>
</UserControl>

View File

@@ -1,128 +0,0 @@
using Serein.Library.Api;
using Serein.Library.Utils;
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.Controls.Primitives;
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.Xml.Linq;
namespace Serein.Workbench.Themes
{
/// <summary>
/// IOCObjectViewControl.xaml 的交互逻辑
/// </summary>
public partial class IOCObjectViewControl : UserControl
{
public Action<string,object> SelectObj { get; set; }
public IOCObjectViewControl()
{
InitializeComponent();
}
private class IOCObj
{
public string Key { get; set; }
public object Instance { get; set; }
}
/// <summary>
/// 运行环境
/// </summary>
public IFlowEnvironment FlowEnvironment { get; set; }
/// <summary>
/// 添加一个实例
/// </summary>
/// <param name="key"></param>
/// <param name="instance"></param>
public void AddDependenciesInstance(string key,object instance)
{
IOCObj iOCObj = new IOCObj
{
Key = key,
Instance = instance,
};
Application.Current.Dispatcher.Invoke(() =>
{
TextBlock textBlock = new TextBlock();
textBlock.Text = key;
textBlock.Tag = iOCObj;
textBlock.MouseDown += (s, e) =>
{
if (s is TextBlock block && block.Tag is IOCObj iocObj)
{
SelectObj?.Invoke(iocObj.Key, iocObj.Instance);
//FlowEnvironment.SetMonitorObjState(iocObj.Instance, true); // 通知环境该节点的数据更新后需要传到UI
}
};
DependenciesListBox.Items.Add(textBlock);
SortLisbox(DependenciesListBox);
});
}
/// <summary>
/// 刷新一个实例
/// </summary>
/// <param name="key"></param>
/// <param name="instance"></param>
public void RefreshDependenciesInstance(string key, object instance)
{
foreach (var item in DependenciesListBox.Items)
{
if (item is TextBlock block && block.Tag is IOCObj iocObj && iocObj.Key.Equals(key))
{
iocObj.Instance = instance;
}
}
}
public void ClearObjItem()
{
DependenciesListBox.Dispatcher.Invoke(() =>
{
DependenciesListBox.Items.Clear();
});
}
private static void SortLisbox(ListBox listBox)
{
var sortedItems = listBox.Items.Cast<TextBlock>().OrderBy(x => x.Text).ToList();
listBox.Items.Clear();
foreach (var item in sortedItems)
{
listBox.Items.Add(item);
}
}
public void RemoveDependenciesInstance(string key)
{
object? itemControl = null;
foreach (var item in DependenciesListBox.Items)
{
if (item is TextBlock block && block.Tag is IOCObj iocObj && iocObj.Key.Equals(key))
{
itemControl = item;
}
}
if (itemControl is not null)
{
DependenciesListBox.Items.Remove(itemControl);
}
}
}
}

View File

@@ -1,16 +0,0 @@
<Window x:Class="Serein.Workbench.Themes.InputDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Serein.Workbench.Themes"
mc:Ignorable="d"
Title="InputDialog" Height="450" Width="800">
<StackPanel Margin="10">
<TextBox x:Name="InputTextBox" Width="200" Margin="0,0,0,10" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="确认" Click="ConfirmButton_Click" Margin="5" />
<Button Content="取消" Click="CancelButton_Click" Margin="5" />
</StackPanel>
</StackPanel>
</Window>

View File

@@ -1,42 +0,0 @@
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.Shapes;
namespace Serein.Workbench.Themes
{
/// <summary>
/// InputDialog.xaml 的交互逻辑
/// </summary>
public partial class InputDialog : Window
{
public string InputValue { get; private set; }
public InputDialog()
{
InitializeComponent();
}
private void ConfirmButton_Click(object sender, RoutedEventArgs e)
{
InputValue = InputTextBox.Text;
DialogResult = true; // 设置返回结果为 true
Close(); // 关闭窗口
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
DialogResult = false; // 设置返回结果为 false
Close(); // 关闭窗口
}
}
}

View File

@@ -1,129 +0,0 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Serein.Workbench.Themes"
xmlns:view="clr-namespace:Serein.Workbench.Node.View"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:converters="clr-namespace:Serein.Workbench.Tool.Converters">
<ResourceDictionary.MergedDictionaries>
</ResourceDictionary.MergedDictionaries>
<converters:InvertableBooleanToVisibilityConverter x:Key="InvertedBoolConverter"/>
<Style TargetType="{x:Type local:MethodDetailsControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MethodDetailsControl}">
<!--根据方法入参数量生成相应的控件-->
<ItemsControl ItemsSource="{Binding MethodDetails.ParameterDetailss, RelativeSource={RelativeSource TemplatedParent}}" Background="#E3FDFD" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<!--连接控制器-->
<view:ArgJunctionControl x:Name="ArgJunctionControl" Grid.Column="0" ArgIndex="{Binding Index}" MyNode="{Binding NodeModel}" />
<!--参数索引提示-->
<TextBlock Grid.Column="1" Text="{Binding Index,StringFormat=agr{0}}" Margin="2,0,2,0" VerticalAlignment="Center"/>
<!--是否设置为显式参数-->
<CheckBox Grid.Column="2" IsChecked="{Binding IsExplicitData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="2,0,2,0" VerticalContentAlignment="Center"/>
<!--入参参数名称-->
<TextBlock Grid.Column="3" MinWidth="50" Text="{Binding Name}" Margin="2,0,2,0" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<!--增加可选参数(如果有)-->
<view:ParamsArgControl x:Name="ParamsArgControl"
ArgIndex="{Binding Index}"
MyNode="{Binding NodeModel}"
Width="12"
Grid.Column="5" Margin="2,0,2,0" HorizontalAlignment="Right" VerticalAlignment="Center"
Visibility="{Binding IsParams, Mode=OneWay,
Converter={StaticResource InvertedBoolConverter},ConverterParameter=Normal}"
/>
<ContentControl Content="{Binding}" Grid.Column="4" VerticalAlignment="Center">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<!--无须指定参数-->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsExplicitData}" Value="false" />
</MultiDataTrigger.Conditions>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" MinWidth="50" Text="无须指定参数"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</MultiDataTrigger>
<!--指定参数:选项类型-->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsExplicitData}" Value="true" />
<Condition Binding="{Binding ExplicitTypeName}" Value="Select" />
</MultiDataTrigger.Conditions>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ComboBox Grid.Column="0"
MinWidth="50"
ItemsSource="{Binding Items}"
SelectedItem="{Binding DataValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</MultiDataTrigger>
<!--指定参数:文本类型(可输入)-->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsExplicitData}" Value="true" />
<Condition Binding="{Binding ExplicitTypeName}" Value="Value" />
</MultiDataTrigger.Conditions>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" MinWidth="50" Text="{Binding DataValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -1,90 +0,0 @@
using Serein.Library;
using Serein.Workbench.Node;
using System.Collections;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
namespace Serein.Workbench.Themes
{
public class MultiConditionConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length == 2 && values[0] is Type valueType && values[1] is bool isEnabled)
{
if (isEnabled)
{
// 返回文本框
if (valueType == typeof(string) || valueType == typeof(int) || valueType == typeof(double))
{
return "TextBoxTemplate";
}
// 返回可选列表框
else if (typeof(IEnumerable).IsAssignableFrom(valueType))
{
return "ComboBoxTemplate";
}
}
}
return DependencyProperty.UnsetValue;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 方法参数控件
/// </summary>
public partial class MethodDetailsControl : UserControl
{
static MethodDetailsControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MethodDetailsControl), new FrameworkPropertyMetadata(typeof(MethodDetailsControl)));
}
#region
public MethodDetails MethodDetails
{
get { return (MethodDetails)GetValue(MethodDetailsProperty); }
set { SetValue(MethodDetailsProperty, value); }
}
public static readonly DependencyProperty MethodDetailsProperty = DependencyProperty.Register(nameof(MethodDetails), typeof(MethodDetails),
typeof(MethodDetailsControl), new PropertyMetadata(null, new PropertyChangedCallback(OnPropertyChange)));
#endregion
static void OnPropertyChange(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
//var MethodDetails = (MethodDetails)args.NewValue;
//MethodDetails.ExplicitDatas[0].
}
public ICommand CommandAddParams { get; }
public MethodDetailsControl()
{
CommandAddParams = new RelayCommand(ExecuteAddParams);
}
private void ExecuteAddParams(object parameter)
{
// 方法逻辑
this.MethodDetails.AddParamsArg();
}
}
}

View File

@@ -1,59 +0,0 @@
<UserControl x:Class="Serein.Workbench.Themes.NodeTreeItemViewControl"
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.Themes"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="200">
<UserControl.Resources>
<Style x:Key="CustomTreeViewItemStyle" TargetType="TreeViewItem">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" x:Name="UpstreamTreeGuid" Margin="0,0,0,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Width="1" x:Name="UpstreamTreeRectangle" Grid.Row="0" Fill="#4A82E4" Margin="4,1,4,1" IsHitTestVisible="False"/>
<TreeView Grid.Column="1" x:Name="UpstreamTreeNodes" BorderThickness="0" ItemContainerStyle="{StaticResource CustomTreeViewItemStyle}"/>
</Grid>
<Grid Grid.Row="1" x:Name="IsSucceedTreeGuid" Margin="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Width="1" x:Name="IsSucceedRectangle" Grid.Row="0" Fill="#04FC10" Margin="4,1,4,1" IsHitTestVisible="False"/>
<TreeView Grid.Column="1" x:Name="IsSucceedTreeNodes" BorderThickness="0" ItemContainerStyle="{StaticResource CustomTreeViewItemStyle}"/>
</Grid>
<Grid Grid.Row="2" x:Name="IsFailTreeGuid" Margin="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Width="1" x:Name="IsFailRectangle" Grid.Row="0" Fill="#F18905" Margin="4,1,4,1" IsHitTestVisible="False"/>
<TreeView Grid.Column="1" x:Name="IsFailTreeNodes" BorderThickness="0" ItemContainerStyle="{StaticResource CustomTreeViewItemStyle}"/>
</Grid>
<Grid Grid.Row="3" x:Name="IsErrorTreeGuid" Margin="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Width="1" x:Name="IsErrorRectangle" Grid.Row="0" Fill="#FE1343" Margin="4,1,4,1" IsHitTestVisible="False"/>
<TreeView Grid.Column="1" x:Name="IsErrorTreeNodes" BorderThickness="0" ItemContainerStyle="{StaticResource CustomTreeViewItemStyle}"/>
</Grid>
</Grid>
</UserControl>

View File

@@ -1,280 +0,0 @@
using Serein.Library;
using Serein.Library.Api;
using Serein.Library.Utils;
using System.Windows;
using System.Windows.Controls;
namespace Serein.Workbench.Themes
{
/// <summary>
/// NodeTreeVIewControl.xaml 的交互逻辑
/// </summary>
public partial class NodeTreeItemViewControl : UserControl
{
public NodeTreeItemViewControl()
{
InitializeComponent();
foreach (var ct in NodeStaticConfig.ConnectionTypes)
{
var guid = ToGridView(this, ct);
guid.Visibility = Visibility.Collapsed;
}
}
/// <summary>
/// 保存的节点数据
/// </summary>
private NodeModelBase nodeModel;
private IFlowEnvironment flowEnvironment { get; set; }
private class NodeTreeModel
{
public NodeModelBase RootNode { get; set; }
public Dictionary<ConnectionInvokeType, List<NodeModelBase>> ChildNodes { get; set; }
}
public void InitAndLoadTree(IFlowEnvironment flowEnvironment, NodeModelBase nodeModel)
{
this.flowEnvironment = flowEnvironment;
this.nodeModel = nodeModel;
RefreshTree();
}
public TreeViewItem RefreshTree()
{
NodeModelBase rootNodeModel = this.nodeModel;
NodeTreeModel nodeTreeModel = new NodeTreeModel
{
RootNode = rootNodeModel,
ChildNodes = new Dictionary<ConnectionInvokeType, List<NodeModelBase>>()
{
{ConnectionInvokeType.Upstream, []},
{ConnectionInvokeType.IsSucceed, [rootNodeModel]},
{ConnectionInvokeType.IsFail, []},
{ConnectionInvokeType.IsError, []},
}
};
string? itemName = rootNodeModel.MethodDetails?.MethodAnotherName;
if (string.IsNullOrEmpty(itemName))
{
itemName = rootNodeModel.ControlType.ToString();
}
var rootNode = new TreeViewItem
{
Header = itemName,
Tag = nodeTreeModel,
};
LoadNodeItem(this, nodeTreeModel);
rootNode.Expanded += TreeViewItem_Expanded; // 监听展开事件
rootNode.IsExpanded = true;
return rootNode;
}
/// <summary>
/// 展开子项事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
{
if (sender is TreeViewItem item && item.Tag is NodeTreeModel nodeTreeModel)
{
item.Items.Clear();
NodeTreeItemViewControl? nodeTreeItemViewControl = LoadTNoderee(nodeTreeModel);
if (nodeTreeItemViewControl is not null)
{
LoadNodeItem(nodeTreeItemViewControl, nodeTreeModel);
item.Items.Add(nodeTreeItemViewControl);
}
item.IsSelected = false;
}
e.Handled = true;
}
/// <summary>
/// 加载面板
/// </summary>
/// <param name="nodeTreeItemViewControl"></param>
/// <param name="nodeTreeModel"></param>
private void LoadNodeItem(NodeTreeItemViewControl nodeTreeItemViewControl, NodeTreeModel nodeTreeModel)
{
foreach (var ct in NodeStaticConfig.ConnectionTypes)
{
var treeViewer = ToTreeView(nodeTreeItemViewControl, ct);
var guid = ToGridView(nodeTreeItemViewControl, ct);
treeViewer.Items.Clear(); // 移除对象树的所有节点
var list = nodeTreeModel.ChildNodes[ct];
if (list.Count > 0)
{
foreach (var child in list)
{
NodeTreeModel tmpNodeTreeModel = new NodeTreeModel
{
RootNode = child,
ChildNodes = child.SuccessorNodes,
};
string? itemName = child?.MethodDetails?.MethodAnotherName;
if (string.IsNullOrEmpty(itemName))
{
itemName = child?.ControlType.ToString();
}
TreeViewItem treeViewItem = new TreeViewItem
{
Header = itemName,
Tag = tmpNodeTreeModel
};
treeViewItem.Expanded += TreeViewItem_Expanded;
var contextMenu = new ContextMenu();
contextMenu.Items.Add(MainWindow.CreateMenuItem("从此节点执行", async (s, e) =>
{
try
{
await flowEnvironment.StartAsyncInSelectNode(tmpNodeTreeModel.RootNode.Guid);
}
catch (Exception ex)
{
SereinEnv.WriteLine(ex);
return;
}
}));
contextMenu.Items.Add(MainWindow.CreateMenuItem("定位", (s, e) => flowEnvironment.NodeLocated(tmpNodeTreeModel.RootNode.Guid)));
treeViewItem.ContextMenu = contextMenu;
treeViewItem.Margin = new Thickness(-20, 0, 0, 0);
treeViewer.Items.Add(treeViewItem);
}
guid.Visibility = Visibility.Visible;
}
else
{
guid.Visibility = Visibility.Collapsed;
}
}
}
/// <summary>
/// 加载节点子项
/// </summary>
/// <param name="nodeTreeModel"></param>
/// <returns></returns>
private NodeTreeItemViewControl? LoadTNoderee(NodeTreeModel nodeTreeModel)
{
NodeTreeItemViewControl nodeTreeItemViewControl = null;
foreach (var connectionType in NodeStaticConfig.ConnectionTypes)
{
var childNodeModels = nodeTreeModel.ChildNodes[connectionType];
if (childNodeModels.Count > 0)
{
nodeTreeItemViewControl ??= new NodeTreeItemViewControl();
}
else
{
continue;
}
TreeView treeView = ToTreeView(nodeTreeItemViewControl, connectionType);
foreach (var childNodeModel in childNodeModels)
{
NodeTreeModel tempNodeTreeModel = new NodeTreeModel
{
RootNode = childNodeModel,
ChildNodes = childNodeModel.SuccessorNodes,
};
string? itemName = childNodeModel?.MethodDetails?.MethodAnotherName;
if (string.IsNullOrEmpty(itemName))
{
itemName = childNodeModel?.ControlType.ToString();
}
TreeViewItem treeViewItem = new TreeViewItem
{
Header = itemName,
Tag = tempNodeTreeModel
};
treeViewItem.Margin = new Thickness(-20, 0, 0, 0);
treeViewItem.Visibility = Visibility.Visible;
treeView.Items.Add(treeViewItem);
}
}
if (nodeTreeItemViewControl is not null)
{
foreach (var connectionType in NodeStaticConfig.ConnectionTypes)
{
var childNodeModels = nodeTreeModel.ChildNodes[connectionType];
if (childNodeModels.Count > 0)
{
nodeTreeItemViewControl ??= new NodeTreeItemViewControl();
}
else
{
continue;
}
}
}
return nodeTreeItemViewControl;
}
/// <summary>
/// 折叠事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TreeViewItem_Collapsed(object sender, RoutedEventArgs e)
{
if (sender is TreeViewItem item && item.Items.Count > 0)
{
item.Items.Clear();
}
}
public static TreeView ToTreeView(NodeTreeItemViewControl item, ConnectionInvokeType connectionType)
{
return connectionType switch
{
ConnectionInvokeType.Upstream => item.UpstreamTreeNodes,
ConnectionInvokeType.IsError => item.IsErrorTreeNodes,
ConnectionInvokeType.IsFail => item.IsFailTreeNodes,
ConnectionInvokeType.IsSucceed => item.IsSucceedTreeNodes,
_ => throw new Exception("LoadNodeItem Error ConnectionType is " + connectionType)
};
}
public static Grid ToGridView(NodeTreeItemViewControl item, ConnectionInvokeType connectionType)
{
return connectionType switch
{
ConnectionInvokeType.Upstream => item.UpstreamTreeGuid,
ConnectionInvokeType.IsError => item.IsErrorTreeGuid,
ConnectionInvokeType.IsFail => item.IsFailTreeGuid,
ConnectionInvokeType.IsSucceed => item.IsSucceedTreeGuid,
_ => throw new Exception("LoadNodeItem Error ConnectionType is " + connectionType)
};
}
//public static System.Windows.Shapes.Rectangle ToRectangle(NodeTreeItemViewControl item, ConnectionType connectionType)
//{
// return connectionType switch
// {
// ConnectionType.Upstream => item.UpstreamTreeRectangle,
// ConnectionType.IsError => item.IsErrorRectangle,
// ConnectionType.IsFail => item.IsFailRectangle,
// ConnectionType.IsSucceed => item.IsSucceedRectangle,
// _ => throw new Exception("LoadNodeItem Error ConnectionType is " + connectionType)
// };
//}
}
}

View File

@@ -1,47 +0,0 @@
<UserControl x:Class="Serein.Workbench.Themes.NodeTreeViewControl"
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.Themes"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<Style x:Key="ListItemNullFocusContainerStyle" TargetType="ListBoxItem">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="Border" Background="Transparent" SnapsToDevicePixels="True">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<!--<RowDefinition Height="*"/>-->
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock Text="起始节点"/>
<ScrollViewer >
<local:NodeTreeItemViewControl x:Name="StartNodeViewer" Margin="4,4,4,4"/>
</ScrollViewer >
</StackPanel>
<StackPanel Grid.Row="1">
<TextBlock Text="全局触发器"/>
<ListBox x:Name="GlobalFlipflopNodeListbox" BorderThickness="0" ItemContainerStyle="{StaticResource ListItemNullFocusContainerStyle}"></ListBox>
</StackPanel>
<!--<StackPanel Grid.Row="2">
<TextBlock Text="无业游民"/>
<ListBox x:Name="UnreachableNodeListbox" BorderThickness="0" ItemContainerStyle="{StaticResource ListItemNullFocusContainerStyle}"></ListBox>
</StackPanel>-->
</Grid>
</UserControl>

View File

@@ -1,85 +0,0 @@
using Serein.Library;
using Serein.Library.Api;
using System.Windows.Controls;
namespace Serein.Workbench.Themes
{
/// <summary>
/// NodeTreeViewControl.xaml 的交互逻辑
/// </summary>
public partial class NodeTreeViewControl : UserControl
{
public NodeTreeViewControl()
{
InitializeComponent();
}
private string startNodeGuid = string.Empty;
private Dictionary<string, NodeTreeItemViewControl> globalFlipflopNodes = [];
private Dictionary<string, NodeTreeItemViewControl> unemployedNodes = [];
public void LoadNodeTreeOfStartNode(IFlowEnvironment flowEnvironment, NodeModelBase nodeModel)
{
startNodeGuid = nodeModel.Guid;
StartNodeViewer.InitAndLoadTree(flowEnvironment, nodeModel);
}
#region
public void AddGlobalFlipFlop(IFlowEnvironment flowEnvironment, NodeModelBase nodeModel)
{
if (!globalFlipflopNodes.ContainsKey(nodeModel.Guid))
{
NodeTreeItemViewControl flipflopTreeViewer = new NodeTreeItemViewControl();
flipflopTreeViewer.InitAndLoadTree(flowEnvironment, nodeModel);
globalFlipflopNodes.Add(nodeModel.Guid, flipflopTreeViewer);
GlobalFlipflopNodeListbox.Items.Add(flipflopTreeViewer);
}
}
public void RefreshGlobalFlipFlop(NodeModelBase nodeModel)
{
if (globalFlipflopNodes.TryGetValue(nodeModel.Guid, out var viewer))
{
viewer.RefreshTree();
}
}
public void RemoveGlobalFlipFlop(NodeModelBase nodeModel)
{
if (globalFlipflopNodes.TryGetValue(nodeModel.Guid, out var viewer))
{
globalFlipflopNodes.Remove(nodeModel.Guid);
GlobalFlipflopNodeListbox.Items.Remove(viewer);
}
}
#endregion
#region
public void AddUnemployed(IFlowEnvironment flowEnvironment, NodeModelBase nodeModel)
{
if (!unemployedNodes.ContainsKey(nodeModel.Guid))
{
NodeTreeItemViewControl flipflopTreeViewer = new NodeTreeItemViewControl();
flipflopTreeViewer.InitAndLoadTree(flowEnvironment, nodeModel);
unemployedNodes.Add(nodeModel.Guid, flipflopTreeViewer);
GlobalFlipflopNodeListbox.Items.Add(flipflopTreeViewer);
}
}
public void RefreshUnemployed(NodeModelBase nodeModel)
{
if (unemployedNodes.TryGetValue(nodeModel.Guid, out var viewer))
{
viewer.RefreshTree();
}
}
public void RemoteUnemployed(NodeModelBase nodeModel)
{
if (unemployedNodes.TryGetValue(nodeModel.Guid, out var viewer))
{
unemployedNodes.Remove(nodeModel.Guid);
GlobalFlipflopNodeListbox.Items.Remove(viewer);
}
}
#endregion
}
}

View File

@@ -1,31 +0,0 @@
<UserControl x:Class="Serein.Workbench.Themes.ObjectViewerControl"
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.Themes"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<!-- 按钮 -->
<RowDefinition Height="*" />
<!-- 树视图 -->
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0" >
<!---->
<!--<Button Grid.Row="0" HorizontalAlignment="Left" Margin="14,2,4,2" Content="监视" Width="100" Height="20" Name="TimerRefreshButton"/>-->
<!--<Button Grid.Row="0" HorizontalAlignment="Left" Margin="14,2,4,2" Content="添加监视表达式" Width="100" Height="20" Name="AddMonitorExpressionButton" Click="AddMonitorExpressionButton_Click"/>-->
<Button Grid.Row="0" HorizontalAlignment="Left" Margin="4,2,4,2" Content="刷新" Width="40" Height="20" Name="RefreshButton" Click="RefreshButton_Click"/>
<Button Grid.Row="0" HorizontalAlignment="Left" Margin="4,2,4,2" Content="添加监视表达式" Width="80" Height="20" Name="UpMonitorExpressionButton" Click="UpMonitorExpressionButton_Click"/>
<TextBox x:Name="ExpressionTextBox" Margin="4,2,4,2" Width="300"/>
</StackPanel>
<!-- 刷新按钮 -->
<!-- 树视图,用于显示对象属性 -->
<TreeView FontSize="14" x:Name="ObjectTreeView" Grid.Row="1" />
</Grid>
</UserControl>

View File

@@ -1,670 +0,0 @@
using Newtonsoft.Json.Linq;
using Serein.Library.Api;
using Serein.Library.Utils.SereinExpression;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Security.Cryptography;
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.Markup.Primitives;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml.Linq;
using static Serein.Workbench.Themes.TypeViewerWindow;
namespace Serein.Workbench.Themes
{
public class FlowDataDetails
{
/// <summary>
/// 属性名称
/// </summary>
public string? Name { get; set; }
/// <summary>
/// 属性类型
/// </summary>
public TreeItemType ItemType { get; set; }
/// <summary>
/// 数据类型
/// </summary>
public Type? DataType { get; set; }
/// <summary>
/// 数据
/// </summary>
public object? DataValue { get; set; }
/// <summary>
/// 数据路径
/// </summary>
public string DataPath { get; set; } = string.Empty;
}
/// <summary>
/// ObjectViewerControl.xaml 的交互逻辑
/// </summary>
public partial class ObjectViewerControl : UserControl
{
public ObjectViewerControl()
{
InitializeComponent();
}
/// <summary>
/// 监视类型
/// </summary>
public enum MonitorType
{
/// <summary>
/// 作用于对象(对象的引用)的监视
/// </summary>
NodeFlowData,
/// <summary>
/// 作用与节点FLowData的监视
/// </summary>
IOCObj,
}
/// <summary>
/// 运行环境
/// </summary>
public IFlowEnvironment? FlowEnvironment { get; set; }
/// <summary>
/// 监视对象的键
/// </summary>
public string? MonitorKey { get => monitorKey; }
/// <summary>
/// 正在监视的对象
/// </summary>
public object? MonitorObj { get => monitorObj; }
/// <summary>
/// 监视表达式
/// </summary>
public string? MonitorExpression { get => ExpressionTextBox.Text.ToString(); }
private string? monitorKey;
private object? monitorObj;
// 用于存储当前展开的节点路径
private HashSet<string> expandedNodePaths = new HashSet<string>();
/// <summary>
/// 加载对象信息,展示其成员
/// </summary>
/// <param name="obj">要展示的对象</param>
public void LoadObjectInformation(string key, object obj)
{
if (obj == null) return;
monitorKey = key;
monitorObj = obj;
expandedNodePaths.Clear();
LoadTree(obj);
}
/// <summary>
/// 刷新对象
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RefreshButton_Click(object sender, RoutedEventArgs e)
{
RefreshObjectTree(monitorObj);
}
/// <summary>
/// 更新表达式
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void UpMonitorExpressionButton_Click(object sender, RoutedEventArgs e)
{
//if (FlowEnvironment is not null && await FlowEnvironment.AddInterruptExpressionAsync(monitorKey, MonitorExpression)) // 对象预览器尝试添加中断表达式
//{
// if (string.IsNullOrEmpty(MonitorExpression))
// {
// ExpressionTextBox.Text = "表达式已清空";
// }
// else
// {
// UpMonitorExpressionButton.Content = "更新监视表达式";
// }
//}
}
private TreeViewItem? LoadTree(object? obj)
{
if (obj is null) return null;
var objectType = obj.GetType();
FlowDataDetails flowDataDetails = new FlowDataDetails
{
Name = objectType.Name,
DataType = objectType,
DataValue = obj,
DataPath = ""
};
var rootNode = new TreeViewItem
{
Header = objectType.Name,
Tag = flowDataDetails,
};
ObjectTreeView.Items.Clear(); // 移除对象树的所有节点
ObjectTreeView.Items.Add(rootNode); // 添加所有节点
rootNode.Expanded += TreeViewItem_Expanded; // 监听展开事件
rootNode.Collapsed += TreeViewItem_Collapsed; // 监听折叠事件
// 这里创建了一个子项,并给这个子项创建了“正在加载”的子项
// 然后移除了原来对象树的所有项,再把这个新创建的子项添加上去
// 绑定了展开/折叠事件后自动展开第一层开始反射obj的成员并判断obj的成员生成什么样的节点
rootNode.IsExpanded = true;
return rootNode;
}
/// <summary>
/// 刷新对象属性树
/// </summary>
public void RefreshObjectTree(object? obj)
{
monitorObj = obj;
var rootNode = LoadTree(obj);
if (rootNode is not null)
{
ExpandPreviouslyExpandedNodes(rootNode); // 遍历节点,展开之前记录的节点
}
}
/// <summary>
/// 展开父节点,如果路径存在哈希记录,则将其自动展开,并递归展开后的子节点。
/// </summary>
/// <param name="node"></param>
private void ExpandPreviouslyExpandedNodes(TreeViewItem node)
{
if (node == null) return;
if(node.Tag is FlowDataDetails flowDataDetails)
{
if (expandedNodePaths.Contains(flowDataDetails.DataPath))
{
node.IsExpanded = true;
}
}
foreach (TreeViewItem child in node.Items)
{
ExpandPreviouslyExpandedNodes(child);
}
}
/// <summary>
/// 展开子项事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
{
if (sender is TreeViewItem item)
{
if (item.Tag is FlowDataDetails flowDataDetails) // FlowDataDetails flowDataDetails object obj
{
if (flowDataDetails.ItemType != TreeItemType.Item && item.Items.Count != 0)
{
return;
}
if(flowDataDetails.DataValue is null || flowDataDetails.DataType is null)
{
return;
}
// 记录当前节点的路径
var path = flowDataDetails.DataPath;
expandedNodePaths.Add(path);
AddMembersToTreeNode(item, flowDataDetails.DataValue, flowDataDetails.DataType);
}
}
}
/// <summary>
/// 折叠事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TreeViewItem_Collapsed(object sender, RoutedEventArgs e)
{
if (sender is TreeViewItem item && item.Items.Count > 0)
{
if (item.Tag is FlowDataDetails flowDataDetails)
{
// 记录当前节点的路径
var path = flowDataDetails.DataPath;
if(path != "")
{
expandedNodePaths.Remove(path);
}
}
}
}
/// <summary>
/// 反射对象数据添加子节点
/// </summary>
/// <param name="treeViewNode"></param>
/// <param name="obj"></param>
/// <param name="type"></param>
private void AddMembersToTreeNode(TreeViewItem treeViewNode, object obj, Type type)
{
// 获取公开的属性
var members = type.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
foreach (var member in members)
{
if (member.Name.StartsWith(".") ||
member.Name.StartsWith("get_") ||
member.Name.StartsWith("set_")
)
{
// 跳过构造函数、属性的get/set方法
continue;
}
TreeViewItem? memberNode = ConfigureTreeViewItem(obj, member); // 根据对象成员生成节点对象
if (memberNode is not null)
{
treeViewNode.Items.Add(memberNode); // 添加到当前节点
// 配置数据路径
FlowDataDetails subFlowDataDetails = (FlowDataDetails)memberNode.Tag;
string superPath = ((FlowDataDetails)treeViewNode.Tag).DataPath;
string subPath = superPath + "." + subFlowDataDetails.Name;
subFlowDataDetails.DataPath = subPath;
// 配置右键菜单
var contextMenu = new ContextMenu();
contextMenu.Items.Add(MainWindow.CreateMenuItem($"表达式", (s, e) =>
{
ExpressionTextBox.Text = subPath; // 获取表达式
}));
memberNode.ContextMenu = contextMenu;
}
}
}
/// <summary>
/// 配置节点子项
/// </summary>
/// <param name="obj"></param>
/// <param name="member"></param>
/// <returns></returns>
private TreeViewItem? ConfigureTreeViewItem(object obj, MemberInfo member)
{
if (obj == null)
{
return null;
}
#region
if (member is PropertyInfo property)
{
#region (
if (property.PropertyType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(property.PropertyType) && property.GetValue(obj) is IEnumerable collection && collection is not null)
{
TreeViewItem memberNode = new TreeViewItem { Header = member.Name };
// 处理集合类型的属性
memberNode.Tag = new FlowDataDetails
{
ItemType = TreeItemType.IEnumerable,
DataType = property.PropertyType,
Name = property.Name,
DataValue = collection,
};
int index = 0;
foreach (var item in collection)
{
var itemNode = new TreeViewItem { Header = $"[{index++}] {item}" ?? "null" };
memberNode.Tag = new FlowDataDetails
{
ItemType = TreeItemType.Item,
DataType = item?.GetType(),
Name = property.Name,
DataValue = itemNode,
};
memberNode.Items.Add(itemNode);
}
memberNode.Header = $"{property.Name} : {property.PropertyType.Name} [{index}]";
if (!property.PropertyType.IsPrimitive && property.PropertyType != typeof(string))
{
memberNode.Expanded += TreeViewItem_Expanded;
memberNode.Collapsed += TreeViewItem_Collapsed;
}
return memberNode;
}
#endregion
#region
else
{
TreeViewItem memberNode = new TreeViewItem { Header = member.Name };
string propertyValue = GetPropertyValue(obj, property, out object? value);
memberNode.Tag = new FlowDataDetails
{
ItemType = TreeItemType.Property,
DataType = property.PropertyType,
Name = property.Name,
DataValue = value,
}; ;
memberNode.Header = $"{property.Name} : {property.PropertyType.Name} = {propertyValue}";
if (!property.PropertyType.IsPrimitive && property.PropertyType != typeof(string))
{
memberNode.Expanded += TreeViewItem_Expanded;
memberNode.Collapsed += TreeViewItem_Collapsed;
}
return memberNode;
}
#endregion
}
#endregion
#region
else if (member is FieldInfo field)
{
#region (
if (field.FieldType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(field.FieldType) && field.GetValue(obj) is IEnumerable collection && collection is not null)
{
TreeViewItem memberNode = new TreeViewItem { Header = member.Name };
// 处理集合类型的字段
memberNode.Tag = new FlowDataDetails
{
ItemType = TreeItemType.IEnumerable,
DataType = field.FieldType,
Name = field.Name,
DataValue = collection,
};
int index = 0;
foreach (var item in collection)
{
var itemNode = new TreeViewItem { Header = $"[{index++}] {item}" ?? "null" };
memberNode.Tag = new FlowDataDetails
{
ItemType = TreeItemType.Item,
DataType = item?.GetType(),
Name = field.Name,
DataValue = itemNode,
};
//collectionNode.Items.Add(itemNode);
memberNode.Items.Add(itemNode);
}
memberNode.Header = $"{field.Name} : {field.FieldType.Name} [{index}]";
if (!field.FieldType.IsPrimitive && field.FieldType != typeof(string))
{
memberNode.Expanded += TreeViewItem_Expanded;
memberNode.Collapsed += TreeViewItem_Collapsed;
}
return memberNode;
}
#endregion
#region
else
{
TreeViewItem memberNode = new TreeViewItem { Header = member.Name };
string fieldValue = GetFieldValue(obj, field, out object? value);
memberNode.Tag = new FlowDataDetails
{
ItemType = TreeItemType.Field,
DataType = field.FieldType,
Name = field.Name,
DataValue = value,
};
memberNode.Header = $"{field.Name} : {field.FieldType.Name} = {fieldValue}";
if (!field.FieldType.IsPrimitive && field.FieldType != typeof(string))
{
memberNode.Expanded += TreeViewItem_Expanded;
memberNode.Collapsed += TreeViewItem_Collapsed;
}
return memberNode;
}
#endregion
}
#endregion
#region null
else
{
return null;
}
#endregion
}
/// <summary>
/// 获取属性类型的成员
/// </summary>
/// <param name="obj"></param>
/// <param name="property"></param>
/// <returns></returns>
private string GetPropertyValue(object obj, PropertyInfo property,out object? value)
{
try
{
if(obj is null)
{
value = null;
return "Error";
}
var properties = obj.GetType().GetProperties();
// 获取实例属性值
value = property.GetValue(obj);
return value?.ToString() ?? "null"; // 返回值或“null”
}
catch
{
value = null;
return "Error";
}
}
/// <summary>
/// 获取字段类型的成员
/// </summary>
/// <param name="obj"></param>
/// <param name="field"></param>
/// <returns></returns>
private string GetFieldValue(object obj, FieldInfo field, out object? value)
{
try
{
value = field.GetValue(obj);
return value?.ToString() ?? "null";
}
catch
{
value = null;
return "Error";
}
}
}
}
/// <summary>
/// 上次刷新时间
/// </summary>
//private DateTime lastRefreshTime = DateTime.MinValue;
/// <summary>
/// 刷新间隔
/// </summary>
//private readonly TimeSpan refreshInterval = TimeSpan.FromSeconds(0.1);
// 当前时间
//var currentTime = DateTime.Now;
//if (currentTime - lastRefreshTime < refreshInterval)
//{
// return; // 跳过过于频繁的刷新调用
//}
//else
//{
// lastRefreshTime = currentTime;// 记录这次的刷新时间
//}
//
/// <summary>
/// 从当前节点获取至父节点的路径,例如 "node1.node2.node3.node4"
/// </summary>
/// <param name="node">目标节点</param>
/// <returns>节点路径</returns>
//private string GetNodeFullPath(TreeViewItem node)
//{
// if (node == null)
// return string.Empty;
// FlowDataDetails flowDataDetails = (FlowDataDetails)node.Tag;
// var parent = GetParentTreeViewItem(node);
// if (parent != null)
// {
// // 递归获取父节点的路径,并拼接当前节点的 Header
// return $"{GetNodeFullPath(parent)}.{flowDataDetails.Name}";
// }
// else
// {
// // 没有父节点,则说明这是根节点,直接返回 Header
// return "";
// }
//}
/// <summary>
/// 获取指定节点的父级节点
/// </summary>
/// <param name="node">目标节点</param>
/// <returns>父节点</returns>
//private TreeViewItem GetParentTreeViewItem(TreeViewItem node)
//{
// DependencyObject parent = VisualTreeHelper.GetParent(node);
// while (parent != null && !(parent is TreeViewItem))
// {
// parent = VisualTreeHelper.GetParent(parent);
// }
// return parent as TreeViewItem;
//}
/// <summary>
/// 根据成员类别配置右键菜单
/// </summary>
/// <param name="memberNode"></param>
/// <param name="member"></param>
/// <param name="contextMenu"></param>
/// <returns></returns>
//private bool ConfigureTreeItemMenu(TreeViewItem memberNode, MemberInfo member, out ContextMenu? contextMenu)
//{
// if (ConfigureTreeItemMenu(memberNode, member, out ContextMenu? contextMenu))
// {
// memberNode.ContextMenu = contextMenu; // 设置子项节点的事件
// }
// bool isChange = false;
// if (member is PropertyInfo property)
// {
// isChange = true;
// contextMenu = new ContextMenu();
// contextMenu.Items.Add(MainWindow.CreateMenuItem($"表达式", (s, e) =>
// {
// string fullPath = GetNodeFullPath(memberNode);
// string copyValue = /*"@Get " + */fullPath;
// ExpressionTextBox.Text = copyValue;
// // Clipboard.SetDataObject(copyValue);
// }));
// }
// else if (member is MethodInfo method)
// {
// //isChange = true;
// contextMenu = new ContextMenu();
// }
// else if (member is FieldInfo field)
// {
// isChange = true;
// contextMenu = new ContextMenu();
// contextMenu.Items.Add(MainWindow.CreateMenuItem($"表达式", (s, e) =>
// {
// string fullPath = GetNodeFullPath(memberNode);
// string copyValue = /*"@Get " +*/ fullPath;
// ExpressionTextBox.Text = copyValue;
// // Clipboard.SetDataObject(copyValue);
// }));
// }
// else
// {
// contextMenu = new ContextMenu();
// }
// return isChange;
//}
///// <summary>
///// 刷新按钮的点击事件
///// </summary>
//private void RefreshButton_Click(object sender, RoutedEventArgs e)
//{
// RefreshObjectTree();
//}
//private bool IsTimerRefres = false;
//private void TimerRefreshButton_Click(object sender, RoutedEventArgs e)
//{
// if (IsTimerRefres)
// {
// IsTimerRefres = false;
// TimerRefreshButton.Content = "定时刷新";
// }
// else
// {
// IsTimerRefres = true;
// TimerRefreshButton.Content = "取消刷新";
// _ = Task.Run(async () => {
// while (true)
// {
// if (IsTimerRefres)
// {
// Application.Current.Dispatcher.Invoke(() =>
// {
// RefreshObjectTree(); // 刷新UI
// });
// await Task.Delay(100);
// }
// else
// {
// break;
// }
// }
// IsTimerRefres = false;
// });
// }
//}

View File

@@ -1,16 +0,0 @@
<Window x:Class="Serein.Workbench.Themes.TypeViewerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Serein.Workbench.Themes"
mc:Ignorable="d"
Topmost="True"
Title="TypeViewerWindow" Height="300" Width="300">
<Grid>
<Grid>
<TreeView x:Name="TypeTreeView"/>
</Grid>
</Grid>
</Window>

View File

@@ -1,279 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
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.Shapes;
namespace Serein.Workbench.Themes
{
/// <summary>
/// TypeViewerWindow.xaml 的交互逻辑
/// </summary>
public partial class TypeViewerWindow : Window
{
public TypeViewerWindow()
{
InitializeComponent();
}
public Type Type { get; set; }
public void LoadTypeInformation()
{
if (Type == null)
return;
NodeFlowDataObjectDetails typeNodeDetails = new NodeFlowDataObjectDetails
{
Name = Type.Name,
DataType = Type,
};
var rootNode = new TreeViewItem { Header = Type.Name, Tag = typeNodeDetails };
AddPlaceholderNode(rootNode); // 添加占位符节点
TypeTreeView.Items.Clear();
TypeTreeView.Items.Add(rootNode);
rootNode.Expanded += TreeViewItem_Expanded; // 监听节点展开事件
}
/// <summary>
/// 添加占位符节点
/// </summary>
private void AddPlaceholderNode(TreeViewItem node)
{
node.Items.Add(new TreeViewItem { Header = "Loading..." });
}
/// <summary>
/// 节点展开事件,延迟加载子节点
/// </summary>
private void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
{
var item = (TreeViewItem)sender;
// 如果已经加载过子节点,则不再重复加载
if (item.Items.Count == 1 && item.Items[0] is TreeViewItem placeholder && placeholder.Header.ToString() == "Loading...")
{
item.Items.Clear();
if (item.Tag is NodeFlowDataObjectDetails typeNodeDetails)
{
AddMembersToTreeNode(item, typeNodeDetails.DataType);
}
}
}
/// <summary>
/// 添加属性节点
/// </summary>
private void AddMembersToTreeNode(TreeViewItem node, Type type)
{
var members = type.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
foreach (var member in members)
{
TreeViewItem memberNode = ConfigureTreeViewItem(member); // 生成类型节点的子项
if (ConfigureTreeItemMenu(memberNode,member, out ContextMenu? contextMenu))
{
memberNode.ContextMenu = contextMenu; // 设置子项节点的事件
}
node.Items.Add(memberNode); // 添加到父节点中
}
}
/// <summary>
/// 生成类型节点的子项
/// </summary>
/// <param name="member"></param>
/// <returns></returns>
private TreeViewItem ConfigureTreeViewItem(MemberInfo member)
{
TreeViewItem memberNode = new TreeViewItem { Header = member.Name };
if (member is PropertyInfo property)
{
NodeFlowDataObjectDetails typeNodeDetails = new NodeFlowDataObjectDetails
{
ItemType = TreeItemType.Property,
DataType = property.PropertyType,
Name = property.Name,
DataValue = property,
};
memberNode.Tag = typeNodeDetails;
var propertyType = typeNodeDetails.DataType;
memberNode.Header = $"{member.Name} : {propertyType.Name}";
if (!propertyType.IsPrimitive && propertyType != typeof(string))
{
// 延迟加载类型的子属性,添加占位符节点
AddPlaceholderNode(memberNode);
memberNode.Expanded += TreeViewItem_Expanded; // 监听展开事件
}
}
else if (member is MethodInfo method)
{
NodeFlowDataObjectDetails typeNodeDetails = new NodeFlowDataObjectDetails
{
ItemType = TreeItemType.Method,
DataType = typeof(MethodInfo),
Name = method.Name,
DataValue = null,
};
memberNode.Tag = typeNodeDetails;
var parameters = method.GetParameters();
var paramStr = string.Join(", ", parameters.Select(p => $"{p.ParameterType.Name} {p.Name}"));
memberNode.Header = $"{member.Name}({paramStr})";
}
else if (member is FieldInfo field)
{
NodeFlowDataObjectDetails typeNodeDetails = new NodeFlowDataObjectDetails
{
ItemType = TreeItemType.Field,
DataType = field.FieldType,
Name = field.Name,
DataValue = field,
};
memberNode.Tag = typeNodeDetails;
memberNode.Header = $"{member.Name} : {field.FieldType.Name}";
}
return memberNode;
}
/// <summary>
/// 设置子项节点的事件
/// </summary>
/// <param name="member"></param>
/// <returns></returns>
private bool ConfigureTreeItemMenu(TreeViewItem memberNode, MemberInfo member,out ContextMenu? contextMenu)
{
bool isChange = false;
if (member is PropertyInfo property)
{
isChange = true;
contextMenu = new ContextMenu();
contextMenu.Items.Add(MainWindow.CreateMenuItem($"取值表达式", (s, e) =>
{
string fullPath = GetNodeFullPath(memberNode);
string copyValue = "@Get " + fullPath;
Clipboard.SetDataObject(copyValue);
}));
}
else if (member is MethodInfo method)
{
//isChange = true;
contextMenu = new ContextMenu();
}
else if (member is FieldInfo field)
{
isChange = true;
contextMenu = new ContextMenu();
contextMenu.Items.Add(MainWindow.CreateMenuItem($"取值表达式", (s, e) =>
{
string fullPath = GetNodeFullPath(memberNode);
string copyValue = "@Get " + fullPath;
Clipboard.SetDataObject(copyValue);
}));
}
else
{
contextMenu = new ContextMenu();
}
return isChange;
}
/// <summary>
/// 获取当前节点的完整路径,例如 "node1.node2.node3.node4"
/// </summary>
/// <param name="node">目标节点</param>
/// <returns>节点路径</returns>
private string GetNodeFullPath(TreeViewItem node)
{
if (node == null)
return string.Empty;
NodeFlowDataObjectDetails typeNodeDetails = (NodeFlowDataObjectDetails)node.Tag;
var parent = GetParentTreeViewItem(node);
if (parent != null)
{
// 递归获取父节点的路径,并拼接当前节点的 Header
return $"{GetNodeFullPath(parent)}.{typeNodeDetails.Name}";
}
else
{
// 没有父节点,则说明这是根节点,直接返回 Header
return "";
// return typeNodeDetails.Name.ToString();
}
}
/// <summary>
/// 获取指定节点的父级节点
/// </summary>
/// <param name="node">目标节点</param>
/// <returns>父节点</returns>
private TreeViewItem? GetParentTreeViewItem(TreeViewItem node)
{
DependencyObject parent = VisualTreeHelper.GetParent(node);
while (parent != null && parent is not TreeViewItem)
{
parent = VisualTreeHelper.GetParent(parent);
}
return parent as TreeViewItem;
}
public class NodeFlowDataObjectDetails
{
/// <summary>
/// 属性名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 属性类型
/// </summary>
public TreeItemType ItemType { get; set; }
/// <summary>
/// 数据类型
/// </summary>
public Type DataType { get; set; }
/// <summary>
/// 数据(调试用?)
/// </summary>
public object DataValue { get; set; }
/// <summary>
/// 数据路径
/// </summary>
public string DataPath { get; set; }
}
public enum TreeItemType
{
Property,
Method,
Field,
IEnumerable,
Item,
}
}
}

View File

@@ -1,30 +0,0 @@
<Window x:Class="Serein.Workbench.Themes.WindowEnvRemoteLoginView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Serein.Workbench.Themes"
Title="登录远程环境" Height="150" Width="200">
<Grid Margin="0,10,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="地址" HorizontalAlignment="Center"></TextBlock>
<TextBox x:Name="TextBlockAddres" Grid.Row="0" Grid.Column="1" Text="127.0.0.1"></TextBox>
<TextBlock Grid.Row="1" Grid.Column="0" Text="端口" HorizontalAlignment="Center"></TextBlock>
<TextBox x:Name="TextBlockPort" Grid.Row="1" Grid.Column="1" Text="7525"></TextBox>
<TextBlock Grid.Row="2" Grid.Column="0" Text="密码" HorizontalAlignment="Center"></TextBlock>
<TextBox x:Name="TextBlockToken" Grid.Row="2" Grid.Column="1" Text="123456"></TextBox>
<StackPanel Grid.Row="3" Grid.Column="1" HorizontalAlignment="Center" Orientation="Horizontal" Margin="4">
<Button Content="测试连接" Margin="2" Click="ButtonTestConnect_Client"></Button>
<Button Content="登录环境" Margin="2" Click="ButtonTestLoginEnv_Client"></Button>
</StackPanel>
</Grid>
</Window>

View File

@@ -1,70 +0,0 @@
using Serein.Library;
using Serein.Library.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
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.Shapes;
namespace Serein.Workbench.Themes
{
/// <summary>
/// WindowDialogInput.xaml 的交互逻辑
/// </summary>
public partial class WindowEnvRemoteLoginView : Window
{
private Action<string, int, string> ConnectRemoteFlowEnv;
/// <summary>
/// 弹窗输入
/// </summary>
/// <param name="connectRemoteFlowEnv"></param>
public WindowEnvRemoteLoginView(Action<string, int, string> connectRemoteFlowEnv)
{
WindowStartupLocation = WindowStartupLocation.CenterScreen;
InitializeComponent();
ConnectRemoteFlowEnv = connectRemoteFlowEnv;
}
private void ButtonTestConnect_Client(object sender, RoutedEventArgs e)
{
var addres = this.TextBlockAddres.Text;
_ = int.TryParse(this.TextBlockPort.Text, out var port);
_ = Task.Run(() => {
bool success = false;
try
{
TcpClient tcpClient = new TcpClient();
var result = tcpClient.BeginConnect(addres, port, null, null);
success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(3));
}
catch
{
success = false;
}
if (!success)
{
SereinEnv.WriteLine(InfoType.ERROR, $"无法连接远程:{addres}:{port}");
}
});
}
private void ButtonTestLoginEnv_Client(object sender, RoutedEventArgs e)
{
var addres = this.TextBlockAddres.Text;
_ = int.TryParse(this.TextBlockPort.Text, out var port);
var token = this.TextBlockToken.Text;
ConnectRemoteFlowEnv?.Invoke(addres, port, token);
}
}
}

View File

@@ -1,41 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows;
namespace Serein.Workbench.Tool.Converters
{
/// <summary>
/// 根据bool类型控制可见性
/// </summary>
[ValueConversion(typeof(bool), typeof(Visibility))]
public class InvertableBooleanToVisibilityConverter : IValueConverter
{
enum Parameters
{
Normal, Inverted
}
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
var boolValue = (bool)value;
var direction = (Parameters)Enum.Parse(typeof(Parameters), (string)parameter);
if (direction == Parameters.Inverted)
return !boolValue ? Visibility.Visible : Visibility.Collapsed;
return boolValue ? Visibility.Visible : Visibility.Collapsed;
}
public object? ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return null;
}
}
}

View File

@@ -1,79 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace Serein.Workbench.Tool.Converters
{
/// <summary>
/// 画布拉动范围距离计算器
/// </summary>
public class RightThumbPositionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is double width)
return width - 10; // Adjust for Thumb width
return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 画布拉动范围距离计算器
/// </summary>
public class BottomThumbPositionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is double height)
return height - 10; // Adjust for Thumb height
return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 画布拉动范围距离计算器
/// </summary>
public class VerticalCenterThumbPositionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is double height)
return height / 2 - 5; // Centering Thumb vertically
return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 画布拉动范围距离计算器
/// </summary>
public class HorizontalCenterThumbPositionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is double width)
return width / 2 - 5; // Centering Thumb horizontally
return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,26 +0,0 @@
using Serein.Library;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
namespace Serein.Workbench.Tool.Converters
{
/// <summary>
/// 根据控件类型切换颜色
/// </summary>
public class TypeToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// 根据 ControlType 返回颜色
return value switch
{
NodeControlType.Action => Brushes.Blue,
NodeControlType.Flipflop => Brushes.Green,
_ => Brushes.Black,
};
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
}
}

View File

@@ -1,53 +0,0 @@
using Serein.Library;
using Serein.Workbench.Node.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
namespace Serein.Workbench.Extension
{
/// <summary>
/// 线条颜色
/// </summary>
public static class LineExtension
{
/// <summary>
/// 根据连接类型指定颜色
/// </summary>
/// <param name="currentConnectionType"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static SolidColorBrush ToLineColor(this ConnectionInvokeType currentConnectionType)
{
return currentConnectionType switch
{
ConnectionInvokeType.IsSucceed => new SolidColorBrush((Color)ColorConverter.ConvertFromString("#04FC10")), // 04FC10 & 027E08
ConnectionInvokeType.IsFail => new SolidColorBrush((Color)ColorConverter.ConvertFromString("#F18905")),
ConnectionInvokeType.IsError => new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FE1343")),
ConnectionInvokeType.Upstream => new SolidColorBrush((Color)ColorConverter.ConvertFromString("#4A82E4")),
ConnectionInvokeType.None => new SolidColorBrush((Color)ColorConverter.ConvertFromString("#56CEF6")),
_ => throw new Exception(),
};
}
/// <summary>
/// 根据连接类型指定颜色
/// </summary>
/// <param name="connection"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static SolidColorBrush ToLineColor(this ConnectionArgSourceType connection)
{
return connection switch
{
ConnectionArgSourceType.GetPreviousNodeData => new SolidColorBrush((Color)ColorConverter.ConvertFromString("#56CEF6")), // 04FC10 & 027E08
ConnectionArgSourceType.GetOtherNodeData => new SolidColorBrush((Color)ColorConverter.ConvertFromString("#56CEF6")),
ConnectionArgSourceType.GetOtherNodeDataOfInvoke => new SolidColorBrush((Color)ColorConverter.ConvertFromString("#B06BBB")),
_ => throw new Exception(),
};
}
}
}

View File

@@ -1,42 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace Serein.Workbench.Extension
{
public static class PointExtension
{
public static Point Add(this Point a, Point b)
{
return new Point(a.X + b.X, a.Y + b.Y);
}
public static Point Sub(this Point a, Point b)
{
return new Point(a.X - b.X, a.Y - b.Y);
}
public static Vector ToVector(this Point me)
{
return new Vector(me.X, me.Y);
}
}
public static class VectorExtension
{
public static double DotProduct(this Vector a, Vector b)
{
return a.X * b.X + a.Y * b.Y;
}
public static Vector NormalizeTo(this Vector v)
{
var temp = v;
temp.Normalize();
return temp;
}
}
}

View File

@@ -1,33 +0,0 @@
using Serein.Workbench.Node.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serein.Workbench.Node
{
/// <summary>
/// 约束具有容器功能的节点控件应该有什么方法
/// </summary>
public interface INodeContainerControl
{
/// <summary>
/// 放置一个节点
/// </summary>
/// <param name="nodeControl"></param>
bool PlaceNode(NodeControlBase nodeControl);
/// <summary>
/// 取出一个节点
/// </summary>
/// <param name="nodeControl"></param>
bool TakeOutNode(NodeControlBase nodeControl);
/// <summary>
/// 取出所有节点(用于删除容器)
/// </summary>
void TakeOutAll();
}
}

View File

@@ -1,52 +0,0 @@
using Serein.Workbench.Node.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace Serein.Workbench.Node
{
/// <summary>
/// 约束一个节点应该有哪些控制点
/// </summary>
public interface INodeJunction
{
/// <summary>
/// 方法执行入口控制点
/// </summary>
JunctionControlBase ExecuteJunction { get; }
/// <summary>
/// 执行完成后下一个要执行的方法控制点
/// </summary>
JunctionControlBase NextStepJunction { get; }
/// <summary>
/// 参数节点控制点
/// </summary>
JunctionControlBase[] ArgDataJunction { get; }
/// <summary>
/// 返回值控制点
/// </summary>
JunctionControlBase ReturnDataJunction { get; }
/// <summary>
/// 获取目标参数控制点用于防止wpf释放资源导致找不到目标节点返回-1,-1的坐标
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
JunctionControlBase GetJunctionOfArgData(int index)
{
var arr = ArgDataJunction;
if (index >= arr.Length)
{
return null;
}
return arr[index];
}
}
}

View File

@@ -1,234 +0,0 @@
using Serein.Library;
using Serein.Workbench.Extension;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace Serein.Workbench.Node.View
{
/// <summary>
/// 连接线的类型
/// </summary>
public enum LineType
{
/// <summary>
/// 贝塞尔曲线
/// </summary>
Bezier,
/// <summary>
/// 半圆线
/// </summary>
Semicircle,
}
/// <summary>
/// 贝塞尔曲线
/// </summary>
public class ConnectionLineShape : Shape
{
private readonly double strokeThickness;
private readonly LineType lineType;
/// <summary>
/// 确定起始坐标和目标坐标、外光样式的曲线
/// </summary>
/// <param name="lineType">线条类型</param>
/// <param name="start">起始坐标</param>
/// <param name="end">结束坐标</param>
/// <param name="brush">颜色</param>
/// <param name="isDotted">是否为虚线</param>
public ConnectionLineShape(LineType lineType,
Point start,
Point end,
Brush brush,
bool isDotted = false,
bool isTop = false)
{
this.lineType = lineType;
this.brush = brush;
startPoint = start;
endPoint = end;
this.strokeThickness = 4;
InitElementPoint(isDotted, isTop);
InvalidateVisual(); // 触发重绘
}
public void InitElementPoint(bool isDotted , bool isTop = false)
{
hitVisiblePen = new Pen(Brushes.Transparent, 1.0); // 初始化碰撞检测线
hitVisiblePen.Freeze(); // Freeze以提高性能
visualPen = new Pen(brush, 3.0); // 默认可视化Pen
opacity = 1.0d;
if (isDotted)
{
opacity = 0.42d;
visualPen.DashStyle = DashStyles.Dash; // 选择虚线样式
}
visualPen.Freeze(); // Freeze以提高性能
linkSize = 4; // 整线条粗细
int zIndex = -999999;
if (isTop)
{
zIndex *= -1;
}
Panel.SetZIndex(this, zIndex); // 置底
}
/// <summary>
/// 更新线条落点位置
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
public void UpdatePoints(Point start, Point end)
{
startPoint = start;
endPoint = end;
InvalidateVisual(); // 触发重绘
}
/// <summary>
/// 更新线条落点位置
/// </summary>
/// <param name="point"></param>
public void UpdateEndPoints(Point point)
{
endPoint = point;
InvalidateVisual(); // 触发重绘
}
/// <summary>
/// 更新线条落点位置
/// </summary>
/// <param name="point"></param>
public void UpdateStartPoints(Point point)
{
startPoint = point;
InvalidateVisual(); // 触发重绘
}
/// <summary>
/// 控件重绘事件
/// </summary>
/// <param name="drawingContext"></param>
protected override void OnRender(DrawingContext drawingContext)
{
// 刷新线条显示位置
switch (this.lineType)
{
case LineType.Bezier:
DrawBezierCurve(drawingContext, startPoint, endPoint);
break;
case LineType.Semicircle:
DrawSemicircleCurve(drawingContext, startPoint, endPoint);
break;
default:
break;
}
}
#region
private readonly StreamGeometry streamGeometry = new StreamGeometry();
private Point rightCenterOfStartLocation; // 目标节点选择左侧边缘中心
private Point leftCenterOfEndLocation; // 起始节点选择右侧边缘中心
private Pen hitVisiblePen; // 初始化碰撞检测线
private Pen visualPen; // 默认可视化Pen
private Point startPoint; // 连接线的起始节点
private Point endPoint; // 连接线的终点
private Brush brush; // 线条颜色
private double opacity; // 透明度
double linkSize; // 根据缩放比例调整线条粗细
protected override Geometry DefiningGeometry => streamGeometry;
public void UpdateLineColor(Brush brush)
{
visualPen = new Pen(brush, 3.0); // 默认可视化Pen
InvalidateVisual(); // 触发重绘
}
private Point c0, c1; // 用于计算贝塞尔曲线控制点逻辑
private Vector axis = new Vector(1, 0);
private Vector startToEnd;
private void DrawBezierCurve(DrawingContext drawingContext,
Point start,
Point end)
{
// 控制点的计算逻辑
double power = 140; // 控制贝塞尔曲线的“拉伸”强度
drawingContext.PushOpacity(opacity);
// 计算轴向向量与起点到终点的向量
//var axis = new Vector(1, 0);
startToEnd = (end.ToVector() - start.ToVector()).NormalizeTo();
// 计算拉伸程度k拉伸与水平夹角正相关
var k = 1 - Math.Pow(Math.Max(0, axis.DotProduct(startToEnd)), 10.0);
// 如果起点x大于终点x增加额外的偏移量避免重叠
var bias = start.X > end.X ? Math.Abs(start.X - end.X) * 0.25 : 0;
// 控制点的实际计算
c0 = new Point(+(power + bias) * k + start.X, start.Y);
c1 = new Point(-(power + bias) * k + end.X, end.Y);
// 准备StreamGeometry以用于绘制曲线
streamGeometry.Clear();
using (var context = streamGeometry.Open())
{
context.BeginFigure(start, true, false); // 曲线起点
context.BezierTo(c0, c1, end, true, false); // 画贝塞尔曲线
}
drawingContext.DrawGeometry(null, visualPen, streamGeometry);
}
private void DrawSemicircleCurve(DrawingContext drawingContext, Point start, Point end)
{
// 计算中心点和半径
// 计算圆心和半径
double x = 35;
// 创建一个弧线路径
streamGeometry.Clear();
using (var context = streamGeometry.Open())
{
// 开始绘制
context.BeginFigure(start, false, false);
// 生成弧线
context.ArcTo(
end, // 结束点
new Size(x, x), // 椭圆的半径
0, // 椭圆的旋转角度
false, // 是否大弧
SweepDirection.Counterclockwise, // 方向
true, // 是否连接到起始点
true // 是否使用高质量渲染
);
// 结束绘制
context.LineTo(start, false, false); // 连接到起始点(可选)
}
// 绘制弧线
drawingContext.DrawGeometry(null, visualPen, streamGeometry);
}
#endregion
}
}

View File

@@ -1,378 +0,0 @@
using Serein.Library;
using Serein.Library.Utils;
using System;
using System.Net;
using System.Reflection;
using System.Windows;
using Serein.Workbench.Extension;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
using System.Windows.Documents;
using System.Threading;
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 ParamsArgControl()
{
this.MouseDown += ParamsArg_OnMouseDown; // 增加或删除
this.MouseMove += ParamsArgControl_MouseMove;
this.MouseLeave += ParamsArgControl_MouseLeave;
AddOrRemoveParamsTask = AddAsync;
}
protected readonly StreamGeometry StreamGeometry = new StreamGeometry();
protected override Geometry DefiningGeometry => StreamGeometry;
#region
public static readonly DependencyProperty NodeProperty =
DependencyProperty.Register(nameof(MyNode), typeof(NodeModelBase), typeof(ParamsArgControl), new PropertyMetadata(default(NodeModelBase)));
//public NodeModelBase NodeModel;
/// <summary>
/// 所在的节点
/// </summary>
public NodeModelBase MyNode
{
get { return (NodeModelBase)GetValue(NodeProperty); }
set { SetValue(NodeProperty, value); }
}
#endregion
#region
public static readonly DependencyProperty ArgIndexProperty =
DependencyProperty.Register(nameof(ArgIndex), typeof(int), typeof(ParamsArgControl), new PropertyMetadata(default(int)));
/// <summary>
/// 参数的索引
/// </summary>
public int ArgIndex
{
get { return (int)GetValue(ArgIndexProperty); }
set { SetValue(ArgIndexProperty, value.ToString()); }
}
#endregion
/// <summary>
/// 控件重绘事件
/// </summary>
/// <param name="drawingContext"></param>
protected override void OnRender(DrawingContext drawingContext)
{
Brush brush = isMouseOver ? Brushes.Red : Brushes.Green;
double height = ActualHeight;
// 定义圆形的大小和位置
double connectorSize = 10; // 连接器的大小
double circleCenterX = 8; // 圆心 X 坐标
double circleCenterY = height / 2; // 圆心 Y 坐标
var circlePoint = new Point(circleCenterX, circleCenterY);
// 圆形部分
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
drawingContext.DrawGeometry(brush, MyUIFunc.CreateAndFreezePen(), ellipse);
}
private bool isMouseOver; // 鼠标悬停状态
private Func<Task> AddOrRemoveParamsTask; // 增加或删除参数
public async void ParamsArg_OnMouseDown(object sender, MouseButtonEventArgs e)
{
await AddOrRemoveParamsTask.Invoke();
}
private void ParamsArgControl_MouseMove(object sender, MouseEventArgs e)
{
isMouseOver = true;
if (cancellationTokenSource.IsCancellationRequested) {
cancellationTokenSource = new CancellationTokenSource();
Task.Run(async () =>
{
await Task.Delay(380);
}, cancellationTokenSource.Token).ContinueWith((t) =>
{
// 如果焦点仍在控件上时,则改变点击事件
if (isMouseOver)
{
AddOrRemoveParamsTask = RemoveAsync;
this.Dispatcher.Invoke(InvalidateVisual);// 触发一次重绘
}
});
}
}
private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
private void ParamsArgControl_MouseLeave(object sender, MouseEventArgs e)
{
isMouseOver = false;
AddOrRemoveParamsTask = AddAsync; // 鼠标焦点离开时恢复点击事件
cancellationTokenSource?.Cancel();
this.Dispatcher.Invoke(InvalidateVisual);// 触发一次重绘
}
private async Task AddAsync()
{
await this.MyNode.Env.ChangeParameter(MyNode.Guid, true, ArgIndex);
}
private async Task RemoveAsync()
{
await this.MyNode.Env.ChangeParameter(MyNode.Guid, false, ArgIndex);
}
}
public abstract class JunctionControlBase : Shape
{
protected JunctionControlBase()
{
this.Width = 25;
this.Height = 20;
this.MouseDown += JunctionControlBase_MouseDown;
this.MouseMove += JunctionControlBase_MouseMove;
this.MouseLeave += JunctionControlBase_MouseLeave; ;
}
#region
public static readonly DependencyProperty NodeProperty =
DependencyProperty.Register(nameof(MyNode), typeof(NodeModelBase), typeof(JunctionControlBase), new PropertyMetadata(default(NodeModelBase)));
//public NodeModelBase NodeModel;
/// <summary>
/// 所在的节点
/// </summary>
public NodeModelBase MyNode
{
get { return (NodeModelBase)GetValue(NodeProperty); }
set { SetValue(NodeProperty, value); }
}
#endregion
#region
public static readonly DependencyProperty JunctionTypeProperty =
DependencyProperty.Register(nameof(JunctionType), typeof(string), typeof(JunctionControlBase), new PropertyMetadata(default(string)));
/// <summary>
/// 控制点类型
/// </summary>
public JunctionType JunctionType
{
get { return EnumHelper.ConvertEnum<JunctionType>(GetValue(JunctionTypeProperty).ToString()); }
set { SetValue(JunctionTypeProperty, value.ToString()); }
}
#endregion
protected readonly StreamGeometry StreamGeometry = new StreamGeometry();
protected override Geometry DefiningGeometry => StreamGeometry;
/// <summary>
/// 重绘方法
/// </summary>
/// <param name="drawingContext"></param>
public abstract void Render(DrawingContext drawingContext);
/// <summary>
/// 中心点
/// </summary>
public abstract Point MyCenterPoint { get; }
/// <summary>
/// 禁止连接
/// </summary>
private bool IsConnectionDisable;
/// <summary>
/// 处理鼠标悬停状态
/// </summary>
private bool _isMouseOver;
public bool IsMouseOver
{
get => _isMouseOver;
set
{
if(_isMouseOver != value)
{
GlobalJunctionData.MyGlobalConnectingData.CurrentJunction = this;
_isMouseOver = value;
InvalidateVisual();
}
}
}
/// <summary>
/// 控件重绘事件
/// </summary>
/// <param name="drawingContext"></param>
protected override void OnRender(DrawingContext drawingContext)
{
Render(drawingContext);
}
/// <summary>
/// 获取背景颜色
/// </summary>
/// <returns></returns>
protected Brush GetBackgrounp()
{
var myData = GlobalJunctionData.MyGlobalConnectingData;
if(!myData.IsCreateing)
{
return Brushes.Transparent;
}
if (IsMouseOver)
{
if (myData.IsCanConnected)
{
if (myData.Type == JunctionOfConnectionType.Invoke)
{
return myData.ConnectionInvokeType.ToLineColor();
}
else
{
return myData.ConnectionArgSourceType.ToLineColor();
}
}
else
{
return Brushes.Red;
}
}
else
{
return Brushes.Transparent;
}
}
private object lockObj = new object();
/// <summary>
/// 控件获得鼠标焦点事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void JunctionControlBase_MouseMove(object sender, MouseEventArgs e)
{
//if (!GlobalJunctionData.MyGlobalConnectingData.IsCreateing) return;
//if (IsMouseOver) return;
IsMouseOver = true;
//this.InvalidateVisual();
}
/// <summary>
/// 控件失去鼠标焦点事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void JunctionControlBase_MouseLeave(object sender, MouseEventArgs e)
{
IsMouseOver = false;
e.Handled = true;
}
/// <summary>
/// 在碰撞点上按下鼠标控件开始进行移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void JunctionControlBase_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
var canvas = MainWindow.GetParentOfType<Canvas>(this);
if (canvas != null)
{
var myData = GlobalJunctionData.MyGlobalConnectingData;
myData.Reset();
myData.IsCreateing = true; // 表示开始连接
myData.StartJunction = this;
myData.CurrentJunction = this;
myData.StartPoint = this.TranslatePoint(new Point(this.Width / 2, this.Height / 2), canvas);
var junctionOfConnectionType = this.JunctionType.ToConnectyionType();
ConnectionLineShape bezierLine; // 类别
Brush brushColor; // 临时线的颜色
if (junctionOfConnectionType == JunctionOfConnectionType.Invoke)
{
brushColor = ConnectionInvokeType.IsSucceed.ToLineColor();
}
else if(junctionOfConnectionType == JunctionOfConnectionType.Arg)
{
brushColor = ConnectionArgSourceType.GetOtherNodeData.ToLineColor();
}
else
{
return;
}
bezierLine = new ConnectionLineShape(LineType.Bezier,
myData.StartPoint,
myData.StartPoint,
brushColor,
isTop: true); // 绘制临时的线
Mouse.OverrideCursor = Cursors.Cross; // 设置鼠标为正在创建连线
myData.MyLine = new MyLine(canvas, bezierLine);
}
}
e.Handled = true;
}
private Point GetStartPoint()
{
return new Point(this.ActualWidth / 2, this.ActualHeight / 2); // 起始节点选择右侧边缘中心
}
}
}

View File

@@ -1,161 +0,0 @@
using Serein.Library;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
namespace Serein.Workbench.Node.View
{
#region Model
public class MyLine
{
public MyLine(Canvas canvas, ConnectionLineShape line)
{
Canvas = canvas;
Line = line;
canvas?.Children.Add(line);
}
public Canvas Canvas { get; set; }
public ConnectionLineShape Line { get; set; }
public void Remove()
{
Canvas?.Children.Remove(Line);
}
}
public class ConnectingData
{
/// <summary>
/// 是否正在创建连线
/// </summary>
public bool IsCreateing { get; set; }
/// <summary>
/// 起始控制点
/// </summary>
public JunctionControlBase StartJunction { get; set; }
/// <summary>
/// 当前的控制点
/// </summary>
public JunctionControlBase CurrentJunction { get; set; }
/// <summary>
/// 开始坐标
/// </summary>
public Point StartPoint { get; set; }
/// <summary>
/// 线条样式
/// </summary>
public MyLine MyLine { get; set; }
/// <summary>
/// 线条类别(方法调用)
/// </summary>
public ConnectionInvokeType ConnectionInvokeType { get; set; } = ConnectionInvokeType.IsSucceed;
/// <summary>
/// 线条类别(参数传递)
/// </summary>
public ConnectionArgSourceType ConnectionArgSourceType { get; set; } = ConnectionArgSourceType.GetOtherNodeData;
/// <summary>
/// 判断当前连接类型
/// </summary>
public JunctionOfConnectionType Type => StartJunction.JunctionType.ToConnectyionType();
/// <summary>
/// 是否允许连接
/// </summary>
public bool IsCanConnected { get
{
if(StartJunction is null
|| CurrentJunction is null
)
{
return false;
}
if (!StartJunction.MyNode.Equals(CurrentJunction.MyNode)
&& StartJunction.JunctionType.IsCanConnection(CurrentJunction.JunctionType))
{
return true;
}
else
{
return false;
}
}
}
/// <summary>
/// 更新临时的连接线
/// </summary>
/// <param name="point"></param>
public void UpdatePoint(Point point)
{
if (StartJunction is null
|| CurrentJunction is null
)
{
return;
}
if (StartJunction.JunctionType == Library.JunctionType.Execute
|| StartJunction.JunctionType == Library.JunctionType.ArgData)
{
MyLine.Line.UpdateStartPoints(point);
}
else
{
MyLine.Line.UpdateEndPoints(point);
}
}
/// <summary>
/// 重置
/// </summary>
public void Reset()
{
IsCreateing = false;
StartJunction = null;
CurrentJunction = null;
MyLine?.Remove();
ConnectionInvokeType = ConnectionInvokeType.IsSucceed;
ConnectionArgSourceType = ConnectionArgSourceType.GetOtherNodeData;
}
}
public static class GlobalJunctionData
{
//private static ConnectingData? myGlobalData;
//private static object _lockObj = new object();
/// <summary>
/// 创建节点之间控制点的连接行为
/// </summary>
public static ConnectingData MyGlobalConnectingData { get; } = new ConnectingData();
/// <summary>
/// 删除连接视觉效果
/// </summary>
public static void OK()
{
MyGlobalConnectingData.Reset();
}
}
#endregion
}

View File

@@ -1,237 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows;
using Serein.Workbench.Node.View;
using System.Windows.Controls;
using Serein.Library;
using System.Windows.Data;
namespace Serein.Workbench.Node.View
{
public abstract class NodeJunctionViewBase : ContentControl, IDisposable
{
public NodeJunctionViewBase()
{
var transfromGroup = new TransformGroup();
transfromGroup.Children.Add(_Translate);
RenderTransform = transfromGroup;
}
/// <summary>
/// 每个连接器都有一个唯一标识符Guid用于标识连接器。
/// </summary>
public Guid Guid
{
get => (Guid)GetValue(GuidProperty);
set => SetValue(GuidProperty, value);
}
public static readonly DependencyProperty GuidProperty = DependencyProperty.Register(
nameof(Guid),
typeof(Guid),
typeof(NodeJunctionViewBase), // NodeConnectorContent
new PropertyMetadata(Guid.Empty));
/// <summary>
/// 连接器当前的连接数,表示有多少条 NodeLink 连接到此连接器。该属性为只读。
/// </summary>
public int ConnectedCount
{
get => (int)GetValue(ConnectedCountProperty);
private set => SetValue(ConnectedCountPropertyKey, value);
}
public static readonly DependencyPropertyKey ConnectedCountPropertyKey = DependencyProperty.RegisterReadOnly(
nameof(ConnectedCount),
typeof(int),
typeof(NodeJunctionViewBase), // NodeConnectorContent
new PropertyMetadata(0));
public static readonly DependencyProperty ConnectedCountProperty = ConnectedCountPropertyKey.DependencyProperty;
/// <summary>
/// 布尔值,指示此连接器是否有任何连接。
/// </summary>
public bool IsConnected
{
get => (bool)GetValue(IsConnectedProperty);
private set => SetValue(IsConnectedPropertyKey, value);
}
public static readonly DependencyPropertyKey IsConnectedPropertyKey = DependencyProperty.RegisterReadOnly(
nameof(IsConnected),
typeof(bool),
typeof(NodeJunctionViewBase), // NodeConnectorContent
new PropertyMetadata(false));
public static readonly DependencyProperty IsConnectedProperty = IsConnectedPropertyKey.DependencyProperty;
/// <summary>
/// 这些属性控制连接器的外观(颜色、边框厚度、填充颜色)。
/// </summary>
public Brush Stroke
{
get => (Brush)GetValue(StrokeProperty);
set => SetValue(StrokeProperty, value);
}
public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register(
nameof(Stroke),
typeof(Brush),
typeof(NodeJunctionViewBase), // NodeConnectorContent
new FrameworkPropertyMetadata(Brushes.Blue));
/// <summary>
/// 这些属性控制连接器的外观(颜色、边框厚度、填充颜色)。
/// </summary>
public double StrokeThickness
{
get => (double)GetValue(StrokeThicknessProperty);
set => SetValue(StrokeThicknessProperty, value);
}
public static readonly DependencyProperty StrokeThicknessProperty = DependencyProperty.Register(
nameof(StrokeThickness),
typeof(double),
typeof(NodeJunctionViewBase), // NodeConnectorContent
new FrameworkPropertyMetadata(1.0));
/// <summary>
/// 这些属性控制连接器的外观(颜色、边框厚度、填充颜色)。
/// </summary>
public Brush Fill
{
get => (Brush)GetValue(FillProperty);
set => SetValue(FillProperty, value);
}
public static readonly DependencyProperty FillProperty = DependencyProperty.Register(
nameof(Fill),
typeof(Brush),
typeof(NodeJunctionViewBase),// NodeConnectorContent
new FrameworkPropertyMetadata(Brushes.Gray));
/// <summary>
/// 指示该连接器是否可以与其他连接器进行连接。
/// </summary>
public bool CanConnect
{
get => (bool)GetValue(CanConnectProperty);
set => SetValue(CanConnectProperty, value);
}
public static readonly DependencyProperty CanConnectProperty = DependencyProperty.Register(
nameof(CanConnect),
typeof(bool),
typeof(NodeJunctionViewBase),// NodeConnectorContent
new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender));
private Point _Position = new Point();
/// <summary>
/// 该连接器的当前坐标(位置)。
/// </summary>
public Point Position
{
get => _Position;
set => UpdatePosition(value);
}
/// <summary>
/// (重要数据)表示连接器所属的节点。
/// </summary>
public NodeModelBase NodeModel { get; private set; } = null;
/// <summary>
/// 该连接器所连接的所有 NodeLink 的集合。
/// </summary>
public IEnumerable<ConnectionControl> NodeLinks => _NodeLinks;
List<ConnectionControl> _NodeLinks = new List<ConnectionControl>();
protected abstract FrameworkElement ConnectorControl { get; }
TranslateTransform _Translate = new TranslateTransform();
void UpdatePosition(Point pos)
{
_Position = pos;
_Translate.X = _Position.X;
_Translate.Y = _Position.Y;
InvalidateVisual();
}
/// <summary>
/// 将 NodeLink 添加到连接器,并更新 ConnectedCount 和 IsConnected。
/// </summary>
/// <param name="nodeLink"></param>
public void Connect(ConnectionControl nodeLink)
{
_NodeLinks.Add(nodeLink);
ConnectedCount = _NodeLinks.Count;
IsConnected = ConnectedCount > 0;
}
/// <summary>
/// 断开与某个 NodeLink 的连接,更新连接状态。
/// </summary>
/// <param name="nodeLink"></param>
public void Disconnect(ConnectionControl nodeLink)
{
_NodeLinks.Remove(nodeLink);
ConnectedCount = _NodeLinks.Count;
IsConnected = ConnectedCount > 0;
}
/// <summary>
/// 获取连接器相对于指定 Canvas 的位置。
/// </summary>
/// <param name="canvas"></param>
/// <param name="xScaleOffset"></param>
/// <param name="yScaleOffset"></param>
/// <returns></returns>
public Point GetContentPosition(Canvas canvas, double xScaleOffset = 0.5, double yScaleOffset = 0.5)
{
// it will be shifted Control position if not called UpdateLayout().
ConnectorControl.UpdateLayout();
var transformer = ConnectorControl.TransformToVisual(canvas);
var x = ConnectorControl.ActualWidth * xScaleOffset;
var y = ConnectorControl.ActualHeight * yScaleOffset;
return transformer.Transform(new Point(x, y));
}
/// <summary>
/// 更新与此连接器相连的所有 NodeLink 的位置。这个方法是抽象的,要求子类实现。
/// </summary>
/// <param name="canvas"></param>
public abstract void UpdateLinkPosition(Canvas canvas);
/// <summary>
/// 用于检查此连接器是否可以与另一个连接器相连接,要求子类实现。
/// </summary>
/// <param name="connector"></param>
/// <returns></returns>
public abstract bool CanConnectTo(NodeJunctionViewBase connector);
/// <summary>
/// 释放连接器相关的资源,包括样式、绑定和已连接的 NodeLink
/// </summary>
public void Dispose()
{
// You need to clear Style.
// Because implemented on style for binding.
Style = null;
// Clear binding for subscribing source changed event from old control.
// throw exception about visual tree ancestor different if you not clear binding.
BindingOperations.ClearAllBindings(this);
var nodeLinks = _NodeLinks.ToArray();
// it must instance to nodeLinks because change node link collection in NodeLink Dispose.
foreach (var nodeLink in nodeLinks)
{
// nodeLink.Dispose();
}
}
}
}

View File

@@ -1,74 +0,0 @@
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using Serein.Library;
namespace Serein.Workbench.Node.View
{
public class ArgJunctionControl : JunctionControlBase
{
public ArgJunctionControl()
{
base.JunctionType = JunctionType.ArgData;
this.InvalidateVisual();
}
#region
public static readonly DependencyProperty ArgIndexProperty =
DependencyProperty.Register("ArgIndex", typeof(int), typeof(ArgJunctionControl), new PropertyMetadata(default(int)));
/// <summary>
/// 所在的节点
/// </summary>
public int ArgIndex
{
get { return (int)GetValue(ArgIndexProperty); }
set { SetValue(ArgIndexProperty, value); }
}
#endregion
private Point _myCenterPoint;
public override Point MyCenterPoint { get => _myCenterPoint; }
public override void Render(DrawingContext drawingContext)
{
double width = ActualWidth;
double height = ActualHeight;
var background = GetBackgrounp();
// 输入连接器的背景
var connectorRect = new Rect(0, 0, width, height);
drawingContext.DrawRectangle(Brushes.Transparent, null, connectorRect);
// 定义圆形的大小和位置
double connectorSize = 10; // 连接器的大小
double circleCenterX = 8; // 圆心 X 坐标
double circleCenterY = height / 2; // 圆心 Y 坐标
var circlePoint = new Point(circleCenterX, circleCenterY);
_myCenterPoint = new Point(circleCenterX - connectorSize / 2, circleCenterY); // 中心坐标
// 绘制连接器的圆形部分
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse);
// 定义三角形的间距
double triangleOffsetX = 4; // 三角形与圆形的间距
double triangleCenterX = circleCenterX + connectorSize / 2 + triangleOffsetX; // 三角形中心 X 坐标
double triangleCenterY = circleCenterY; // 三角形中心 Y 坐标
// 绘制三角形
var pathGeometry = new StreamGeometry();
using (var context = pathGeometry.Open())
{
context.BeginFigure(new Point(triangleCenterX, triangleCenterY - 4.5), true, true);
context.LineTo(new Point(triangleCenterX + 5, triangleCenterY), 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, MyUIFunc.CreateAndFreezePen(), pathGeometry);
}
}
}

View File

@@ -1,84 +0,0 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using Serein.Library;
namespace Serein.Workbench.Node.View
{
public class ExecuteJunctionControl : JunctionControlBase
{
public ExecuteJunctionControl()
{
base.JunctionType = JunctionType.Execute;
this.InvalidateVisual();
}
private Point _myCenterPoint;
public override Point MyCenterPoint { get => _myCenterPoint; }
public override void Render(DrawingContext drawingContext)
{
double width = ActualWidth;
double height = ActualHeight;
var background = GetBackgrounp();
// 绘制边框
//var borderBrush = new SolidColorBrush(Colors.Black);
//var borderThickness = 1.0;
//var borderRect = new Rect(0, 0, width, height);
//drawingContext.DrawRectangle(null, new Pen(borderBrush, borderThickness), borderRect);
// 输入连接器的背景
var connectorRect = new Rect(0, 0, width, height);
drawingContext.DrawRectangle(Brushes.Transparent,null, connectorRect);
//drawingContext.DrawRectangle(Brushes.Transparent, new Pen(background,2), connectorRect);
// 定义圆形的大小和位置
double connectorSize = 10; // 连接器的大小
double circleCenterX = 8; // 圆心 X 坐标
double circleCenterY = height / 2; // 圆心 Y 坐标
_myCenterPoint = new Point(circleCenterX - connectorSize / 2, circleCenterY); // 中心坐标
var circlePoint = new Point(circleCenterX, circleCenterY);
// 绘制连接器的圆形部分
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse);
// 定义三角形的间距
double triangleOffsetX = 4; // 三角形与圆形的间距
double triangleCenterX = circleCenterX + connectorSize / 2 + triangleOffsetX; // 三角形中心 X 坐标
double triangleCenterY = circleCenterY; // 三角形中心 Y 坐标
// 绘制三角形
var pathGeometry = new StreamGeometry();
using (var context = pathGeometry.Open())
{
context.BeginFigure(new Point(triangleCenterX, triangleCenterY - 4.5), true, true);
context.LineTo(new Point(triangleCenterX + 5, triangleCenterY), 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, MyUIFunc.CreateAndFreezePen(), pathGeometry);
// 绘制标签
//var formattedText = new FormattedText(
// "执行",
// System.Globalization.CultureInfo.CurrentCulture,
// FlowDirection.LeftToRight,
// new Typeface("Segoe UI"),
// 12,
// Brushes.Black,
// VisualTreeHelper.GetDpi(this).PixelsPerDip);
//drawingContext.DrawText(formattedText, new Point(18,1));
}
}
}

View File

@@ -1,60 +0,0 @@
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using Serein.Library;
namespace Serein.Workbench.Node.View
{
public class NextStepJunctionControl : JunctionControlBase
{
//public override JunctionType JunctionType { get; } = JunctionType.NextStep;
public NextStepJunctionControl()
{
base.JunctionType = JunctionType.NextStep;
this.InvalidateVisual();
}
private Point _myCenterPoint;
public override Point MyCenterPoint { get => _myCenterPoint; }
public override void Render(DrawingContext drawingContext)
{
double width = ActualWidth;
double height = ActualHeight;
var background = GetBackgrounp();
// 输入连接器的背景
var connectorRect = new Rect(0, 0, width, height);
drawingContext.DrawRectangle(Brushes.Transparent, null, connectorRect);
// 定义圆形的大小和位置
double connectorSize = 10; // 连接器的大小
double circleCenterX = 8; // 圆心 X 坐标
double circleCenterY = height / 2; // 圆心 Y 坐标
_myCenterPoint = new Point(circleCenterX - connectorSize / 2, circleCenterY); // 中心坐标
var circlePoint = new Point(circleCenterX, circleCenterY);
// 绘制连接器的圆形部分
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse);
// 绘制连接器的圆形部分
//var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
// 定义三角形的间距
double triangleOffsetX = 4; // 三角形与圆形的间距
double triangleCenterX = circleCenterX + connectorSize / 2 + triangleOffsetX; // 三角形中心 X 坐标
double triangleCenterY = circleCenterY; // 三角形中心 Y 坐标
// 绘制三角形
var pathGeometry = new StreamGeometry();
using (var context = pathGeometry.Open())
{
context.BeginFigure(new Point(triangleCenterX, triangleCenterY - 4.5), true, true);
context.LineTo(new Point(triangleCenterX + 5, triangleCenterY), 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, MyUIFunc.CreateAndFreezePen(), pathGeometry);
}
}
}

View File

@@ -1,61 +0,0 @@
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using Serein.Library;
namespace Serein.Workbench.Node.View
{
public class ResultJunctionControl : JunctionControlBase
{
//public override JunctionType JunctionType { get; } = JunctionType.ReturnData;
public ResultJunctionControl()
{
base.JunctionType = JunctionType.ReturnData;
this.InvalidateVisual();
}
private Point _myCenterPoint;
public override Point MyCenterPoint { get => _myCenterPoint; }
public override void Render(DrawingContext drawingContext)
{
double width = ActualWidth;
double height = ActualHeight;
// 输入连接器的背景
var connectorRect = new Rect(0, 0, width, height);
drawingContext.DrawRectangle(Brushes.Transparent, null, connectorRect);
var background = GetBackgrounp();
// 定义圆形的大小和位置
double connectorSize = 10; // 连接器的大小
double circleCenterX = 8; // 圆心 X 坐标
double circleCenterY = height / 2; // 圆心 Y 坐标
var circlePoint = new Point(circleCenterX, circleCenterY);
_myCenterPoint = new Point(circleCenterX - connectorSize / 2 , circleCenterY); // 中心坐标
// 绘制连接器的圆形部分
var ellipse = new EllipseGeometry(circlePoint, connectorSize / 2, connectorSize / 2);
drawingContext.DrawGeometry(background, MyUIFunc.CreateAndFreezePen(), ellipse);
// 定义三角形的间距
double triangleOffsetX = 4; // 三角形与圆形的间距
double triangleCenterX = circleCenterX + connectorSize / 2 + triangleOffsetX; // 三角形中心 X 坐标
double triangleCenterY = circleCenterY; // 三角形中心 Y 坐标
// 绘制三角形
var pathGeometry = new StreamGeometry();
using (var context = pathGeometry.Open())
{
context.BeginFigure(new Point(triangleCenterX, triangleCenterY - 4.5), true, true);
context.LineTo(new Point(triangleCenterX + 5, triangleCenterY), 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, MyUIFunc.CreateAndFreezePen(), pathGeometry);
}
}
}

View File

@@ -1,198 +0,0 @@
using Serein.Library;
using Serein.Library.Api;
using Serein.Workbench.Node.ViewModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
namespace Serein.Workbench.Node.View
{
/// <summary>
/// 节点控件基类(控件)
/// </summary>
public abstract class NodeControlBase : UserControl, IDynamicFlowNode
{
/// <summary>
/// 节点所在的画布(以后需要将画布封装出来,实现多画布的功能)
/// </summary>
public Canvas NodeCanvas { get; set; }
private INodeContainerControl nodeContainerControl;
/// <summary>
/// 如果该节点放置在了某个容器节点,就会记录这个容器节点
/// </summary>
private INodeContainerControl NodeContainerControl { get; }
/// <summary>
/// 记录与该节点控件有关的所有连接
/// </summary>
private readonly List<ConnectionControl> connectionControls = new List<ConnectionControl>();
public NodeControlViewModelBase ViewModel { get; set; }
protected NodeControlBase()
{
this.Background = Brushes.Transparent;
}
protected NodeControlBase(NodeControlViewModelBase viewModelBase)
{
ViewModel = viewModelBase;
this.Background = Brushes.Transparent;
this.DataContext = viewModelBase;
SetBinding();
}
/// <summary>
/// 放置在某个节点容器中
/// </summary>
public void PlaceToContainer(INodeContainerControl nodeContainerControl)
{
this.nodeContainerControl = nodeContainerControl;
NodeCanvas.Children.Remove(this); // 临时从画布上移除
var result = nodeContainerControl.PlaceNode(this);
if (!result) // 检查是否放置成功,如果不成功,需要重新添加回来
{
NodeCanvas.Children.Add(this); // 从画布上移除
}
}
/// <summary>
/// 从某个节点容器取出
/// </summary>
public void TakeOutContainer()
{
var result = nodeContainerControl.TakeOutNode(this); // 从控件取出
if (result) // 移除成功时才添加到画布上
{
NodeCanvas.Children.Add(this); // 重新添加到画布上
if (nodeContainerControl is NodeControlBase containerControl)
{
this.ViewModel.NodeModel.Position.X = containerControl.ViewModel.NodeModel.Position.X + containerControl.Width + 10;
this.ViewModel.NodeModel.Position.Y = containerControl.ViewModel.NodeModel.Position.Y;
}
}
}
/// <summary>
/// 添加与该节点有关的连接后,记录下来
/// </summary>
/// <param name="connection"></param>
public void AddCnnection(ConnectionControl connection)
{
connectionControls.Add(connection);
}
/// <summary>
/// 删除了连接之后,还需要从节点中的记录移除
/// </summary>
/// <param name="connection"></param>
public void RemoveConnection(ConnectionControl connection)
{
connectionControls.Remove(connection);
connection.Remote();
}
/// <summary>
/// 删除所有连接
/// </summary>
public void RemoveAllConection()
{
foreach (var connection in this.connectionControls)
{
connection.Remote();
}
}
/// <summary>
/// 更新与该节点有关的数据
/// </summary>
public void UpdateLocationConnections()
{
foreach (var connection in this.connectionControls)
{
connection.RefreshLine(); // 主动更新连线位置
}
}
/// <summary>
/// 设置绑定:
/// Canvas.X and Y 画布位置
/// </summary>
public void SetBinding()
{
// 绑定 Canvas.Left
Binding leftBinding = new Binding("X")
{
Source = ViewModel.NodeModel.Position, // 如果 X 属性在当前 DataContext 中
Mode = BindingMode.TwoWay
};
BindingOperations.SetBinding(this, Canvas.LeftProperty, leftBinding);
// 绑定 Canvas.Top
Binding topBinding = new Binding("Y")
{
Source = ViewModel.NodeModel.Position, // 如果 Y 属性在当前 DataContext 中
Mode = BindingMode.TwoWay
};
BindingOperations.SetBinding(this, Canvas.TopProperty, topBinding);
}
/// <summary>
/// 穿透视觉树获取指定类型的第一个元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="parent"></param>
/// <returns></returns>
protected T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (child is T typedChild)
{
return typedChild;
}
var childOfChild = FindVisualChild<T>(child);
if (childOfChild != null)
{
return childOfChild;
}
}
return null;
}
}
//public class FLowNodeObObservableCollection<T> : ObservableCollection<T>
//{
// public void AddRange(IEnumerable<T> items)
// {
// foreach (var item in items)
// {
// this.Items.Add(item);
// }
// OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));
// }
//}
}

View File

@@ -1,26 +0,0 @@
using System.Windows.Input;
namespace Serein.Workbench.Node
{
public class RelayCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Func<object, bool> _canExecute;
public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
{
_execute = execute;
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) => _canExecute == null || _canExecute(parameter);
public void Execute(object parameter) => _execute(parameter);
public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}

View File

@@ -1,297 +0,0 @@
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);
}
}
}

View File

@@ -1,87 +0,0 @@
<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>

View File

@@ -1,87 +0,0 @@
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();
}
}
}

View File

@@ -1,93 +0,0 @@
<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>

View File

@@ -1,162 +0,0 @@
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
}
}

View File

@@ -1,26 +0,0 @@
using Serein.NodeFlow.Model;
using Serein.Workbench.Node.View;
namespace Serein.Workbench.Node.ViewModel
{
public class ExpOpNodeControlViewModel: NodeControlViewModelBase
{
public new SingleExpOpNode NodeModel { get; }
//public string Expression
//{
// get => node.Expression;
// set
// {
// node.Expression = value;
// OnPropertyChanged();
// }
//}
public ExpOpNodeControlViewModel(SingleExpOpNode nodeModel) : base(nodeModel)
{
this.NodeModel = nodeModel;
}
}
}

View File

@@ -1,51 +0,0 @@
using Serein.Library;
using Serein.NodeFlow.Model;
using Serein.Workbench.Node.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace Serein.Workbench.Node.ViewModel
{
public class GlobalDataNodeControlViewModel : NodeControlViewModelBase
{
private SingleGlobalDataNode NodeModel => (SingleGlobalDataNode)base.NodeModel;
/// <summary>
/// 复制全局数据表达式
/// </summary>
public ICommand CommandCopyDataExp { get; }
/// <summary>
/// 刷新数据
/// </summary>
public ICommand CommandRefreshData { get; }
public GlobalDataNodeControlViewModel(SingleGlobalDataNode node) : base(node)
{
CommandCopyDataExp = new RelayCommand( o =>
{
string exp = NodeModel.KeyName;
string copyValue = $"@Get #{exp}#";
Clipboard.SetDataObject(copyValue);
});
}
/// <summary>
/// 自定义参数值
/// </summary>
public string? KeyName
{
get => NodeModel?.KeyName;
set { NodeModel.KeyName = value; OnPropertyChanged(); }
}
}
}

View File

@@ -1,62 +0,0 @@
using Serein.Library;
using Serein.Library.Core;
using Serein.Library.Utils;
using Serein.NodeFlow.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace Serein.Workbench.Node.ViewModel
{
public class ScriptNodeControlViewModel : NodeControlViewModelBase
{
private SingleScriptNode NodeModel => (SingleScriptNode)base.NodeModel;
public string? Script
{
get => NodeModel?.Script;
set { NodeModel.Script = value; OnPropertyChanged(); }
}
public ScriptNodeControlViewModel(NodeModelBase nodeModel) : base(nodeModel)
{
CommandExecuting = new RelayCommand(async o =>
{
try
{
var result = await NodeModel.ExecutingAsync(new DynamicContext(nodeModel.Env));
SereinEnv.WriteLine(InfoType.INFO, result?.ToString());
}
catch (Exception ex)
{
SereinEnv.WriteLine(InfoType.ERROR, ex.ToString());
}
});
CommandLoadScript = new RelayCommand( o =>
{
NodeModel.ReloadScript();
});
}
/// <summary>
/// 加载脚本代码
/// </summary>
public ICommand CommandLoadScript{ get; }
/// <summary>
/// 尝试执行
/// </summary>
public ICommand CommandExecuting { get; }
}
}

View File

@@ -1,7 +0,0 @@
{
"profiles": {
"Serein.Workbench": {
"commandName": "Project"
}
}
}

View File

@@ -1,292 +0,0 @@
<Project>
<PropertyGroup>
<AssemblyName>Serein.Workbench</AssemblyName>
<IntermediateOutputPath>obj\Release\</IntermediateOutputPath>
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
<MSBuildProjectExtensionsPath>D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\</MSBuildProjectExtensionsPath>
<_TargetAssemblyProjectName>Serein.Workbench</_TargetAssemblyProjectName>
<RootNamespace>Serein.Workbench</RootNamespace>
</PropertyGroup>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>True</UseWPF>
<BaseOutputPath>D:\Project\C#\DynamicControl\SereinFlow\.Output</BaseOutputPath>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<!--<IsRoslynComponent>true</IsRoslynComponent>-->
</PropertyGroup>
<ItemGroup>
<Compile Remove="Node\NodeModel\**" />
<Compile Remove="Themes\Condition\**" />
<EmbeddedResource Remove="Node\NodeModel\**" />
<EmbeddedResource Remove="Themes\Condition\**" />
<None Remove="Node\NodeModel\**" />
<None Remove="Themes\Condition\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Node\FlipflopRegionControl.xaml.cs" />
<Compile Remove="Node\NodeBase.cs" />
<Compile Remove="Themes\ConditionControl.xaml.cs" />
<Compile Remove="Themes\ConditionControlModel.cs" />
<Compile Remove="Themes\ExplicitDataControl.xaml.cs" />
<Compile Remove="Themes\ObjectViewerControl1.xaml.cs" />
</ItemGroup>
<ItemGroup>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Library.Core\Serein.Library.Core.csproj" />
<ProjectReference Include="..\Library.Framework\Serein.Library.Framework.csproj" />
<ProjectReference Include="..\Library\Serein.Library.csproj" />
<ProjectReference Include="..\NodeFlow\Serein.NodeFlow.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<Compile Update="Themes\MethodDetailsControl.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\Accessibility.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\Microsoft.CSharp.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\Microsoft.VisualBasic.Core.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\Microsoft.VisualBasic.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\Microsoft.Win32.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\Microsoft.Win32.Registry.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\Microsoft.Win32.Registry.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\Microsoft.Win32.SystemEvents.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\mscorlib.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\netstandard.dll" />
<ReferencePath Include="C:\Users\Az\.nuget\packages\newtonsoft.json\13.0.3\lib\net6.0\Newtonsoft.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\PresentationCore.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\PresentationFramework.Aero.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\PresentationFramework.Aero2.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\PresentationFramework.AeroLite.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\PresentationFramework.Classic.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\PresentationFramework.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\PresentationFramework.Luna.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\PresentationFramework.Royale.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\PresentationUI.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\ReachFramework.dll" />
<ReferencePath Include="D:\Project\C#\DynamicControl\SereinFlow\.Output\Release\net8.0\Serein.Library.Core.dll" />
<ReferencePath Include="D:\Project\C#\DynamicControl\SereinFlow\.Output\Release\net8.0\Serein.Library.dll" />
<ReferencePath Include="D:\Project\C#\DynamicControl\SereinFlow\.Output\Release\librarynet462\Serein.Library.Framework.dll" />
<ReferencePath Include="D:\Project\C#\DynamicControl\SereinFlow\.Output\Release\netstandard2.0\Serein.Library.NodeGenerator.dll" />
<ReferencePath Include="D:\Project\C#\DynamicControl\SereinFlow\.Output\Release\net8.0\Serein.NodeFlow.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.AppContext.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Buffers.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.CodeDom.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Collections.Concurrent.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Collections.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Collections.Immutable.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Collections.NonGeneric.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Collections.Specialized.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.ComponentModel.Annotations.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.ComponentModel.DataAnnotations.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.ComponentModel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.ComponentModel.EventBasedAsync.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.ComponentModel.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.ComponentModel.TypeConverter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Configuration.ConfigurationManager.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Configuration.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Console.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Core.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Data.Common.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Data.DataSetExtensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Data.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Diagnostics.Contracts.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Diagnostics.Debug.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Diagnostics.DiagnosticSource.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Diagnostics.EventLog.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Diagnostics.FileVersionInfo.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Diagnostics.PerformanceCounter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Diagnostics.Process.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Diagnostics.StackTrace.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Diagnostics.TextWriterTraceListener.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Diagnostics.Tools.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Diagnostics.TraceSource.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Diagnostics.Tracing.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.DirectoryServices.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Drawing.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Drawing.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Dynamic.Runtime.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Formats.Asn1.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Formats.Tar.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Globalization.Calendars.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Globalization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Globalization.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.Compression.Brotli.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.Compression.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.Compression.FileSystem.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.Compression.ZipFile.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.FileSystem.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.FileSystem.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.FileSystem.DriveInfo.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.FileSystem.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.FileSystem.Watcher.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.IsolatedStorage.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.MemoryMappedFiles.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.IO.Packaging.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.Pipes.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.Pipes.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.IO.UnmanagedMemoryStream.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Linq.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Linq.Expressions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Linq.Parallel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Linq.Queryable.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Memory.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.Http.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.Http.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.HttpListener.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.Mail.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.NameResolution.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.NetworkInformation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.Ping.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.Quic.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.Requests.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.Security.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.ServicePoint.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.Sockets.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.WebClient.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.WebHeaderCollection.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.WebProxy.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.WebSockets.Client.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Net.WebSockets.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Numerics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Numerics.Vectors.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.ObjectModel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Printing.dll" />
<ReferencePath Include="C:\Users\Az\.nuget\packages\system.reactive\6.0.1\lib\net6.0\System.Reactive.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Reflection.DispatchProxy.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Reflection.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Reflection.Emit.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Reflection.Emit.ILGeneration.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Reflection.Emit.Lightweight.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Reflection.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Reflection.Metadata.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Reflection.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Reflection.TypeExtensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Resources.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Resources.Reader.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Resources.ResourceManager.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Resources.Writer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.CompilerServices.Unsafe.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.CompilerServices.VisualC.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.Handles.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.InteropServices.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.InteropServices.JavaScript.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.InteropServices.RuntimeInformation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.Intrinsics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.Loader.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.Numerics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.Serialization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.Serialization.Formatters.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.Serialization.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.Serialization.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Runtime.Serialization.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.Claims.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.Cryptography.Algorithms.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.Cryptography.Cng.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.Cryptography.Csp.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.Cryptography.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.Cryptography.Encoding.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.Cryptography.OpenSsl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Security.Cryptography.Pkcs.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.Cryptography.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Security.Cryptography.ProtectedData.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.Cryptography.X509Certificates.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Security.Cryptography.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Security.Permissions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.Principal.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.Principal.Windows.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Security.SecureString.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.ServiceModel.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.ServiceProcess.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Text.Encoding.CodePages.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Text.Encoding.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Text.Encoding.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Text.Encodings.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Text.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Text.RegularExpressions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Threading.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Threading.Channels.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Threading.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Threading.Overlapped.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Threading.Tasks.Dataflow.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Threading.Tasks.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Threading.Tasks.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Threading.Tasks.Parallel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Threading.Thread.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Threading.ThreadPool.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Threading.Timer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Transactions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Transactions.Local.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.ValueTuple.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Web.HttpUtility.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Windows.Controls.Ribbon.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Windows.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Windows.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Windows.Input.Manipulations.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Windows.Presentation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\System.Xaml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Xml.Linq.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Xml.ReaderWriter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Xml.Serialization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Xml.XDocument.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Xml.XmlDocument.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Xml.XmlSerializer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Xml.XPath.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\ref\net8.0\System.Xml.XPath.XDocument.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\UIAutomationClient.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\UIAutomationClientSideProviders.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\UIAutomationProvider.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\UIAutomationTypes.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\8.0.10\ref\net8.0\WindowsBase.dll" />
</ItemGroup>
<ItemGroup>
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\LogWindow.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\MainWindow.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\ActionNodeControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\ActionRegionControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\ConditionNodeControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\ConditionRegionControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\DllControlControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\ExpOpNodeControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Node\View\FlipflopNodeControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Themes\InputDialog.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Themes\IOCObjectViewControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Themes\NodeTreeItemViewControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Themes\NodeTreeViewControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Themes\ObjectViewerControl.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Themes\TypeViewerWindow.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\Themes\WindowDialogInput.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\App.g.cs" />
<Compile Include="D:\Project\C#\DynamicControl\SereinFlow\WorkBench\obj\Release\net8.0-windows\GeneratedInternalTypeHelper.g.cs" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="C:\Program Files\dotnet\sdk\9.0.100-rc.2.24474.11\Sdks\Microsoft.NET.Sdk\targets\..\analyzers\Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll" />
<Analyzer Include="C:\Program Files\dotnet\sdk\9.0.100-rc.2.24474.11\Sdks\Microsoft.NET.Sdk\targets\..\analyzers\Microsoft.CodeAnalysis.NetAnalyzers.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\analyzers/dotnet/cs/Microsoft.Interop.ComInterfaceGenerator.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\analyzers/dotnet/cs/Microsoft.Interop.JavaScript.JSImportGenerator.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\analyzers/dotnet/cs/Microsoft.Interop.LibraryImportGenerator.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\analyzers/dotnet/cs/Microsoft.Interop.SourceGeneration.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\analyzers/dotnet/cs/System.Text.Json.SourceGeneration.dll" />
<Analyzer Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\8.0.10\analyzers/dotnet/cs/System.Text.RegularExpressions.Generator.dll" />
</ItemGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>

View File

@@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows;
namespace Serein.Workbench.Themes
{
public partial class BindableRichTextBox : RichTextBox
{
public new FlowDocument Document
{
get { return (FlowDocument)GetValue(DocumentProperty); }
set { SetValue(DocumentProperty, value); }
}
// Using a DependencyProperty as the backing store for Document. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DocumentProperty =
DependencyProperty.Register("Document", typeof(FlowDocument), typeof(BindableRichTextBox), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnDucumentChanged)));
private static void OnDucumentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
RichTextBox rtb = (RichTextBox)d;
rtb.Document = (FlowDocument)e.NewValue;
}
}
}

View File

@@ -1,68 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serein.Workbench.Tool
{
/// <summary>
/// Guid替换工具类
/// </summary>
public class GuidReplacer
{
private class TrieNode
{
public Dictionary<char, TrieNode> Children = new();
public string Replacement; // 替换后的值
}
private readonly TrieNode _root = new();
// 构建字典树
public void AddReplacement(string guid, string replacement)
{
var current = _root;
foreach (var c in guid)
{
if (!current.Children.ContainsKey(c))
{
current.Children[c] = new TrieNode();
}
current = current.Children[c];
}
current.Replacement = replacement;
}
// 替换逻辑
public string Replace(string input)
{
var result = new StringBuilder();
var current = _root;
int i = 0;
while (i < input.Length)
{
if (current.Children.ContainsKey(input[i]))
{
current = current.Children[input[i]];
i++;
if (current.Replacement != null) // 找到匹配
{
result.Append(current.Replacement);
current = _root; // 回到根节点
}
}
else
{
result.Append(input[i]);
current = _root; // 未匹配,回到根节点
i++;
}
}
return result.ToString();
}
}
}