This is a migrated thread and some comments may be shown as answers.

Serialize properties of child controls of LayoutControl

3 Answers 165 Views
LayoutControl
This is a migrated thread and some comments may be shown as answers.
Simeon
Top achievements
Rank 1
Iron
Simeon asked on 12 Aug 2019, 09:38 AM

I just saw and testing the new layout control and it is wonderful.

I am wondering is there a way to save properties like width, height, text, etc... of the embeded controls along with SaveLayout of the layout control.

It would be great functionality.

 

Regards,

Simeon

 

 

3 Answers, 1 is accepted

Sort by
0
Simeon
Top achievements
Rank 1
Iron
answered on 13 Aug 2019, 09:52 AM

I worte my own solution via overriding SaveLayout and LoadLayout methods.

I'm using Telerik ControlXmlSerializer class to store xml string with control properties on Tag property of each LayoutControlItem.

In addition i'm checking image property and if image exists i'm writing it with base64 encoded text on additional xml element.

The code is not best but works for now and will appreciate any optimization.

I hope it helps someone.

public override void SaveLayout(Stream stream)
       {
           foreach (Telerik.WinControls.UI.LayoutControlItem myItem in this.Items)
           {
 
               ControlXmlSerializer ser = new ControlXmlSerializer();
               System.IO.Stream myStream1 = new System.IO.MemoryStream();
               XmlTextWriter writer = new XmlTextWriter(myStream1, Encoding.UTF8);
               writer.Formatting = Formatting.None;
               writer.WriteStartDocument();
               writer.WriteStartElement("ROOT");
               writer.WriteStartElement("RadUserControl");
               ser.WriteObjectElement(writer, myItem.AssociatedControl);
               writer.WriteEndElement();
               var myControl = myItem.AssociatedControl;
               if (myControl.GetType().GetProperty("Image") != null
              && myControl.GetType().GetProperty("Image").GetValue(myControl) != null
            && myControl.GetType().GetProperty("Image").GetValue(myControl).ToString() != "")
               {
                   writer.WriteStartElement("Base64Image");
                   byte[] myByteArray =  App.ImageToByteArray((Image)myControl.GetType().GetProperty("Image").GetValue(myControl));
                   writer.WriteBase64(myByteArray, 0, myByteArray.Length);
                   writer.WriteEndElement();
               }
               writer.WriteEndElement();
               writer.WriteEndDocument();
               writer.Flush();
               myItem.Tag = App.StreamToString(myStream1);
               writer.Close();
               myStream1.Close();
           }
           base.SaveLayout(stream);
       }
 
       public override void LoadLayout(Stream stream)
       {
           base.LoadLayout(stream);
           foreach (Telerik.WinControls.UI.LayoutControlItem myItem in this.Items)
           {
               if (myItem.Tag != null && myItem.Tag.ToString() != "")
               {
                   System.IO.Stream sr = new MemoryStream();
                   sr = App.StringToStream(myItem.Tag.ToString());
                   using (XmlTextReader textReader = new XmlTextReader(sr))
                   {
                       ControlXmlSerializer ser = new ControlXmlSerializer();
                       textReader.Read();
                       textReader.ReadStartElement("ROOT");
                       ser.ReadObjectElement(textReader, myItem.AssociatedControl);
                       textReader.Read();
                       if (textReader.NodeType.ToString() == "Element" && textReader.Name == "Base64Image")
                       {
                           MemoryStream ms = null;
                           byte[] buffer = new byte[256];
                           int bytesRead;
                           while ((bytesRead = textReader.ReadElementContentAsBase64(
                               buffer, 0, buffer.Length)) > 0)
                           {
                               if (ms == null) ms = new MemoryStream(bytesRead);
                               ms.Write(buffer, 0, bytesRead);
                           }
                           if (ms != null)
                           {
                               Image image = Image.FromStream(ms, true);
                               myItem.AssociatedControl.GetType().GetProperty("Image").SetValue(myItem.AssociatedControl, image);
                           };
                       }
                   }
 
               }
           }
 
       }

 

0
Accepted
Dess | Tech Support Engineer, Principal
Telerik team
answered on 13 Aug 2019, 10:07 AM
Hello, Simeon, 

The SaveLayout method that RadLayoutControl offers, preserves the current state of RadLayoutControl to an XML file. Hence, you can restore it later. It is not purposed to store any controls that are added to RadLayoutControl.

All controls that are added to RadLayoutControl at design time are stored in the Designer.cs file. This ensures that when you run the project and show the form, these controls will be loaded and shown as well. There is no automatic mechanism for storing the controls that are added to RadLayoutControl. You need to implement such a custom functionality according to your custom requirements. You can iterate the controls you have and produce a custom XML file with the internal structure that you will store the information for restoring the controls back on the form when running the application.

After some research in general programming forums, I have found the following threads which may be useful for serializing dynamics controls on the form:
https://stackoverflow.com/questions/32187309/saving-dynamically-added-c-sharp-winforms-controls
https://social.msdn.microsoft.com/Forums/windows/en-US/a42a54b0-f308-465f-9b4e-8dd09c600569/how-to-make-dynamic-button-permament-to-form-though-application-restarts-in-vbnet?forum=winforms 

Note that the SaveLayout and LoadLayout method can be overridden. Thus, if you need to extend the default logic, you can create a derivative of RadLayoutControl and override the basic logic. Internally, both methods use a LayoutControlXmlSerializer which is a ComponentXmlSerializer inheritor. You can also download the source code from your account and investigate the default logic for storing/restoring the layout. Then, you can plug your custom logic into the process for storing/restoring the layout.

I hope this information helps. If you need any further assistance please don't hesitate to contact me. 

Regards,
Dess | Tech Support Engineer, Sr.
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Simeon
Top achievements
Rank 1
Iron
answered on 13 Aug 2019, 11:09 AM

Thank you, Dess!

You are very accurate and comprehensive as usual.

Regards,

 

Tags
LayoutControl
Asked by
Simeon
Top achievements
Rank 1
Iron
Answers by
Simeon
Top achievements
Rank 1
Iron
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or