1 Star 0 Fork 247

回忆满满 / AIStudio.Wpf.Diagram

forked from 艾竹 / AIStudio.Wpf.Diagram 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
LGPL-3.0

本画板在WPF-Diagram-Designer的基础上进行的开发,界面框架使用Fluent.Ribbon的框架。

先上源码地址:https://gitee.com/akwkevin/aistudio.-wpf.-diagram

写在前面

友情提示 很多朋友老问为什么编译不过去,您需要安装对应的net版本,或者修改工程的net版本,如下图。 输入图片说明

2023年7月2日更新内容(做一个Block编程画板)

先上一张效果动图,本次更新主要仿照Scratch,目前仅完成拖拽部分,逻辑部分后续完善。 输入图片说明

本次扩展主要内容:

1.Block模块,入口在文件新建下。

输入图片说明

2.简易Block的使用:

输入图片说明

3.仿Scratch的Block的使用(完成图鉴,准备编写逻辑):

输入图片说明

2023年5月17日更新内容(做一个画笔画板)

输入图片说明

更新内容如下

  • [1] 画笔实现
  • [2] 封闭画笔实现
  • [3] 钢笔实现
  • [4] 文字画笔
  • [5] 直线,矩形,椭圆
  • [6] Path形状
  • [7] 取色器
  • [8] 三种画笔可选

画笔示例入口

输入图片说明 输入图片说明

画笔示例截图

输入图片说明

2023年5月1号更新内容(做一个可编程画板):

输入图片说明

1.简单使用,自定义一个text模块的代码如下:

Code = @"using System;
namespace AIStudio.Wpf.CSharpScript
{
    public class Writer
    {   
        public string StringValue{ get; set;} = ""Welcome to AIStudio.Wpf.Diagram"";

        public string Execute()
        {
            return StringValue;
        }
    }
}";

是不是很简单。

2.本次扩展的主要内容

【1】.可编程模块,使用C#语言。

【2】.控制台打印控件,可以打印程序中的Console.WriteLine数据

【3】.为了便于大家使用,写了一个Box工厂分配Box的数据流向效果图。

3.可编程模块的实现原理

使用Microsoft.CodeAnalysis.CSharp.Scripting对代码进行编译,生成Assembly,然后对Assembly反射获得对象,对象内部固定有一个Execute方法,每次扫描的时候执行即可。 1.编译使用的Using,必须添加引用集,为了省事,把整个程序的Reference都放入进行编译,获得引用的核心代码如下:

var references = AppDomain.CurrentDomain.GetAssemblies().Where(p => !p.IsDynamic && !string.IsNullOrEmpty(p.Location)).Select(x => MetadataReference.CreateFromFile(x.Location)).ToList();
//Costura.Fody压缩后,无Location,读取资源文件中的reference
foreach (var assemblyEmbedded in AppDomain.CurrentDomain.GetAssemblies().Where(p => !p.IsDynamic && string.IsNullOrEmpty(p.Location)))
{
    using (var stream = Assembly.GetEntryAssembly().GetManifestResourceStream($"costura.{assemblyEmbedded.GetName().Name.ToLowerInvariant()}.dll.compressed"))
    {
        if (stream != null)
        {
            using (var compressStream = new DeflateStream(stream, CompressionMode.Decompress))
            {
                var memStream = new MemoryStream();
                CopyTo(compressStream, memStream);
                memStream.Position = 0;
                references.Add(MetadataReference.CreateFromStream(memStream));
            }

        }
    }
}

2.动态编译的代码的核心代码如下:

