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
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);
};
}
}
}
}
}
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
Thank you, Dess!
You are very accurate and comprehensive as usual.
Regards,