This commit is contained in:
fengjiayi
2025-01-04 22:26:16 +08:00
92 changed files with 253 additions and 10261 deletions

View File

@@ -158,25 +158,7 @@ namespace Serein.Library
|| (start == JunctionType.ArgData && end == JunctionType.ReturnData);
}
//var endType = end.ToConnectyionType();
//if (startType != endType
// || startType == JunctionOfConnectionType.None
// || endType == JunctionOfConnectionType.None)
//{
// return false;
//}
//else
//{
// if (startType == JunctionOfConnectionType.Invoke)
// {
// return end == JunctionType.NextStep;
// }
// else // if (startType == JunctionOfConnectionType.Arg)
// {
// return end == JunctionType.ReturnData;
// }
//}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,22 @@
using Android.App;
using Android.Content.PM;
using Avalonia;
using Avalonia.Android;
namespace Serein.Workbench.Avalonia.Android;
[Activity(
Label = "Serein.Workbench.Avalonia.Android",
Theme = "@style/MyTheme.NoActionBar",
Icon = "@drawable/icon",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)]
public class MainActivity : AvaloniaMainActivity<App>
{
protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
{
return base.CustomizeAppBuilder(builder)
.WithInterFont();
}
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET" />
<application android:label="AvaloniaTest" android:icon="@drawable/Icon" />
</manifest>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<color android:color="@color/splash_background"/>
</item>
<item android:drawable="@drawable/icon"
android:width="120dp"
android:height="120dp"
android:gravity="center" />
</layer-list>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="splash_background">#212121</color>
</resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="splash_background">#FFFFFF</color>
</resources>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MyTheme">
</style>
<style name="MyTheme.NoActionBar" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowActionBar">false</item>
<item name="android:windowBackground">@drawable/splash_screen</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>

View File

@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-android</TargetFramework>
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
<Nullable>enable</Nullable>
<ApplicationId>com.CompanyName.AvaloniaTest</ApplicationId>
<ApplicationVersion>1</ApplicationVersion>
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<AndroidPackageFormat>apk</AndroidPackageFormat>
<AndroidEnableProfiledAot>False</AndroidEnableProfiledAot>
</PropertyGroup>
<ItemGroup>
<AndroidResource Include="Icon.png">
<Link>Resources\drawable\Icon.png</Link>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia.Android" Version="11.2.3" />
<PackageReference Include="Xamarin.AndroidX.Core.SplashScreen" Version="11.2.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Serein.Workbench.Avalonia\Serein.Workbench.Avalonia.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,17 @@
using System.Runtime.Versioning;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Browser;
using Serein.Workbench.Avalonia;
internal sealed partial class Program
{
private static Task Main(string[] args) => BuildAvaloniaApp()
.WithInterFont()
.StartBrowserAppAsync("out");
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>();
}

View File

@@ -0,0 +1 @@
[assembly:System.Runtime.Versioning.SupportedOSPlatform("browser")]

View File

@@ -0,0 +1,13 @@
{
"profiles": {
"Serein.Workbench.Avalonia.Browser": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:7169;http://localhost:5235",
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
}
}
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.WebAssembly">
<PropertyGroup>
<TargetFramework>net8.0-browser</TargetFramework>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia.Browser" Version="11.2.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Serein.Workbench.Avalonia\Serein.Workbench.Avalonia.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,10 @@
{
"wasmHostProperties": {
"perHostConfig": [
{
"name": "browser",
"host": "browser"
}
]
}
}

View File

@@ -0,0 +1,58 @@
/* HTML styles for the splash screen */
.avalonia-splash {
position: absolute;
height: 100%;
width: 100%;
background: white;
font-family: 'Outfit', sans-serif;
justify-content: center;
align-items: center;
display: flex;
pointer-events: none;
}
/* Light theme styles */
@media (prefers-color-scheme: light) {
.avalonia-splash {
background: white;
}
.avalonia-splash h2 {
color: #1b2a4e;
}
.avalonia-splash a {
color: #0D6EFD;
}
}
@media (prefers-color-scheme: dark) {
.avalonia-splash {
background: #1b2a4e;
}
.avalonia-splash h2 {
color: white;
}
.avalonia-splash a {
color: white;
}
}
.avalonia-splash h2 {
font-weight: 400;
font-size: 1.5rem;
}
.avalonia-splash a {
text-decoration: none;
font-size: 2.5rem;
display: block;
}
.avalonia-splash.splash-close {
transition: opacity 200ms, display 200ms;
display: none;
opacity: 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

View File

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<title>Serein.Workbench.Avalonia</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./app.css" />
</head>
<body style="margin: 0; overflow: hidden">
<div id="out">
<div class="avalonia-splash">
<h2>
Powered by
<a href="https://www.avaloniaui.net/" target="_blank">
<svg width="266" height="52" viewBox="0 0 266 52" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M55.8592 47.3941C54.9035 47.3941 54.1184 47.1723 53.504 46.7285C52.9237 46.2848 52.5483 45.6875 52.3776 44.9365C52.2411 44.1856 52.3947 43.3493 52.8384 42.4277L65.9456 13.7045C66.4917 12.544 67.1403 11.7077 67.8912 11.1957C68.6421 10.6496 69.5125 10.3765 70.5024 10.3765C71.4923 10.3765 72.3627 10.6496 73.1136 11.1957C73.8645 11.7077 74.496 12.544 75.008 13.7045L88.2176 42.4277C88.6613 43.3493 88.8149 44.2027 88.6784 44.9877C88.576 45.7387 88.2347 46.336 87.6544 46.7797C87.0741 47.1893 86.3232 47.3941 85.4016 47.3941C84.2411 47.3941 83.3365 47.1211 82.688 46.5749C82.0736 46.0288 81.5275 45.1755 81.0496 44.0149L78.9279 39.0997H62.0415L59.9552 44.0149C59.4432 45.2096 58.8971 46.08 58.3168 46.6261C57.7707 47.1381 56.9515 47.3941 55.8592 47.3941ZM70.4 19.2853L64.6844 32.9045H76.2627L70.5024 19.2853H70.4Z" fill="currentColor"/>
<path d="M101.869 47.3941C100.879 47.3941 100.009 47.1381 99.258 46.6261C98.5071 46.08 97.9096 45.2779 97.4659 44.2197L89.7348 26.4021C89.3593 25.5147 89.2228 24.6955 89.3252 23.9445C89.4276 23.1595 89.786 22.5451 90.4004 22.1013C91.0489 21.6235 91.9364 21.3845 93.0628 21.3845C93.9844 21.3845 94.7353 21.6064 95.3156 22.0501C95.8959 22.4597 96.4079 23.2619 96.8516 24.4565L102.018 37.95L107.552 24.4053C108.03 23.2448 108.559 22.4597 109.14 22.0501C109.72 21.6064 110.522 21.3845 111.546 21.3845C112.433 21.3845 113.133 21.6235 113.645 22.1013C114.191 22.5451 114.516 23.1424 114.618 23.8933C114.755 24.6443 114.618 25.4635 114.208 26.3509L106.324 44.2197C105.88 45.312 105.283 46.1141 104.532 46.6261C103.815 47.1381 102.927 47.3941 101.869 47.3941Z" fill="currentColor"/>
<path d="M126.569 47.4965C124.726 47.4965 123.07 47.1381 121.602 46.4213C120.135 45.7045 118.991 44.7317 118.172 43.5029C117.353 42.2741 116.943 40.8917 116.943 39.3557C116.943 37.5125 117.421 36.0619 118.377 35.0037C119.333 33.9115 120.886 33.1435 123.036 32.6997C125.186 32.2219 128.037 31.9829 131.586 31.9829H133.43V35.9765H131.638C129.897 35.9765 128.48 36.0789 127.388 36.2837C126.33 36.4544 125.562 36.7616 125.084 37.2053C124.64 37.6491 124.418 38.2635 124.418 39.0485C124.418 40.0043 124.743 40.7893 125.391 41.4037C126.074 42.0181 127.047 42.3253 128.31 42.3253C129.299 42.3253 130.17 42.1035 130.921 41.6597C131.706 41.1819 132.32 40.5504 132.764 39.7653C133.208 38.9461 133.43 38.0245 133.43 37.0005V31.1125C133.43 29.6107 133.088 28.5525 132.406 27.9381C131.723 27.2896 130.562 26.9653 128.924 26.9653C128.002 26.9653 126.995 27.0848 125.903 27.3237C124.845 27.5285 123.667 27.8869 122.37 28.3989C121.619 28.7403 120.954 28.8256 120.374 28.6549C119.793 28.4501 119.35 28.1088 119.042 27.6309C118.735 27.1189 118.582 26.5728 118.582 25.9925C118.582 25.3781 118.752 24.7979 119.094 24.2517C119.435 23.6715 119.998 23.2448 120.783 22.9717C122.387 22.3232 123.889 21.8795 125.289 21.6405C126.722 21.4016 128.037 21.2821 129.231 21.2821C131.859 21.2821 134.01 21.6747 135.682 22.4597C137.389 23.2107 138.669 24.3883 139.522 25.9925C140.376 27.5627 140.802 29.5936 140.802 32.0853V43.4517C140.802 44.7147 140.495 45.6875 139.881 46.3701C139.266 47.0528 138.379 47.3941 137.218 47.3941C136.058 47.3941 135.153 47.0528 134.505 46.3701C133.89 45.6875 133.583 44.7147 133.583 43.4517L133.594 43.15C133.594 43.15 133.293 44.032 132.61 44.8853C131.962 45.7045 131.126 46.3531 130.102 46.8309C129.078 47.2747 127.9 47.4965 126.569 47.4965Z" fill="currentColor"/>
<path d="M155.632 47.4965C152.594 47.4965 150.324 46.6603 148.822 44.9877C147.321 43.2811 146.57 40.7552 146.57 37.4101V14.3189C146.57 13.0219 146.894 12.0491 147.542 11.4005C148.225 10.7179 149.198 10.3765 150.461 10.3765C151.69 10.3765 152.628 10.7179 153.277 11.4005C153.959 12.0491 154.301 13.0219 154.301 14.3189V37.1029C154.301 38.5024 154.591 39.5435 155.171 40.2261C155.786 40.8747 156.588 41.1989 157.578 41.1989C157.851 41.1989 158.107 41.1819 158.346 41.1477C158.585 41.1136 158.841 41.0965 159.114 41.0965C159.66 41.0283 160.035 41.1989 160.24 41.6085C160.479 41.984 160.598 42.752 160.598 43.9125C160.598 44.9365 160.394 45.7216 159.984 46.2677C159.574 46.7797 158.943 47.1211 158.09 47.2917C157.748 47.3259 157.356 47.36 156.912 47.3941C156.468 47.4624 156.042 47.4965 155.632 47.4965Z" fill="currentColor"/>
<path d="M175.453 47.4965C172.756 47.4965 170.401 46.9675 168.387 45.9093C166.407 44.8512 164.871 43.3323 163.779 41.3525C162.687 39.3728 162.141 37.0347 162.141 34.3381C162.141 32.3243 162.448 30.5152 163.062 28.9109C163.677 27.3067 164.564 25.9413 165.725 24.8149C166.919 23.6544 168.336 22.784 169.974 22.2037C171.613 21.5893 173.439 21.2821 175.453 21.2821C178.149 21.2821 180.487 21.8112 182.467 22.8693C184.481 23.9275 186.034 25.4293 187.126 27.3749C188.253 29.3205 188.816 31.6416 188.816 34.3381C188.816 36.3861 188.492 38.2123 187.843 39.8165C187.229 41.4208 186.341 42.8032 185.181 43.9637C184.02 45.1243 182.604 46.0117 180.931 46.6261C179.293 47.2064 177.467 47.4965 175.453 47.4965ZM175.453 41.7109C176.579 41.7109 177.552 41.4379 178.371 40.8917C179.19 40.3456 179.839 39.5435 180.317 38.4853C180.795 37.3931 181.034 36.0107 181.034 34.3381C181.034 31.8464 180.522 30.0203 179.498 28.8597C178.474 27.6651 177.125 27.0677 175.453 27.0677C174.361 27.0677 173.388 27.3237 172.534 27.8357C171.715 28.3477 171.067 29.1499 170.589 30.2421C170.145 31.3003 169.923 32.6656 169.923 34.3381C169.923 36.8299 170.435 38.6901 171.459 39.9189C172.483 41.1136 173.814 41.7109 175.453 41.7109Z" fill="currentColor"/>
<path d="M197.411 47.3941C196.148 47.3941 195.175 47.0528 194.492 46.3701C193.844 45.6875 193.52 44.7147 193.52 43.4517V25.2757C193.52 24.0128 193.844 23.0571 194.492 22.4085C195.175 21.7259 196.114 21.3845 197.308 21.3845C198.537 21.3845 199.476 21.7259 200.124 22.4085C200.773 23.0571 201.112 24.1871 201.112 25.45C201.141 25.3955 202.48 23.552 204.016 22.6645C205.586 21.7429 207.361 21.2821 209.34 21.2821C211.354 21.2821 213.01 21.6747 214.307 22.4597C215.604 23.2107 216.577 24.3712 217.225 25.9413C217.874 27.4773 218.198 29.44 218.198 31.8293V43.4517C218.198 44.7147 217.857 45.6875 217.174 46.3701C216.525 47.0528 215.57 47.3941 214.307 47.3941C213.078 47.3941 212.122 47.0528 211.44 46.3701C210.791 45.6875 210.467 44.7147 210.467 43.4517V32.1877C210.467 30.4469 210.143 29.2011 209.494 28.4501C208.88 27.6651 207.924 27.2725 206.627 27.2725C204.988 27.2725 203.674 27.7845 202.684 28.8085C201.729 29.8325 201.251 31.1979 201.251 32.9045V43.4517C201.251 46.08 199.971 47.3941 197.411 47.3941Z" fill="currentColor"/>
<path d="M227.861 47.3429C226.598 47.3429 225.625 46.9845 224.942 46.2677C224.294 45.5168 223.97 44.4757 223.97 43.1445V25.6341C223.97 24.2688 224.294 23.2277 224.942 22.5109C225.625 21.76 226.598 21.3845 227.861 21.3845C229.09 21.3845 230.028 21.76 230.677 22.5109C231.359 23.2277 231.701 24.2688 231.701 25.6341V43.1445C231.701 44.4757 231.377 45.5168 230.728 46.2677C230.079 46.9845 229.124 47.3429 227.861 47.3429ZM227.861 17.1861C226.427 17.1861 225.318 16.8619 224.533 16.2133C223.782 15.5307 223.406 14.5749 223.406 13.3461C223.406 12.0832 223.782 11.1275 224.533 10.4789C225.318 9.79629 226.427 9.45496 227.861 9.45496C229.294 9.45496 230.387 9.79629 231.138 10.4789C231.889 11.1275 232.264 12.0832 232.264 13.3461C232.264 14.5749 231.889 15.5307 231.138 16.2133C230.387 16.8619 229.294 17.1861 227.861 17.1861Z" fill="currentColor"/>
<path d="M246.169 47.4965C244.326 47.4965 242.67 47.1381 241.202 46.4213C239.735 45.7045 238.591 44.7317 237.772 43.5029C236.953 42.2741 236.543 40.8917 236.543 39.3557C236.543 37.5125 237.021 36.0619 237.977 35.0037C238.933 33.9115 240.486 33.1435 242.636 32.6997C244.786 32.2219 247.637 31.9829 251.186 31.9829H253.03V35.9765H251.238C249.497 35.9765 248.08 36.0789 246.988 36.2837C245.93 36.4544 245.162 36.7616 244.684 37.2053C244.24 37.6491 244.018 38.2635 244.018 39.0485C244.018 40.0043 244.343 40.7893 244.991 41.4037C245.674 42.0181 246.647 42.3253 247.91 42.3253C248.899 42.3253 249.77 42.1035 250.521 41.6597C251.306 41.1819 251.92 40.5504 252.364 39.7653C252.808 38.9461 253.03 38.0245 253.03 37.0005V31.1125C253.03 29.6107 252.688 28.5525 252.006 27.9381C251.323 27.2896 250.162 26.9653 248.524 26.9653C247.602 26.9653 246.595 27.0848 245.503 27.3237C244.445 27.5285 243.267 27.8869 241.97 28.3989C241.219 28.7403 240.554 28.8256 239.974 28.6549C239.393 28.4501 238.95 28.1088 238.642 27.6309C238.335 27.1189 238.182 26.5728 238.182 25.9925C238.182 25.3781 238.352 24.7979 238.694 24.2517C239.035 23.6715 239.598 23.2448 240.383 22.9717C241.987 22.3232 243.489 21.8795 244.889 21.6405C246.322 21.4016 247.637 21.2821 248.831 21.2821C251.459 21.2821 253.61 21.6747 255.282 22.4597C256.989 23.2107 258.269 24.3883 259.122 25.9925C259.976 27.5627 260.402 29.5936 260.402 32.0853V43.4517C260.402 44.7147 260.095 45.6875 259.481 46.3701C258.866 47.0528 257.979 47.3941 256.818 47.3941C255.658 47.3941 254.753 47.0528 254.105 46.3701C253.49 45.6875 253.183 44.7147 253.183 43.4517V43.1789C253.183 43.3144 252.893 44.032 252.21 44.8853C251.562 45.7045 250.726 46.3531 249.702 46.8309C248.678 47.2747 247.5 47.4965 246.169 47.4965Z" fill="currentColor"/>
<path d="M22.3444 20.9916C18.7895 20.9916 15.9077 24.0073 15.9077 27.7274C15.9077 31.4475 18.7895 34.4632 22.3444 34.4632C25.8993 34.4632 28.7811 31.4475 28.7811 27.7274C28.7811 24.0073 25.8993 20.9916 22.3444 20.9916Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M37.6937 49.0667H21.9271C10.8346 48.8653 1.90173 39.3893 1.90173 27.7333C1.90173 15.9513 11.0289 6.40002 22.2878 6.40002C33.3638 6.40002 42.3768 15.6435 42.6667 27.161L42.6314 44.4824C42.338 47.0679 40.2434 49.0667 37.6937 49.0667ZM9.22617 24.667C10.5612 18.3725 15.9275 13.6656 22.3444 13.6656C29.7657 13.6656 35.7818 19.9613 35.7818 27.7274C35.7818 27.7857 35.7825 27.8488 35.7831 27.9136C35.7846 28.0483 35.7861 28.1901 35.7818 28.3103V41.6939H28.7907V40.0685C26.877 41.1655 24.6803 41.7892 22.3444 41.7892C15.9275 41.7892 10.5612 37.0823 9.22617 30.7878C10.5043 30.4129 11.4416 29.1847 11.4416 27.7274C11.4416 26.2701 10.5043 25.0419 9.22617 24.667ZM8.33937 29.9683C9.52696 29.9683 10.4897 28.9609 10.4897 27.7181C10.4897 26.4753 9.52696 25.4678 8.33937 25.4678C7.15178 25.4678 6.18904 26.4753 6.18904 27.7181C6.18904 28.9609 7.15178 29.9683 8.33937 29.9683Z" fill="currentColor"/>
</svg>
</a>
</h2>
</div>
</div>
<script type='module' src="./main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,13 @@
import { dotnet } from './_framework/dotnet.js'
const is_browser = typeof window != "undefined";
if (!is_browser) throw new Error(`Expected to be running in a browser`);
const dotnetRuntime = await dotnet
.withDiagnosticTracing(false)
.withApplicationArgumentsFromQuery()
.create();
const config = dotnetRuntime.getConfig();
await dotnetRuntime.runMain(config.mainAssemblyName, [globalThis.location.href]);

View File

@@ -1,40 +0,0 @@
using Avalonia.Controls;
using Serein.Workbench.Avalonia.Custom.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Serein.Workbench.Avalonia.Model
{
/// <summary>
/// 绘制的线
/// </summary>
public class MyLine
{
/// <summary>
/// 将线条绘制出来
/// </summary>
/// <param name="canvas">放置画布</param>
/// <param name="line">线的实体</param>
public MyLine(Canvas canvas, ConnectionLineShape line)
{
Canvas = canvas;
Line = line;
canvas?.Children.Add(line);
}
public Canvas Canvas { get; }
public ConnectionLineShape Line { get; }
/// <summary>
/// 移除线
/// </summary>
public void Remove()
{
Canvas?.Children.Remove(Line);
}
}
}

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

@@ -18,8 +18,7 @@ namespace Serein.Workbench.Node.View
InitializeComponent();
if(ExecuteJunctionControl.MyNode != null)
{
ExecuteJunctionControl.MyNode.Guid = viewModel.NodeModel.Guid;
ExecuteJunctionControl.MyNode.Guid = viewModel.NodeModel.Guid;
}
}

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();
}
}
}