public static Assembly GenerateAssemblyFromCode(string code, out string message)
{
    Assembly assembly = null;
    message = "";
    // 丛代码中转换表达式树
    SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
    // 随机程序集名称
    string assemblyName = Path.GetRandomFileName();
    // 引用

    // 创建编译对象
    CSharpCompilation compilation = CSharpCompilation.Create(assemblyName, new[] { syntaxTree }, References, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

    using (var ms = new MemoryStream())
    {
        // 将编译好的IL代码放入内存流
        EmitResult result = compilation.Emit(ms);

        // 编译失败,提示
        if (!result.Success)
        {
            IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
                        diagnostic.IsWarningAsError ||
                        diagnostic.Severity == DiagnosticSeverity.Error).ToList();
            foreach (Diagnostic diagnostic in failures)
            {
                message += $"{diagnostic.Id}: {diagnostic.GetMessage()}";
                Console.WriteLine(message);
            }
        }
        else
        {
            // 编译成功,从内存中加载编译好的程序集
            ms.Seek(0, SeekOrigin.Begin);
            assembly = Assembly.Load(ms.ToArray());
        }
    }
    return assembly;
}

3.获得编译后的程序集,以及执行。

// 反射获取程序集中 的类
Type type = assembly.GetTypes().FirstOrDefault(p => p.FullName.StartsWith("AIStudio.Wpf"));   //assembly.GetType("AIStudio.Wpf.CSharpScript.Write");

// 创建该类的实例
object obj = Activator.CreateInstance(type);

// 通过反射方式调用类中的方法。
var result = type.InvokeMember("Execute",
    BindingFlags.Default | BindingFlags.InvokeMethod,
    null,
    obj,
    new object[] { });

4.代码编辑模块的实现

选择AvalonEdit控件,另外为了使用VS2019_Dark的黑色皮肤,引用官方Demo中的HL和TextEditlib实现自定义换肤。

输入图片说明

官方Demo的换肤写的超级复杂,看不懂,但是我们只要理解换肤的核心部分就是动态资源字典,因此我简化下,改进后的核心换肤代码如下:

public class TextEditorThemeHelper
{
    static Dictionary<string, ResourceDictionary> ThemeDictionary = new Dictionary<string, ResourceDictionary>();

    public static List<string> Themes = new List<string>() { "Dark", "Light", "TrueBlue", "VS2019_Dark" };
    public static string CurrentTheme { get; set; }

    static TextEditorThemeHelper()
    {
        var resource = new ResourceDictionary { Source = new Uri("/TextEditLib;component/Themes/LightBrushs.xaml", UriKind.RelativeOrAbsolute) };
        ThemeDictionary.Add("Light", resource);

        resource = new ResourceDictionary { Source = new Uri("/TextEditLib;component/Themes/DarkBrushs.xaml", UriKind.RelativeOrAbsolute) };
        ThemeDictionary.Add("Dark", resource);

        Application.Current.Resources.MergedDictionaries.Add(resource);
    }

    /// <summary>
    /// 设置主题
    /// </summary>
    /// <param name="theme"></param>
    public static void SetCurrentTheme(string theme)
    {
        OnAppThemeChanged(theme);//切换到VS2019_Dark
        CurrentTheme = theme;
    }

