无法通过Avalon Dock Manager维护Xelements的WPF画布序列化/反序列化

如何解决无法通过Avalon Dock Manager维护Xelements的WPF画布序列化/反序列化

在使用WPF在Canvas中设计图的过程中,我将Canvas容器放入Avalon Docking Manager控件(对接文档)中,然后,如果在对接文档之间进行切换,则无法看到元素和元素的反序列化过程。第一次打开XML文件时,元素的连接器是否断开,而切换Avalon停靠容器时,该图丢失了吗?

请在下面查看我的序列化/反序列化代码:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Xml;
using System.Xml.Linq;
using Microsoft.Win32;
using Xceed.Wpf.AvalonDock;
using Xceed.Wpf.AvalonDock.Layout.Serialization;

namespace DiagramDesigner
{
public partial class DesignerCanvas
{




    public static RoutedCommand DistributeHorizontal = new RoutedCommand();
    public static RoutedCommand DistributeVertical = new RoutedCommand();
    public static RoutedCommand SelectAll = new RoutedCommand();

    public DesignerCanvas()
    {
        this.CommandBindings.Add(new CommandBinding(ApplicationCommands.New,New_Executed));
        this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Open,Open_Executed));
        this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Save,Save_Executed));
        this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Print,Print_Executed));
        this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut,Cut_Executed,Cut_Enabled));
        
        this.CommandBindings.Add(new CommandBinding(DesignerCanvas.SelectAll,SelectAll_Executed));
        SelectAll.InputGestures.Add(new KeyGesture(Key.A,ModifierKeys.Control));

        this.AllowDrop = true;
        Clipboard.Clear();

    }

    #region New Command

    private void New_Executed(object sender,ExecutedRoutedEventArgs e)
    {
        this.Children.Clear();
        this.SelectionService.ClearSelection();
    }

    #endregion

    #region Open Command

    private void Open_Executed(object sender,ExecutedRoutedEventArgs e)
    {
        XElement root = LoadSerializedDataFromFile();

        if (root == null)
            return;

        this.Children.Clear();
        this.SelectionService.ClearSelection();

        IEnumerable<XElement> itemsXML = root.Elements("DesignerItems").Elements("DesignerItem");
        foreach (XElement itemXML in itemsXML)
        {
            Guid id = new Guid(itemXML.Element("ID").Value);
            DesignerItem item = DeserializeDesignerItem(itemXML,id,0);
            this.Children.Add(item);
            SetConnectorDecoratorTemplate(item);
        }

        this.InvalidateVisual();

        IEnumerable<XElement> connectionsXML = root.Elements("Connections").Elements("Connection");
        foreach (XElement connectionXML in connectionsXML)
        {
            Guid sourceID = new Guid(connectionXML.Element("SourceID").Value);
            Guid sinkID = new Guid(connectionXML.Element("SinkID").Value);

            String sourceConnectorName = connectionXML.Element("SourceConnectorName").Value;
            String sinkConnectorName = connectionXML.Element("SinkConnectorName").Value;

            Connector sourceConnector = GetConnector(sourceID,sourceConnectorName);
            Connector sinkConnector = GetConnector(sinkID,sinkConnectorName);

            Connection connection = new Connection(sourceConnector,sinkConnector);
            Canvas.SetZIndex(connection,Int32.Parse(connectionXML.Element("zIndex").Value));

            this.Children.Add(connection);
        }
    }

    #endregion

    #region Save Command

    private void Save_Executed(object sender,ExecutedRoutedEventArgs e)
    {

        

        
        IEnumerable<DesignerItem> designerItems = this.Children.OfType<DesignerItem>();
        IEnumerable<Connection> connections = this.Children.OfType<Connection>();

        XElement designerItemsXML = SerializeDesignerItems(designerItems);
        XElement connectionsXML = SerializeConnections(connections);

        XElement root = new XElement("Root");
        root.Add(designerItemsXML);
        root.Add(connectionsXML);

        
            
        

        SaveFile(root);
    }

    #endregion

    #region Print Command

    #region SelectAll Command

    private void SelectAll_Executed(object sender,ExecutedRoutedEventArgs e)
    {
        SelectionService.SelectAll();
    }

    #endregion
    #region Helper Methods

    private XElement LoadSerializedDataFromFile()
    {
        OpenFileDialog openFile = new OpenFileDialog();
        openFile.Filter = "Designer Files (*.xml)|*.xml|All Files (*.*)|*.*";

        if (openFile.ShowDialog() == true)
        {
            try
            {

                return XElement.Load(openFile.FileName);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.StackTrace,e.Message,MessageBoxButton.OK,MessageBoxImage.Error);
            }
        }

        return null;
    }

    void SaveFile(XElement xElement)
    {
        SaveFileDialog saveFile = new SaveFileDialog();
        saveFile.Filter = "Files (*.xml)|*.xml|All Files (*.*)|*.*";
        if (saveFile.ShowDialog() == true)
        {
            try
            {

                xElement.Save(saveFile.FileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace,ex.Message,MessageBoxImage.Error);
            }
        }
    }

    private XElement LoadSerializedDataFromClipBoard()
    {
        if (Clipboard.ContainsData(DataFormats.Xaml))
        {
            String clipboardData = Clipboard.GetData(DataFormats.Xaml) as String;

            if (String.IsNullOrEmpty(clipboardData))
                return null;
            try
            {
                return XElement.Load(new StringReader(clipboardData));
            }
            catch (Exception e)
            {
                MessageBox.Show(e.StackTrace,MessageBoxImage.Error);
            }
        }

        return null;
    }

    private XElement SerializeDesignerItems(IEnumerable<DesignerItem> designerItems)
    {
        
        XElement serializedItems = new XElement("DesignerItems",from item in designerItems
                                   let contentXaml = XamlWriter.Save(((DesignerItem)item).Content)
                                   select new XElement("DesignerItem",new XElement("Left",Canvas.GetLeft(item)),new XElement("Top",Canvas.GetTop(item)),new XElement("Width",item.Width),new XElement("Height",item.Height),new XElement("ID",item.ID),new XElement("zIndex",Canvas.GetZIndex(item)),new XElement("IsGroup",item.IsGroup),new XElement("ParentID",item.ParentID),new XElement("Content",contentXaml),new XElement("ShapeType",item.XName),new XElement("shapeNAME",item.shapeNAME)
                                            )
                               );

        return serializedItems;
    }
    private XElement SerializeConnections(IEnumerable<Connection> connections)
    {
        var serializedConnections = new XElement("Connections",from connection in connections
                       select new XElement("Connection",new XElement("SourceID",connection.Source.ParentDesignerItem.ID),new XElement("SourceName",connection.Source.ParentDesignerItem.shapeNAME),new XElement("SourceType",connection.Source.ParentDesignerItem.XName),new XElement("SinkID",connection.Sink.ParentDesignerItem.ID),new XElement("SinkName",connection.Sink.ParentDesignerItem.shapeNAME),new XElement("SinkType",connection.Sink.ParentDesignerItem.XName),new XElement("SourceConnectorName",connection.Source.Name),new XElement("SinkConnectorName",connection.Sink.Name),new XElement("SourceArrowSymbol",connection.SourceArrowSymbol),new XElement("SinkArrowSymbol",connection.SinkArrowSymbol),Canvas.GetZIndex(connection))
                                 )
                              );


        

        return serializedConnections;
    }





    private static DesignerItem DeserializeDesignerItem(XElement itemXML,Guid id,double OffsetX,double OffsetY)
    {
        DesignerItem item = new DesignerItem(id);
        item.Width = Double.Parse(itemXML.Element("Width").Value,CultureInfo.InvariantCulture);
        item.Height = Double.Parse(itemXML.Element("Height").Value,CultureInfo.InvariantCulture);
        item.ParentID = new Guid(itemXML.Element("ParentID").Value);
        item.IsGroup = Boolean.Parse(itemXML.Element("IsGroup").Value);
        Canvas.SetLeft(item,Double.Parse(itemXML.Element("Left").Value,CultureInfo.InvariantCulture) + OffsetX);
        Canvas.SetTop(item,Double.Parse(itemXML.Element("Top").Value,CultureInfo.InvariantCulture) + OffsetY);
        Canvas.SetZIndex(item,Int32.Parse(itemXML.Element("zIndex").Value));
        Object content = XamlReader.Load(XmlReader.Create(new StringReader(itemXML.Element("Content").Value)));
        item.shapeNAME= string.Concat(itemXML.Element("shapeNAME").Value);
        item.Content = content;


        return item;


    }

    private void CopyCurrentSelection()
    {
        IEnumerable<DesignerItem> selectedDesignerItems =
            this.SelectionService.CurrentSelection.OfType<DesignerItem>();

        List<Connection> selectedConnections =
            this.SelectionService.CurrentSelection.OfType<Connection>().ToList();

        foreach (Connection connection in this.Children.OfType<Connection>())
        {
            if (!selectedConnections.Contains(connection))
            {
                DesignerItem sourceItem = (from item in selectedDesignerItems
                                           where item.ID == connection.Source.ParentDesignerItem.ID
                                           select item).FirstOrDefault();

                DesignerItem sinkItem = (from item in selectedDesignerItems
                                         where item.ID == connection.Sink.ParentDesignerItem.ID
                                         select item).FirstOrDefault();

                if (sourceItem != null &&
                    sinkItem != null &&
                    BelongToSameGroup(sourceItem,sinkItem))
                {
                    selectedConnections.Add(connection);
                }
            }
        }

        XElement designerItemsXML = SerializeDesignerItems(selectedDesignerItems);
        XElement connectionsXML = SerializeConnections(selectedConnections);

        XElement root = new XElement("Root");
        root.Add(designerItemsXML);
        root.Add(connectionsXML);

        root.Add(new XAttribute("OffsetX",10));
        root.Add(new XAttribute("OffsetY",10));

        Clipboard.Clear();
        Clipboard.SetData(DataFormats.Xaml,root);
    }

    private void DeleteCurrentSelection()
    {
        foreach (Connection connection in SelectionService.CurrentSelection.OfType<Connection>())
        {
            this.Children.Remove(connection);
        }

        foreach (DesignerItem item in SelectionService.CurrentSelection.OfType<DesignerItem>())
        {
            Control cd = item.Template.FindName("PART_ConnectorDecorator",item) as Control;

            List<Connector> connectors = new List<Connector>();
            GetConnectors(cd,connectors);

            foreach (Connector connector in connectors)
            {
                foreach (Connection con in connector.Connections)
                {
                    this.Children.Remove(con);
                }
            }
            this.Children.Remove(item);
        }

        SelectionService.ClearSelection();
        UpdateZIndex();
    }

    private void UpdateZIndex()
    {
        List<UIElement> ordered = (from UIElement item in this.Children
                                   orderby Canvas.GetZIndex(item as UIElement)
                                   select item as UIElement).ToList();

        for (int i = 0; i < ordered.Count; i++)
        {
            Canvas.SetZIndex(ordered[i],i);
        }
    }

    private static Rect GetBoundingRectangle(IEnumerable<DesignerItem> items)
    {
        double x1 = Double.MaxValue;
        double y1 = Double.MaxValue;
        double x2 = Double.MinValue;
        double y2 = Double.MinValue;

        foreach (DesignerItem item in items)
        {
            x1 = Math.Min(Canvas.GetLeft(item),x1);
            y1 = Math.Min(Canvas.GetTop(item),y1);

            x2 = Math.Max(Canvas.GetLeft(item) + item.Width,x2);
            y2 = Math.Max(Canvas.GetTop(item) + item.Height,y2);
        }

        return new Rect(new Point(x1,y1),new Point(x2,y2));
    }

    private void GetConnectors(DependencyObject parent,List<Connector> connectors)
    {
        int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < childrenCount; i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(parent,i);
            if (child is Connector)
            {
                connectors.Add(child as Connector);
            }
            else
                GetConnectors(child,connectors);
        }
    }

    private Connector GetConnector(Guid itemID,String connectorName)
    {
        DesignerItem designerItem = (from item in this.Children.OfType<DesignerItem>()
                                     where item.ID == itemID
                                     select item).FirstOrDefault();

        Control connectorDecorator = designerItem.Template.FindName("PART_ConnectorDecorator",designerItem) as Control;
        connectorDecorator.ApplyTemplate();

        return connectorDecorator.Template.FindName(connectorName,connectorDecorator) as Connector;
    }

    private bool BelongToSameGroup(IGroupable item1,IGroupable item2)
    {
        IGroupable root1 = SelectionService.GetGroupRoot(item1);
        IGroupable root2 = SelectionService.GetGroupRoot(item2);

        return (root1.ID == root2.ID);
    }

    #endregion
}
 }

请问是否有人可以帮助解决该问题?

非常感谢!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-