Итак, я сейчас работаю над аналогичным приложением "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>