    /// <summary>
    /// Invoke this method to apply a change of theme to the content of the document
    /// (eg: Adjust the highlighting colors when changing from "Dark" to "Light"
    ///      WITH current text document loaded.)
    /// </summary>
    internal static void OnAppThemeChanged(string theme)
    {
        ThemedHighlightingManager.Instance.SetCurrentTheme(theme);

        if (ThemeDictionary.ContainsKey(theme))
        {
            foreach (var key in ThemeDictionary[theme].Keys)
            {
                ApplyToDynamicResource(key, ThemeDictionary[theme][key]);
            }
        }
        // Does this highlighting definition have an associated highlighting theme?
        else if (ThemedHighlightingManager.Instance.CurrentTheme.HlTheme != null)
        {
            // A highlighting theme with GlobalStyles?
            // Apply these styles to the resource keys of the editor
            foreach (var item in ThemedHighlightingManager.Instance.CurrentTheme.HlTheme.GlobalStyles)
            {
                switch (item.TypeName)
                {
                    case "DefaultStyle":
                        ApplyToDynamicResource(TextEditLib.Themes.ResourceKeys.EditorBackground, item.backgroundcolor);
                        ApplyToDynamicResource(TextEditLib.Themes.ResourceKeys.EditorForeground, item.foregroundcolor);
                        break;

                    case "CurrentLineBackground":
                        ApplyToDynamicResource(TextEditLib.Themes.ResourceKeys.EditorCurrentLineBackgroundBrushKey, item.backgroundcolor);
                        ApplyToDynamicResource(TextEditLib.Themes.ResourceKeys.EditorCurrentLineBorderBrushKey, item.bordercolor);
                        break;

                    case "LineNumbersForeground":
                        ApplyToDynamicResource(TextEditLib.Themes.ResourceKeys.EditorLineNumbersForeground, item.foregroundcolor);
                        break;

                    case "Selection":
                        ApplyToDynamicResource(TextEditLib.Themes.ResourceKeys.EditorSelectionBrush, item.backgroundcolor);
                        ApplyToDynamicResource(TextEditLib.Themes.ResourceKeys.EditorSelectionBorder, item.bordercolor);
                        break;

                    case "Hyperlink":
                        ApplyToDynamicResource(TextEditLib.Themes.ResourceKeys.EditorLinkTextBackgroundBrush, item.backgroundcolor);
                        ApplyToDynamicResource(TextEditLib.Themes.ResourceKeys.EditorLinkTextForegroundBrush, item.foregroundcolor);
                        break;

                    case "NonPrintableCharacter":
                        ApplyToDynamicResource(TextEditLib.Themes.ResourceKeys.EditorNonPrintableCharacterBrush, item.foregroundcolor);
                        break;

                    default:
                        throw new System.ArgumentOutOfRangeException("GlobalStyle named '{0}' is not supported.", item.TypeName);
                }
            }
        }

    }

    /// <summary>
    /// Re-define an existing <seealso cref="SolidColorBrush"/> and backup the originial color
    /// as it was before the application of the custom coloring.
    /// </summary>
    /// <param name="key"></param>
    /// <param name="newColor"></param>
    private static void ApplyToDynamicResource(ComponentResourceKey key, Color? newColor)
    {
        if (Application.Current.Resources[key] == null || newColor == null)
            return;

        // Re-coloring works with SolidColorBrushs linked as DynamicResource
        if (Application.Current.Resources[key] is SolidColorBrush)
        {
            //backupDynResources.Add(resourceName);

            var newColorBrush = new SolidColorBrush((Color)newColor);
            newColorBrush.Freeze();

            Application.Current.Resources[key] = newColorBrush;
        }
    }

    private static void ApplyToDynamicResource(object key, object newValue)
    {
        if (Application.Current.Resources[key] == null || newValue == null)
            return;

        Application.Current.Resources[key] = newValue;
    }
}

使用方法: TextEditorThemeHelper.SetCurrentTheme("VS2019_Dark");

或者 TextEditorThemeHelper.SetCurrentTheme("TrueBlue");

或者 TextEditorThemeHelper.SetCurrentTheme("Dark");

或者 TextEditorThemeHelper.SetCurrentTheme("Light");

是不是超级简单。

5.代码编辑模块的编译与测试。

输入图片说明

输入图片说明

6.WPF打印控制台数据

控制台打印方法支持切换运行输出方法Console.SetOut,核心代码如下:
public class ConsoleWriter : TextWriter
{
    private readonly Action<string> _Write;
    private readonly Action<string> _WriteLine;
    private readonly Action<string, string, string, int> _WriteCallerInfo;

    public ConsoleWriter()
    {

    }

    /// <summary>
    /// Console 输出重定向
    /// </summary>
    /// <param name="write">日志方法委托(针对于 Write)</param>
    /// <param name="writeLine">日志方法委托(针对于 WriteLine)</param>
    public ConsoleWriter(Action<string> write, Action<string> writeLine, Action<string, string, string, int> writeCallerInfo)
    {
        _Write = write;
        _WriteLine = writeLine?? write;
        _WriteCallerInfo = writeCallerInfo;
    }

    /// <summary>
    /// Console 输出重定向
    /// </summary>
    /// <param name="write">日志方法委托(针对于 Write)</param>
    /// <param name="writeLine">日志方法委托(针对于 WriteLine)</param>
    public ConsoleWriter(Action<string> write, Action<string> writeLine)
    {
        _Write = write;
        _WriteLine = writeLine;
    }

