Here is what was promised.
As I explain in my comment, a Control
has hundreds of properties, some specific to the type of Control
, others inherited from the base class Control
, others inherited from object
... Serialize all these data is complicated and Json.Net is not able to do it. On the other hand, it does not make much sense to serialize much of that data.
I'll add a solution below. It is possible that it could be improved, and you can definitely modify it to add other properties that you need to store, but I think it can help you.
First we start by creating the class that is really going to be serialized:
public class ControlSerializado
{
public Type Tipo { get; set; }
public string Texto { get; set; }
public Point Posicion { get; set; }
public Size Tamano { get; set; }
public string Nombre { get; set; }
public string Padre { get; set; }
public List<ControlSerializado> Controles { get; set; }
}
As you see, I add the properties that I want to store. You probably want to add others, such as the background color etc ... That's up to your choice.
Now we create the method that will recursively go through all the control controls that are passed to it:
public ControlSerializado Serializar(Control control)
{
ControlSerializado cs = new ControlSerializado();
cs.Nombre = control.Name;
cs.Tipo = control.GetType();
cs.Texto = control.Text;
cs.Posicion = control.Location;
cs.Tamano = control.Size;
cs.Padre = control.Parent.Name;
cs.Controles = new List<ControlSerializado>();
foreach (var cont in control.Controls.Cast<Control>())
{
cs.Controles.Add(Serializar(cont));
}
return cs;
}
As you see, he is creating ControlSerializado
objects mapping the properties of the control to the custom class, and then recursively doing the same with the children controls.
An example of how it would be used:
//Creamos un user control de prueba
UserControl UC = new UserControl();
UC.Name = "UC1";
Panel p = new Panel();
p.Size = new Size(400, 400);
p.Location = new Point(0, 0);
p.Name = "Panel1";
Label lb1 = new Label();
lb1.Text = "Prueba";
lb1.Location = new Point(10, 10);
lb1.Name = "label1";
p.Controls.Add(lb1);
UC.Controls.Add(p);
this.Controls.Add(UC);
//Creamos nuestro ControlSerializado y llamamos a SerializeObject
var controlSerializado = Serializar(UC);
var serializado = JsonConvert.SerializeObject(controlSerializado);
In serializado
we already have control with all your serialized children to be able to save them in a file for example.
Now we are going to recover the data. We create a method that is reading the recovered Personalized Control and adding it to their respective parents:
private void MostrarControl(ControlSerializado control,Control padre)
{
//Buscamos el control Padre del que vamos a mostrar
var controlPadre = (padre.Name == control.Padre) ? padre : padre.Controls.OfType<Control>().Where(x => x.Name == control.Padre).FirstOrDefault();
//creamos el control
var c = (Control)Activator.CreateInstance(control.Tipo);
c.Name = control.Nombre;
c.Text = control.Texto;
c.Location = control.Posicion;
c.Size = control.Tamano;
controlPadre.Controls.Add(c);
foreach(var hijo in control.Controles)
{
MostrarControl(hijo,c);
}
}
And finally, an example of use:
var deserializado = JsonConvert.DeserializeObject<ControlSerializado>(serializado);
MostrarControl(deserializado,this);
I hope you have been clear, I could extend a little more in the explanations but I think the answer has been a bit extensive, if you have any questions you comment.