的自定义TypeConverter在WinForms设计器中生成AddRange(),但该转换器不起作用



根据问题:让设计器为UserControl 的简单List属性生成AddRange

以下TypeConverter不生成AddRange((。而我看到一些控件以相同的代码方式生成它。

Form1.designer.cs

// userControl11
// 
this.userControl11.BackColor = System.Drawing.Color.Red;
this.userControl11.Fruits.Add(new WindowsFormsApp2.Fruit(false, null));
this.userControl11.Fruits.Add(new WindowsFormsApp2.Fruit(false, null));
this.userControl11.Fruits.Add(new WindowsFormsApp2.Fruit(false, null));
this.userControl11.Fruits.Add(new WindowsFormsApp2.Fruit(false, null));
this.userControl11.Fruits.Add(new WindowsFormsApp2.Fruit(false, null));
this.userControl11.Fruits.Add(new WindowsFormsApp2.Fruit(false, null));
this.userControl11.Fruits.Add(new WindowsFormsApp2.Fruit(false, null));
this.userControl11.Location = new System.Drawing.Point(278, 224);
this.userControl11.Name = "userControl11";

应该是

this.userControl1.Fruits.AddRange(new Fruite[]{new Fruit(X, Y), new Fruit(X, Y), etc})

虽然我看到标准控件也一样,但它生成得很好:

// listBox1
// 
this.listBox1.FormattingEnabled = true;
this.listBox1.Items.AddRange(new object[] {   // WORKS in standard controls...
"123",
"123",
"123"});

我的代码:

[TypeConverter(typeof(FruitConverter))]
public class Fruit
{
public Fruit() { }
public Fruit(bool edible, string name) : this()
{
Edible = edible;
Name = name;
}
public bool Edible { get; set; }
public string Name { get; set; }
}
public class FruitConverter : ExpandableObjectConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor)) return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor) && (value is Fruit pi))
{
ConstructorInfo ctor = typeof(Fruit).GetConstructor(new Type[] { typeof(bool), typeof(string) });
object[] pars = new object[] { pi.Edible, pi.Name };
return new InstanceDescriptor(ctor, pars);
}
return base.ConvertTo(context, culture, value, destinationType);
}
}

UserControl中的测试

public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}

private Collection<Fruit> fruits = new Collection<Fruit>();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Collection<Fruit> Fruits => fruits;
}

我现在该怎么办?

这真的太难了。但下面的文章解释了一些:https://www.codeproject.com/Articles/5372/How-to-Edit-and-Persist-Collections-with-Collectio

第三,集合类必须实现以下方法:Add和AddRange。尽管IList接口具有添加成员并且CollectionBase实现IList,则仍然需要在给定CollectionBase的情况下,为集合实现Add方法声明IList的Add成员的显式成员实现。设计器根据您的方法序列化集合已经实施。如果同时实现了这两种方法,则AddRange为首选。

使用Add方法进行序列化时,它会为每个项使用一个新行

this.tc.SimpleItems.Add(new Test.Items.SimpleItem_FullTc(-1, "Item1"));
this.tc.SimpleItems.Add(new Test.Items.SimpleItem_FullTc(-1, "Item2"));`

当设计器使用AddRange方法时,所有项都会添加到一行中。

this.tc.SimpleItems.AddRange
(new Test.Items.SimpleItem[]{new Test.Items.SimpleItem_FullTc(-1, "Item1"),
new Test.Items.SimpleItem_FullTc(-1, "Item2")});

因此,必须实现从Collection<T>CollectionBase继承的类,然后添加AddRange((方法

最新更新