您好我有一个自定义的genric表单,自定义类型和UITypeEditor以及它的表单。
我可以在设计时设置和编辑自定义类型的列表。我的问题是。设置后,它没有序列化到designer.cs文件。
我在这里错过了什么吗?MyCustomForm:
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;
}
}
TypeEditor
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?
答案 0 :(得分:0)
要使用自定义编辑器对BindingList<MySampleModel>
进行编辑,您需要应用以下更改:
1)该属性应由CollectionConverter
public partial class MyBaseForm<T> : Form
{
public MyBaseForm()
{
InitializeComponent();
}
BindingList<MySampleModel> someProperty = new BindingList<MySampleModel>();
[Editor(typeof(MyUITypeEditor), typeof(UITypeEditor))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[TypeConverter(typeof(CollectionConverter))]
public BindingList<MySampleModel> SomeProperty
{
get { return someProperty; }
set { someProperty = value; }
}
[Browsable(false)]
public Type MyGenericType { get { return typeof(MySampleModel); } }
}
然后是DerivedForm
:
public partial class MyDerivedForm : MyBaseForm<MySampleModel>
{
public MyDerivedForm()
{
InitializeComponent();
}
}
注意:您不需要将YourModel
标记为Serializer
。您的模型将以这种方式序列化:
MCVE.MySampleModel mySampleModel1 = new MCVE.MySampleModel();
MCVE.MySampleModel mySampleModel2 = new MCVE.MySampleModel();
...
...
mySampleModel1.Id = 1;
mySampleModel1.Name = "X";
mySampleModel1.Price = 100;
mySampleModel2.Id = 2;
mySampleModel2.Name = "Y";
mySampleModel2.Price = 200;
this.SomeProperty.Add(mySampleModel1);
this.SomeProperty.Add(mySampleModel2);
...
...
2)在MyEditorForm
中,您应该在编辑后返回BindingList
的新实例,以使设计器序列化列表:
public partial class MyEditorForm<T> : Form
{
public MyEditorForm()
{
InitializeComponent();
this.StartPosition = FormStartPosition.CenterScreen;
}
public BindingList<T> List
{
get
{
return (BindingList<T>)dataGridView1.DataSource;
}
set
{
if (value == null)
value = new BindingList<T>();
dataGridView1.DataSource = new BindingList<T>(value);
}
}
private void button1_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
}
}
3)在您的UITypeEditor
中,您应该在对话框关闭后返回值:
public override object EditValue(ITypeDescriptorContext context,
IServiceProvider provider, object value)
{
var svc = provider.GetService(typeof(IWindowsFormsEditorService))
as IWindowsFormsEditorService;
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(genericArguments);
if (svc != null) {
using (var f = (Form)Activator.CreateInstance(editorFormInstance)) {
f.GetType().GetProperty("List").SetValue(f, value);
if (svc.ShowDialog(f) == DialogResult.OK)
return ((dynamic)f).List;
}
}
else {
using (var f = (Form)Activator.CreateInstance(editorFormInstance)) {
f.GetType().GetProperty("List").SetValue(f, value);
if (f.ShowDialog() == DialogResult.OK)
return ((dynamic)f).List;
}
}
return base.EditValue(context, provider, value);
}