    /// <summary>
    /// Console 输出重定向
    /// </summary>
    /// <param name="write">日志方法委托</param>
    public ConsoleWriter(Action<string> write)
    {
        _Write = write;
        _WriteLine = write;
    }

    /// <summary>
    /// Console 输出重定向(带调用方信息)
    /// </summary>
    /// <param name="write">日志方法委托(后三个参数为 CallerFilePath、CallerMemberName、CallerLineNumber)</param>
    public ConsoleWriter(Action<string, string, string, int> write)
    {
        _WriteCallerInfo = write;
    }

    /// <summary>
    /// 使用 UTF-16 避免不必要的编码转换
    /// </summary>
    public override Encoding Encoding => Encoding.Unicode;

    /// <summary>
    /// 最低限度需要重写的方法
    /// </summary>
    /// <param name="value">消息</param>
    public override void Write(string value)
    {
        if (_WriteCallerInfo != null)
        {
            WriteWithCallerInfo(value);
            return;
        }

        _Write(value);
    }

    /// <summary>
    /// 为提高效率直接处理一行的输出
    /// </summary>
    /// <param name="value">消息</param>
    public override void WriteLine(string value)
    {
        if (_WriteCallerInfo != null)
        {
            WriteWithCallerInfo(value);
            return;
        }

        _WriteLine(value);
    }

    /// <summary>
    /// 带调用方信息进行写消息
    /// </summary>
    /// <param name="value">消息</param>
    private void WriteWithCallerInfo(string value)
    {
        //3、System.Console.WriteLine -> 2、System.IO.TextWriter + SyncTextWriter.WriteLine -> 1、DotNet.Utilities.ConsoleHelper.ConsoleWriter.WriteLine -> 0、DotNet.Utilities.ConsoleHelper.ConsoleWriter.WriteWithCallerInfo
        var callInfo = ClassHelper.GetMethodInfo(4);
        _WriteCallerInfo(value, callInfo?.FileName, callInfo?.MethodName, callInfo?.LineNumber ?? 0);
    }

    public override void Close()
    {
        var standardOutput = new StreamWriter(Console.OpenStandardOutput());
        standardOutput.AutoFlush = true;
        Console.SetOut(standardOutput);
        base.Close();
    }
}

使用:

ConsoleWriter ConsoleWriter = new ConsoleWriter(_write, _writeLine);

Console.SetOut(ConsoleWriter);

7.动态编译模块的输入输出自动生成。

1.输入输出模块:public string Value{ get; set;} 2.输入模块:public string Value{private get; set;} 3.输出模块:public string Value{get;private set;} 4.与外部交互模块:private string Value{ get; set;} ,必须同名同属性。 核心代码如下:

public static Dictionary<string, List<PropertyInfo>> GetPropertyInfo(Type type)
{
    Dictionary<string, List<PropertyInfo>> puts = new Dictionary<string, List<PropertyInfo>>()
    {
        {"Input", new List<PropertyInfo>() },
        {"Output", new List<PropertyInfo>() },
        {"Input_Output", new List<PropertyInfo>() },
        {"Inner", new List<PropertyInfo>() }
    };

    try
    {
        foreach (System.Reflection.PropertyInfo info in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            if (info.CanRead && info.CanWrite)
            {
                if (info.SetMethod.IsPublic && info.GetMethod.IsPublic)
                {
                    puts["Input_Output"].Add(info);
                }
                else if (info.SetMethod.IsPublic)
                {
                    puts["Input"].Add(info);
                }
                else if (info.GetMethod.IsPublic)
                {
                    puts["Output"].Add(info);
                }
            }
            else if (info.CanRead)
            {
                if (info.GetMethod.IsPublic)
                {
                    puts["Output"].Add(info);
                }
            }
        }

        foreach (System.Reflection.PropertyInfo info in type.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance))
        {
            if (info.CanRead)
            {
                puts["Inner"].Add(info);
            }
        }
    }
    catch (Exception ex)
    {

    }

    return puts;
}

