序列化和反序列化多个自定义用户控件到画布与WPF?

xghobddn  于 2023-10-22  发布在  其他
关注(0)|答案(1)|浏览(98)

如标题所述,我试图在WPF中序列化和反序列化画布的内容。我一直使用this link作为我的指南。在这种情况下,画布的内容是由用户添加的自定义用户控件。在我的程序中,这些是蓝色的圆圈和红色的方块(用于简单和易于解释)。
目前,我可以保存和加载文件,但是,当加载保存的文件时,会出现一些问题。
1.程序只创建红色方块。
1.创建的红色方块与保存文件时的位置不同。它们都在画布的0,0位置生成。
程序确实创建了正确数量的形状。然而,非常无益的是,我不确定序列化,反序列化或两者都是程序失败的地方。
为了帮助理解,下面是存储形状的类,准备进行序列化:

[Serializable()]
public class shaypeh
{
    private double x, y;
    private bool circleOrSquare; 

    public shaypeh()
    {

    }

    public shaypeh(double x, double y, bool circleOrSquare)
    {
        this.x = x;
        this.y = y;
        this.circleOrSquare = circleOrSquare;
    }

    public bool getCircleOrSquare()
    {
        return circleOrSquare;
    }

    public double getX()
    {
        return x;
    }

    public double getY()
    {
        return y;
    }
}

下面的代码是我用来保存画布的函数。我怀疑这是程序的问题,但是我不确定我错在哪里。
下面是将2个圆和1个正方形添加到画布并保存时的输出。

<?xml version="1.0"?>
<ArrayOfShaypeh xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <shaypeh />
  <shaypeh />
  <shaypeh />
</ArrayOfShaypeh>
double top;
double left;
List<shaypeh> shaypehs = new List<shaypeh>();
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Text file (*.txt)|*.txt|XML (*.xml)|*.xml";
if (sfd.ShowDialog() != true)
{
    return; 
}

foreach(object obj in pictureBoard.Children)
{
    if (obj is Circle)
    {
        UIElement s = (Circle)obj;
        top = Canvas.GetTop(s); 
        left = Canvas.GetLeft(s);
        shaypehs.Add(new shaypeh(left, top, true));
    }
    if (obj is Rectangle)
    {
         UIElement s = (Rectangle)obj;
         top = Canvas.GetTop(s);
         left = Canvas.GetLeft(s);
         shaypehs.Add(new shaypeh(left, top, true));
     }
}
XmlSerializer serializer = new XmlSerializer(typeof(List<shaypeh>));
using (FileStream stream = File.Create(sfd.FileName))
{
    serializer.Serialize(stream, shaypehs);
}

下面的代码是我用来反序列化文件的代码。我相信这是正确的,但我不确定。

OpenFileDialog ofd = new OpenFileDialog();
ofd.DefaultExt = ".xml"; 
ofd.Filter = "Text file (*.txt)|*.txt|XML (*.xml)|*.xml";
if (ofd.ShowDialog()!= true)
{
    return; 
}

pictureBoard.Children.Clear();
XmlSerializer serializer = new XmlSerializer (typeof(List<shaypeh>));
using (FileStream stream = File.Open(ofd.FileName, FileMode.Open))
{
    List<shaypeh> shaypehs = (List<shaypeh>)serializer.Deserialize(stream);
    foreach(shaypeh shape in shaypehs)
    {
        if (shape.getCircleOrSquare() == true)
        {
            Circle c = new Circle();
            Canvas.SetTop(c, shape.getY());
            Canvas.SetLeft(c, shape.getX());
            c.PreviewMouseDown += c_PreviewMouseDown; 
            pictureBoard.Children.Add(c);
        }
        if (shape.getCircleOrSquare() == false)
        {
            Rectangle r = new Rectangle();
            Canvas.SetTop(r, shape.getY());
            Canvas.SetLeft(r, shape.getX());
            r.PreviewMouseDown += c_PreviewMouseDown;
            pictureBoard.Children.Add(r);
         }
    }
}

任何帮助/建议将不胜感激。

vfh0ocws

vfh0ocws1#

XmlSerializer忽略私有成员。
您应该将shaypeh实现为C#类型,即将get*方法替换为属性,并更改名称以符合common coding conventions

[Serializable]
public class Shaypeh
{
    public Shaypeh()
    {

    }

    public Shaypeh(double x, double y, bool circleOrSquare)
    {
        this.X = x;
        this.Y = y;
        this.CircleOrSquare = circleOrSquare;
    }

    public bool CircleOrSquare { get; set; }

    public double X { get; set; }

    public double Y { get; set; }
}

使用上面的Shaypeh实现,您的序列化代码应该可以工作。

相关问题