【发布时间】:2017-11-10 14:05:43
【问题描述】:
您好,我有一个自定义通用表单、自定义类型和一个 UITypeEditor,其中包含它的表单。
我可以在设计时设置和编辑我的自定义类型列表。我的问题是。设置后,不会序列化到designer.cs文件。
我在这里遗漏了什么吗?
我的自定义表单:
public partial class MyBrowseForm<TParentEntity> : Form where TParentEntity:class
{
private BindingList<MyBindingFields> _myBindingFieldsCollection = new BindingList<MyBindingFields>();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Editor(typeof(BdFormTypeEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(ExpandableObjectConverter))]
public BindingList<MyBindingFields> MyBindingFieldsCollection
{
get => _myBindingFieldsCollection;
set => _myBindingFieldsCollection = value;
}
}
类型编辑器
class BdFormTypeEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
var svc = provider.GetService(typeof(IWindowsFormsEditorService))
as IWindowsFormsEditorService;
BindingList<MyBindingFields> bindingFieldsList = context.Instance.GetPropValue("MyBindingFieldsCollection") as BindingList<MyBindingFields>;
var myGenericTypeProperty = context?.Instance.GetType()
.GetProperty("MyGenericType");
var genericArgument = (Type)myGenericTypeProperty.GetValue(context.Instance);
var editorFormType = typeof(MyEditorForm<>);
var genericArguments = new[] { genericArgument };
var editorFormInstance = editorFormType.MakeGenericType(genericType);
if (svc != null)
{
using (var f = (Form) Activator.CreateInstance(editorFormInstance))
{
((dynamic) f).MyBindingFieldsList = bindingFieldsList;
f.ShowDialog();
context.Instance.GetType().GetProperty("MyBindingFieldsCollection")?.SetValue(context.Instance, ((dynamic)f).MyBindingFieldsList);
}
}
else
{
using (var f = (Form)Activator.CreateInstance(editorFormInstance))
{
((dynamic)f).MyBindingFieldsList = bindingFieldsList;
f.ShowDialog();
context.Instance.GetType().GetProperty("MyBindingFieldsCollection")?.SetValue(context.Instance, ((dynamic)f).MyBindingFieldsList);
}
}
return value;
}
}
MyBindingFields 类:
public class MyBindingFields
{
private ControlTypes _ControlType;
public ControlTypes ControlType
{
get => _ControlType;
set => _ControlType = value;
}
//public string MyParentEntity { get; set; }
public string BindingField { get; set; }
public string ChildEntity { get; set; }
public string ValueMember { get; set; }
public string DisplayMember { get; set; }
}
所以在我设置值并按保存之后会发生什么。 这些值存储在,当我单击以再次打开此窗口时。我有我以前的记录,如果我添加新记录也很好。这里的问题是由于这个原因数据没有序列化到designer.cs文件。当我运行程序或清理并重建解决方案时,我会丢失这些数据。 我在这里想念什么?我该怎么做才能在按下保存按钮时将数据序列化到designer.cs?
【问题讨论】:
-
数据只有通过公共属性公开且类型具有 [Serializable] 属性时才能序列化为 InitializeComponent()。不要过度这样做,这是非常危险的。设计时的异常,比如你在改变类型时会得到的那种,会导致非常讨厌的问题。 InitializeComponent() 不是一个很好的数据库。
-
我在这里只存储字符串值。即使我将可序列化属性放在 MyBindingFields 类的顶部,它仍然无法完成这项工作。那么有什么建议吗?
-
这里,问题不是
Serializable属性。事实上,您不需要将模型标记为可序列化。相反,您应该使用CollectionConverter作为属性的类型转换器。目前在您的代码中,编辑器也不会返回编辑后的值。您应该在ShowDialog之后返回从对话框中获得的值。您需要应用一些更改才能使代码正常工作。
标签: c# winforms generics windows-forms-designer uitypeeditor