8.最后介绍一下Demo的实现。

1#.Int整数模块,界面定义一个TextBox绑定Int模块的输入管脚。 2#.Box产生模块,如果内部数组为空,那么按照输入管脚的数量初始化一个容量为输入整数数量的数组(随机颜色与形状),然后把数据放到输出管脚,当数据被取走后,下一个数据再次放到输出管脚。 3#.Bool模块,为false的时候按照颜色进行分配,为true的时候按照形状进行分配。 4#.Box分配模块,当输入管脚为空的时候,2#模块的输出可以移动到4#的输入管脚,移动时间为1s,移动完成后,清除2#模块的输出。同时把数据按照颜色或者形状分配到输出,同时把输入管脚清除。 按照颜色分配时: (1.如果颜色为红色,那么输出到1号 (2.如果颜色为橙色,那么输出到2号 (3.如果颜色为黄色,那么输出到3号 (4.如果颜色为绿色,那么输出到4号 (5.如果颜色为青色,那么输出到5号 (6.如果颜色为蓝色,那么输出到6号 (7.如果颜色为紫色,那么输出到7号 按照形状分配时: (1.如果形状为圆形,那么输出到1号 (2.如果形状为三角形,那么输出到2号 (3.如果形状为方形,那么输出到3号 (4.如果形状为菱形,那么输出到4号 (5.如果形状为梯形,那么输出到5号 (6.如果形状为五角星,那么输出到6号 (7.如果形状为六边形,那么输出到7号 6#.有两个红色|圆形收集器(7#,8#),按两个容器中的数量比较反馈,均匀分配到这两个收集器中。 9#,10#,11#,12#,13#,14#按照管脚取走数据即可。

2023年4月5号更新内容(本次更新主要仿照百度脑图):

1.思维导图、目录组织图、鱼骨头图、逻辑结构图、组织结构图,入口在文件新建下。

输入图片说明

2.思维导图工具栏(只有思维导图模式下可见)

输入图片说明

2.1插入链接

输入图片说明

2.2插入图片

输入图片说明

2.3插入备注

输入图片说明

2.4插入优先级

输入图片说明

2.5插入进度

输入图片说明

2.6切换类型

输入图片说明 输入图片说明 输入图片说明 输入图片说明

2.7切换主题

输入图片说明 输入图片说明 输入图片说明 输入图片说明 输入图片说明 输入图片说明

2.8还有展开节点,全选,居中,适应窗体大小等功能,不在介绍。

3 添加搜索功能(不仅仅思维导图可以使用)

输入图片说明

