无法通过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
}
 }

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

非常感谢!

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

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/1680012.html

大家都在问