У меня возникают проблемы при десериализации/загрузке элементов управления в среду выполнения.
Кажется, что все методы, которые я пробовал, имеют тот или иной тип проблемы.
Проблема, например:
- Элементы управления по-прежнему привязаны к времени разработки.
- Не все свойства десериализуются со всеми свойствами, а именно с вложенными свойствами.
- Похоже, что ассоциации элементов управления соблюдаются, т.е. Кнопка на панели больше не будет на панели, даже если свойство по-прежнему является родительским после загрузки.
Есть основные фрагменты кода:
Сериализация из времени разработки
Код: Выделить всё
private void LoadRuntime(int type)
{
var controls = surface.ComponentContainer.Components;
SerializationStore data = (SerializationStore)surface.
_designerSerializationService.Serialize(controls);
MemoryStream ms = new MemoryStream();
data.Save(ms);
SaveData.Data = ms.ToArray();
SaveData.LoadType = type;
new RuntimeForm().Show();
}
public object Serialize(System.Collections.ICollection objects)
{
ComponentSerializationService componentSerializationService =
_serviceProvider.GetService(typeof(ComponentSerializationService)) as
ComponentSerializationService;
SerializationStore returnObject = null;
using (SerializationStore serializationStore =
componentSerializationService.CreateStore())
{
foreach (object obj in objects)
{
if (obj is Control control)
{
componentSerializationService.SerializeAbsolute(serializationStore, obj);
}
returnObject = serializationStore;
}
}
return returnObject;
}
Вот попытка с отражением:
Код: Выделить всё
MemoryStream ms = new MemoryStream(SaveData.Data);
Designer d = new Designer();
var controls = d._designerSerializationService.Deserialize(ms);
ms.Close();
if (SaveData.LoadType == 1)
{
foreach (Control cont in controls)
{
var ts = Assembly.Load(cont.GetType().Assembly.FullName);
var o = ts.GetType(cont.GetType().FullName);
Control controlform = (Control)Activator.CreateInstance(o);
PropertyInfo[] controlProperties = cont.GetType().GetProperties();
foreach (PropertyInfo propInfo in controlProperties)
{
if (propInfo.CanWrite)
{
if (propInfo.Name != "Site" && propInfo.Name != WindowTarget")
{
try
{
var obj = propInfo.GetValue(cont, null);
propInfo.SetValue(controlform, obj, null);
}
catch { }
}
else { }
}
}
Controls.Add(controlform);
}
}
Код: Выделить всё
MemoryStream ms = new MemoryStream(SaveData.Data);
Designer d = new Designer();
var controls = d._designerSerializationService.Deserialize(ms);
foreach (Control cont in controls)
Controls.Add(cont);
Я также не считаю необходимым писать собственный сериализатор для каждого элемента управления, поскольку он наверняка уже есть. Visual Studio способна сериализовать все свои свойства по мере их изменения в PropertyGrid и загружать их обратно при запуске программы.
Мне бы хотелось сериализовать конструктор в файл .cs, но как? Как сериализовать элементы управления/форму и изменить свойства в файл, такой как дизайнер VS, я пытался и искал только xml и двоичный сериализатор. Моим идеальным решением было бы создать файл Designer.cs с помощью CodeDom.
Как правильно выполнить эту сериализацию между временем разработки и временем выполнения?
Подробнее здесь: https://stackoverflow.com/questions/595 ... erate-c-sh
Мобильная версия