动态保存和存储面板的内容
本文关键字:保存 存储 动态 | 更新日期: 2023-09-27 18:21:39
我有一个程序,用户可以在其中创建文本框,并将图像拖放到windows窗体中的面板中,在这里用户可以移动图像、调整图像大小、删除图像等。基本上是一个非常简单的图像编辑器。
我想做的是让这项工作像一个非常简单的PowerPoint程序。
我正在尝试确定用户是否可以保存包含这些图像(在图片框中)和文本框的面板的内容。然后清除面板,从新的图像和文本开始,但如果他们愿意,可以返回到上一个面板进行编辑。
所以程序中的每个面板基本上都是PowerPoint中的一张幻灯片。
目前,我可以将面板保存为Jpeg,并存储这些内容,但这样我就不能像重新加载面板一样编辑内容。
我希望我已经在某种程度上解释了这种情况。
有可能做我正在尝试的事情吗?或者我应该以不同的方式处理这个问题吗?
实现这一点的方法是定义一个类,该类存储构成幻灯片的所有信息(因此,可以在代码中表示幻灯片),然后将幻灯片列表(称为Presentation)序列化为XML文件。
每张幻灯片都有不同数量的控件,可以是图像、文本框等,所以让我们先定义一个控件:
public class MySlideClass
{
public class Control
{
public Point Position { get; set; }
public Size Size { get; set; }
public Color Background { get; set; }
public Color Forground { get; set; }
public Image Picture { get; set; }
public string Text { get; set; }
public float TextSize { get; set; }
public Point TextPosition { get; set; }
// ...
public float Transparency { get; set; }
public bool Visible { get; set; }
public Control()
{
}
}
public class Slide
{
[XmlAttribute]
public string Name { get; set; }
//
public string Title { get; set; }
public Size Size { get; set; }
public Color Background { get; set; }
public Color Forground { get; set; }
public float Transparency { get; set; }
public bool Visible { get; set; }
public List<Control> Children { get; set; }
public Slide()
{
}
}
public MySlideClass()
{
}
}
显然,您可以根据需要添加/删除属性。
注意{ get; set; }
和空的默认构造函数。您的类必须由公共属性(使用get/set定义的变量)组成,并且具有XMLSerializer
的空默认构造函数才能序列化您的类(您仍然可以指定其他不为空的构造函数)。
你可以这样使用类:
public void SaveSlideTest()
{
// New control
MySlideClass.Control newControl = new MySlideClass.Control();
newControl.Position = new Point(20,30);
newControl.Size = new Size(75,25);
newControl.Text = "Image1";
newControl.TextPosition= new Point(0,25);
//ctl.Picture = new Bitmap("image1.bmp");
// Add control to children list
List<MySlideClass.Control> childrenControls = new List<MySlideClass.Control>();
childrenControls.Add(newControl);
// New slide
MySlideClass.Slide newSlide = new MySlideClass.Slide();
newSlide.Name = "Slide1";
newSlide.Title = "New Slide";
newSlide.Size = new Size(200,100);
// Add child controls to slide
newSlide.Children = childrenControls;
// Add slide to presentation or 'slideshow'
List<MySlideClass.Slide> mySlidePresentation = new List<MySlideClass.Slide>();
mySlidePresentation.Add( newSlide );
// Save presentation to XML
SerializeObject("SavedSlidePresentation.xml",mySlidePresentation);
}
您的SavedSlidePresentation.xml看起来像:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfSlide xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Slide Name="Slide1">
<Title>New Slide</Title>
<Size>
<Width>200</Width>
<Height>100</Height>
</Size>
<Background />
<Forground />
<Transparency>0</Transparency>
<Visible>false</Visible>
<Children>
<Control>
<Position>
<X>20</X>
<Y>30</Y>
</Position>
<Size>
<Width>75</Width>
<Height>25</Height>
</Size>
<Background />
<Forground />
<Text>Image1</Text>
<TextSize>0</TextSize>
<TextPosition>
<X>0</X>
<Y>25</Y>
</TextPosition>
<Transparency>0</Transparency>
<Visible>false</Visible>
</Control>
</Children>
</Slide>
</ArrayOfSlide>
以下是序列化/反序列化函数:
public static List<MySlideClass.Slide> DeserializePresentation(string FileName)
{
List<MySlideClass.Slide> returnList = new List<MySlideClass.Slide>();
using(StreamReader streamReader = new StreamReader(FileName))
{
XmlSerializer xmlReader = new XmlSerializer(typeof(List<MySlideClass.Slide>));
returnList = (List<MySlideClass.Slide>) xmlReader.Deserialize(streamReader);
}
return returnList;
}
// A generic object serializer
public static void SerializeObject(string Filename,object Obj)
{
using(StreamWriter streamWriter = new StreamWriter(Filename))
{
XmlSerializer xmlSerializer = new XmlSerializer(Obj.GetType());
xmlSerializer.Serialize(streamWriter,Obj);
}
}
这应该比Dictionary<TKey,TValue>
更健壮。
需要注意的一个重要方面是:如果决定将属性添加到Slide或Control类,则反序列化程序将无法使用旧版本的数据类反序列化XML文件。
在这种情况下,您可以1)手动或以其他方式转换旧版本的XML文件,或者2)在类中实现ISerializable
接口(建议)。
我以前做过一个类似的项目,我创建了两个字典来保存的所有数据
// Dictionary which Holds all the Info for the shapes in a Particular Slide
Dictionary<Int32, ShapeInfo> slideInfoDict = new Dictionary<Int32, ShapeInfo>();
// Dictionary which Holds all the Info for the all the shapes in the all the slides
Dictionary<Int32, SlideInfo> appInfoDict = new Dictionary<Int32, SlideInfo>();
我的"ShapeInfo"类有关于各种形状(表格、矩形、图像等)的所有信息此shapeInfoDict的键(Int32)是选定的形状。
类"幻灯片信息"保存有关该特定幻灯片的所有信息。此幻灯片的键(Int32)InfoDict已选择幻灯片。
希望能有所帮助。