无法使用反序列化方法在 C# WPF 中执行粘贴功能

Cant perform Paste function in C# WPF using Deserialize method

所以我目前正在开发一个 "Paint" 类似的应用程序,我想复制一个选定的项目并对其执行 "copy" 和 "Paste" 功能,但我似乎有有些麻烦。我正在使用序列化和反序列化方法来处理它。部分关键代码如下:

下面是序列化方法:

public XElement Serialize()
    {
        RotateTransform contentRotate = this.RenderTransform as RotateTransform;
        double rotateAngle = 0;

        string savedItem = XamlWriter.Save(this.Content); //Null?

        if (contentRotate != null)
        {
            rotateAngle = contentRotate.Angle;
        }

        XElement serial = new XElement("DesignerItem",
                          new XAttribute("Width", this.Width),
                          new XAttribute("Height", this.Height),
                          new XAttribute("Name", this.Name),
                          new XAttribute("RotateAngle", rotateAngle),
                          new XAttribute("Left", Canvas.GetLeft(this)),
                          new XAttribute("Top", Canvas.GetTop(this)),
                          new XAttribute("Offset", 0),
                          new XAttribute("Content", savedItem));
        return serial;
    }//End of Serialize

反序列化方法如下:

public static DesignerItem Deserialize(XElement serial)
    {
        DesignerItem item = new DesignerItem();

        item.Width = Double.Parse(serial.Attribute("Width").Value);
        item.Height = Double.Parse(serial.Attribute("Width").Value);
        item.Name = serial.Attribute("Name").Value;
        Canvas.SetLeft(item, Double.Parse(serial.Attribute("Left").Value) + Double.Parse(serial.Attribute("Offset").Value));
        Canvas.SetTop(item, Double.Parse(serial.Attribute("Top").Value) + Double.Parse(serial.Attribute("Offset").Value));
        /*This part is for the "Content"*/
        var value = serial.Element("Content").Value; //NullReferenceException Occurred
        StringReader stringReader = new StringReader(value);
        XmlReader xmlReader = XmlReader.Create(stringReader);
        ContentElement readerLoad = (ContentElement)XamlReader.Load(xmlReader);
        item.Content = readerLoad;

        item.RenderTransformOrigin = new Point(0.5, 0.5);
        item.RenderTransform = new RotateTransform(Double.Parse(serial.Attribute("RotateAngle").Value));

        return item;
    }//End of Deserialize

以下为 CopySelection 方法:

private void copySelection()
    { 
        XElement serial = this.SelectedItem.Serialize();
        serial.SetAttributeValue("OffSet", 15);
        Clipboard.SetData(DataFormats.Xaml, serial);
    }//End of copySelection

粘贴命令如下:

private void Paste_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        if (Clipboard.ContainsData(DataFormats.Xaml))
        {
            string clipboardData = Clipboard.GetData(DataFormats.Xaml) as string;

            if (clipboardData != null && clipboardData != string.Empty)
            {
                this.CreateRestorePoint();

                XElement serial = XElement.Load(new StringReader(clipboardData));
                DesignerItem item = DesignerItem.Deserialize(serial);
                this.Children.Add(item);
                this.SelectedItem = item;
            }
        }
    }

    private void Paste_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = Clipboard.ContainsData(DataFormats.Xaml);
    }

反序列化方法出现 NullReferenceException 错误:

var value = serial.Element("Content").Value;

我知道错误是由于未将对象引用设置为对象的实例。因此,经过多次逆向工程后,我注意到 "Object Reference" 的意思是 "Content"。 所以,这是我的问题。当我回溯到 Serialize 方法时:

string savedItem = XamlWriter.Save(this.Content);

"Save(this.Content)" <-- 是否考虑为空? 当我 运行 它整个项目没有错误发生,直到我点击我的 "Paste" 按钮的那一刻。如果有人可以解决我的困惑,我将不胜感激。谢谢。

好的,所以我发现了我的错误。 因为在我的反序列化方法中想要调用 "serial.Element("Content")".

var value = serial.Element("Content").Value;

在序列化方法中,内容部分应该是 XElement,而不是 XAttribute。 因此,更改此行:

new XAttribute("Content", savedItem);

到这一行:

new XElement("Content", savedItem);

此外,对于反序列化方法中的"Content part":

var value = serial.Element("Content").Value; //NullReferenceException Occurred
StringReader stringReader = new StringReader(value);
XmlReader xmlReader = XmlReader.Create(stringReader);
ContentElement readerLoad = (ContentElement)XamlReader.Load(xmlReader);
item.Content = readerLoad;

ContentElement 在这里不再扮演角色。所以可以把这部分改成这一行代码:

item.Content = XamlReader.Load(XmlReader.Create(new StringReader(serial.Element("Content").Value)));

通过这些重大更改,我可以对所选项目执行复制和粘贴功能。