4 MindEditor:最后为了方便大家使用,我封装了一个思维脑图的控件MindEditor,可以直接绑定json格式的数据,数据改变,可以直接加载应用。(见AIStudio.Wpf.DiagramDesigner.Demo

输入图片说明

2023年2月5号更新内容:

本次更新主要参照了一个Blazor的Diagram的画线算法,链接地址:https://github.com/Blazor-Diagrams/Blazor.Diagrams,感谢作者。

1.连线改进,新增连线算法,目前共4种连线:Smooth(曲线),Straight(直线),Boundary(网格边界连接模式),Corner(折线)

2.序列化改进,xml与json序列化,新增自定义元素后,无需更改根元素,只需要在新增的元素上添加序列化的对象即可,扩展性更灵活了。

3.箭头改进,箭头按照连线的实际角度显示(即0-360度),还支持自定义的箭头path。

4.新增快捷键自定义扩展,用户可根据自己的习惯定义快捷键。

5.FlowchartEditor:封装了一个标准的工作流控件FlowchartEditor,具体使用可以参照开源权限管理框架种的用法: https://gitee.com/akwkevin/aistudio.-wpf.-aclient

nuget地址:输入图片说明

6.连接上添加动画:路径动画效果和线条流动效果。

7.改变结构,使用户更容易自定义自己的样式,覆盖系统默认样式。

8.从Blazor.Diagrams种引入PortlessLinks(直接连接两个node,不需要port),自动连接节点Snapping,按距离最近连接ReconnectLinksToClosestPorts

9.新增Demo示例,帮助用户快速上手,见底部2023年2月5号更新附加说明。

2023年之前发布内容:

界面图:

本画板在WPF-Diagram-Designer进行的开发,界面框架使用Fluent.Ribbon的框架。

界面图: 输入图片说明

1.支持字体样式,字体颜色,字体阴影,对齐方向,行间距。

2.支持复制粘贴剪贴,格式化,撤销重做。

3.支持形状绘制。

4.连接线

5.位置,组合,对齐

6.元素翻转,旋转。

7.填充颜色,支持线性渐变色,径向渐变色等

8.支持箭头样式

9.锁定与解锁

10.快速样式

11.支持矢量文本,二维码

12.支持插入图片,视频,SVG

13.支持画板大小,方向,标尺,网格是否显示,画板背景色

14.支持流程图(在文件新建下-基本绘图-流程图)

输入图片说明

输入图片说明

15支持逻辑图(在文件新建下-基本绘图-逻辑图)

输入图片说明

16支持SFC顺序控制图(在文件新建下-基本绘图-顺序控制图)

输入图片说明

示例项目说明(AIStudio.Wpf.DiagramDesigner.Demo)目录如下:

1 Simple 简单示例

输入图片说明

2 Locked 锁定节点

3 Events 事件(暂未完成,敬请期待)

4 DynamicInsertions 动态插入(暂未完成,敬请期待)

5 Performance 性能(100个节点生成)

6 Zoom 放大缩小

7 SnapToGrid 对齐到网格

输入图片说明

8 DragAndDrop 拖拽

输入图片说明

9 Nodes 节点示例

9.1 Svg svg样式

输入图片说明

9.2 CustomDefinedNode 自定义节点

输入图片说明

9.3 PortlessLinks 无Port的node连接

输入图片说明

9.4 GradientNode 渐变色node

输入图片说明

9.5 Rotate 旋转node(连接线还需要优化,还算连接在旋转之前的位置上)

输入图片说明

10 Links 连线示例

10.1 Snapping 连接线靠近节点自动连接
10.2 Labels 连接线上的文字(支持多处)

输入图片说明

10.3 Vertices 连接线上的中间节点

输入图片说明

10.4 Markers 箭头,支持自定义

输入图片说明

10.5 Routers 连线模式

输入图片说明

10.6 PathGenerators 连线算法

输入图片说明

11 Ports 连接点示例

11.1 ColoredPort 彩色连接点,相同颜色的连接点才能连接

输入图片说明

11.2 InnerPort 内部连接点

输入图片说明

12 Groups 分组示例

12.1 Group 分组
12.2 CustomDefinedGroup 自定义分组
12.3 CustomShortcutGroup 自定义分组快捷键

13 Texts 文本节点示例

13.1 Text 文本
13.2 Alignment 对齐方式
13.3 FontSize 字体大小
13.4 ColorText 彩色字体

输入图片说明

13.5 OutlineText 轮廓文本

14 Customization 自定义

14.1 CustomNode 覆盖默认节点样式

输入图片说明

14.2 CustomLink 设置线条连接样式

输入图片说明

14.3 CustomPort 覆盖默认连接点样式

输入图片说明

14.4 CustomGroup 覆盖默认分组样式

输入图片说明

15 Algorithms 算法

14.6 ReconnectLinksToClosestPorts 重新计算,按最近的连接点连接。

15 Animations

15.1 PathAnimation 动画路径

输入图片说明

15.2 LineAnimation 线条流动动画

输入图片说明

16 Editor

16.1 FlowchartEditor 工作流封装控件

采用兼容主流的diagram的序列化格式

输入图片说明

{"Nodes":[{"Kind":1,"UserIds":null,"RoleIds":null,"ActType":null,"Id":"e0f2c29c-2c89-4c0c-857e-35eb0b121d7e","ParentId":null,"Name":null,"Color":"#1890ff","Label":"开始","Width":100.0,"Height":80.0,"X":12.5,"Y":147.5,"Type":"FlowchartNode","ZIndex":0,"PortAlignmentList":["Top","Bottom","Left","Right","Top","Bottom","Left","Right"]},{"Kind":3,"UserIds":[],"RoleIds":[],"ActType":null,"Id":"716f64ec-bcdb-438c-9748-9546abf990cc","ParentId":null,"Name":null,"Color":"#1890ff","Label":"节点1","Width":100.0,"Height":80.0,"X":137.5,"Y":147.5,"Type":"FlowchartNode","ZIndex":2,"PortAlignmentList":["Top","Bottom","Left","Right","Top","Bottom","Left","Right"]},{"Kind":4,"UserIds":null,"RoleIds":null,"ActType":null,"Id":"3cd6c332-6b5b-44ef-96c4-c7aef66fd5dd","ParentId":null,"Name":null,"Color":"#1890ff","Label":"条件节点","Width":100.0,"Height":80.0,"X":262.5,"Y":147.5,"Type":"FlowchartNode","ZIndex":3,"PortAlignmentList":["Top","Bottom","Left","Right","Top","Bottom","Left","Right"]},{"Kind":3,"UserIds":[],"RoleIds":[],"ActType":null,"Id":"7d953234-ddff-4701-a52a-bf6460ffa7b9","ParentId":null,"Name":null,"Color":"#1890ff","Label":"节点2","Width":100.0,"Height":80.0,"X":387.5,"Y":22.5,"Type":"FlowchartNode","ZIndex":6,"PortAlignmentList":["Top","Bottom","Left","Right","Top","Bottom","Left","Right"]},{"Kind":3,"UserIds":[],"RoleIds":[],"ActType":null,"Id":"7dfd4102-2751-42c7-a386-adcfcca27ede","ParentId":null,"Name":null,"Color":"#1890ff","Label":"节点3","Width":100.0,"Height":80.0,"X":387.5,"Y":272.5,"Type":"FlowchartNode","ZIndex":7,"PortAlignmentList":["Top","Bottom","Left","Right","Top","Bottom","Left","Right"]},{"Kind":2,"UserIds":null,"RoleIds":null,"ActType":null,"Id":"ad57e53f-8860-4212-9afb-f67e14eecbc8","ParentId":null,"Name":null,"Color":"#1890ff","Label":"结束","Width":100.0,"Height":80.0,"X":512.5,"Y":147.5,"Type":"FlowchartNode","ZIndex":10,"PortAlignmentList":["Top","Bottom","Left","Right","Top","Bottom","Left","Right"]}],"Links":[{"Id":"65f6432f-2084-462d-93d8-a6b3ff889182","Color":"#FF808080","SelectedColor":"#FF000000","Width":2.0,"Label":null,"SourceId":"e0f2c29c-2c89-4c0c-857e-35eb0b121d7e","TargetId":"716f64ec-bcdb-438c-9748-9546abf990cc","SourcePortAlignment":"Right","TargetPortAlignment":"Left","Type":"DiagramLink","Router":null,"PathGenerator":null,"SourceMarkerPath":null,"SourceMarkerWidth":null,"TargetMarkerPath":null,"TargetMarkerWidth":null},{"Id":"7d1dcf2d-ee69-4c24-84ff-3a99b6555692","Color":"#FF808080","SelectedColor":"#FF000000","Width":2.0,"Label":null,"SourceId":"716f64ec-bcdb-438c-9748-9546abf990cc","TargetId":"3cd6c332-6b5b-44ef-96c4-c7aef66fd5dd","SourcePortAlignment":"Right","TargetPortAlignment":"Left","Type":"DiagramLink","Router":null,"PathGenerator":null,"SourceMarkerPath":null,"SourceMarkerWidth":null,"TargetMarkerPath":null,"TargetMarkerWidth":null},{"Id":"cd18c02f-0cdb-4eb5-9793-b9db87eeea09","Color":"#FF808080","SelectedColor":"#FF000000","Width":2.0,"Label":"条件1","SourceId":"3cd6c332-6b5b-44ef-96c4-c7aef66fd5dd","TargetId":"7d953234-ddff-4701-a52a-bf6460ffa7b9","SourcePortAlignment":"Top","TargetPortAlignment":"Left","Type":"DiagramLink","Router":null,"PathGenerator":null,"SourceMarkerPath":null,"SourceMarkerWidth":null,"TargetMarkerPath":null,"TargetMarkerWidth":null},{"Id":"69bbb083-8eb4-403b-937a-b0f0d3c80eb0","Color":"#FF808080","SelectedColor":"#FF000000","Width":2.0,"Label":"条件2","SourceId":"3cd6c332-6b5b-44ef-96c4-c7aef66fd5dd","TargetId":"7dfd4102-2751-42c7-a386-adcfcca27ede","SourcePortAlignment":"Bottom","TargetPortAlignment":"Left","Type":"DiagramLink","Router":null,"PathGenerator":null,"SourceMarkerPath":null,"SourceMarkerWidth":null,"TargetMarkerPath":null,"TargetMarkerWidth":null},{"Id":"d640c547-5ba8-428c-8d65-74874b1d28bd","Color":"#FF808080","SelectedColor":"#FF000000","Width":2.0,"Label":null,"SourceId":"7d953234-ddff-4701-a52a-bf6460ffa7b9","TargetId":"ad57e53f-8860-4212-9afb-f67e14eecbc8","SourcePortAlignment":"Right","TargetPortAlignment":"Top","Type":"DiagramLink","Router":null,"PathGenerator":null,"SourceMarkerPath":null,"SourceMarkerWidth":null,"TargetMarkerPath":null,"TargetMarkerWidth":null},{"Id":"74ad5635-c96d-42e8-9c0a-42c613c66b7a","Color":"#FF808080","SelectedColor":"#FF000000","Width":2.0,"Label":null,"SourceId":"7dfd4102-2751-42c7-a386-adcfcca27ede","TargetId":"ad57e53f-8860-4212-9afb-f67e14eecbc8","SourcePortAlignment":"Right","TargetPortAlignment":"Bottom","Type":"DiagramLink","Router":null,"PathGenerator":null,"SourceMarkerPath":null,"SourceMarkerWidth":null,"TargetMarkerPath":null,"TargetMarkerWidth":null}]}

近期会持续更新,欢迎大家光临。

最后上一个动画流程图。

输入图片说明

特别说明

博客园文章地址 https://www.cnblogs.com/akwkevin/p/15047453.html

用Wpf做一个Diagram画板(续2)(包含封装一个控件FlowchartEditor): https://www.cnblogs.com/akwkevin/p/17093865.html

用Wpf做一个思维导图(续3-Diagram画板)https://www.cnblogs.com/akwkevin/p/17288814.html

用Wpf做一个可编程画板(续4-Diagram画板)https://www.cnblogs.com/akwkevin/p/17367212.html

用Wpf做一个画笔画板(续5-Diagram画板)https://www.cnblogs.com/akwkevin/p/17417546.html

捐助 如果您觉得我们的开源软件对你有所帮助,请扫下方二维码打赏我们一杯咖啡,开源不易,感谢您的支持。(可以联系我,在下面添加特别鸣谢,谢谢。)

捐赠列表:

输入图片说明

相关链接地址:

Fluent.Ribbon: https://github.com/fluentribbon/Fluent.Ribbon

WPF-Diagram-Designer:https://github.com/LinRaise/WPF-Diagram-Designer

个人QQ:80267720,

QQ技术交流群1:51286643(已满),QQ技术交流群2:51280970(如果您还喜欢,帮忙点个星,谢谢)

特别感谢:https://dotnet9.com/ 的站长:dotnet9。  

有想加入开发的朋友可以联系我。
GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.

简介

用Wpf做一个Diagram画板(包含流程图FlowChart,思维导图MindEditor,可编程模块等等) 展开 收起
C#
LGPL-3.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C#
1
https://gitee.com/huiyimanman/aistudio.-wpf.-diagram.git
git@gitee.com:huiyimanman/aistudio.-wpf.-diagram.git
huiyimanman
aistudio.-wpf.-diagram
AIStudio.Wpf.Diagram
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891