Не могу выполнить функцию вставки в C # WPF, используя метод десериализации - PullRequest
0 голосов
/ 11 марта 2019

Итак, я сейчас работаю над аналогичным приложением "Paint" и хочу скопировать выбранный элемент и выполнить для него функции "копировать" и "Вставить", но, похоже, у меня возникли некоторые проблемы. Я использую метод Serialize и Deserialize для работы над ним. Ниже показаны некоторые коды клавиш:

Ниже приведен метод сериализации:

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;

Я понимаю, что ошибка связана с тем, что ссылка на объект не установлена ​​для экземпляра объекта. Таким образом, после сильно измененного проектирования, я заметил, что «Ссылка на объект» означала «Содержание». Вот мой вопрос. Когда я вернулся к методу сериализации:

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

"Сохранить (this.Content)" <- считать пустым? Когда я запускаю весь проект, никаких ошибок не возникало, пока я не нажал на кнопку «Вставить». Глубоко признателен, если есть кто-нибудь, кто может помочь моей путанице. Спасибо. </p>

1 Ответ

0 голосов
/ 11 марта 2019

Ладно, вот я и обнаружил свои ошибки.Поскольку в моем методе десериализации требуется вызвать "serial. Element (" Content ")".

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

В методе Serialize часть Content должна быть XElement, а не XAttribute .Таким образом, измените эту строку:

new XAttribute("Content", savedItem);

на эту строку:

new XElement("Content", savedItem);

Кроме того , для «Содержательной части» в методе десериализации:

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

С этими основными изменениями я смог выполнить функцию копирования и вставки для выбранных элементов.

...