TypeConverter.ConvertFrom一直被调用,当用户选择一个值时,我只需执行一次转换。
我希望能够在PropertyGrid控件中显示对象,以便您可以查看和更改其中的子值。使用ExpandableObjectConverter将该属性归因于此。我还希望能够从下拉列表中选择不同的值以设置对象。通过扩展ExpandableObjectConverter并实现GetStandardValues和ConvertFrom,我可以使其工作。
在我的示例中,我对GetStandardValues使用描述性值,然后将其转换为ConvertFrom中的目标对象。但是,我需要创建的对象会占用大量资源,因此,在UI中选择它们之前,我不想创建任何对象。
我遇到的问题是PropertyGrid多次调用ConvertFrom,而不仅仅是将所选结果转换为目标类型(请参见下面的日志)。
我想实现此处显示的内容,但是仅在用户实际进行选择时创建基础对象。
PropertyGridCtrl.SelectedObject = new MyContainer();
...
public class MyContainer
{
[TypeConverterAttribute(typeof(ExpandableObjectConverterWithPicker))]
public MyExpensiveObjectToCreate SlowCreationObj { get; set; } = new MyExpensiveObjectToCreate("Original");
}
public class MyExpensiveObjectToCreate
{
public MyExpensiveObjectToCreate(string value)
{
Debug.WriteLine("Creating Expensive Object : " + value);
this.Value = value;
Thread.Sleep(1000);
}
public string Value { get; set; } = "test";
public override string ToString() { return this.Value; }
}
public class ExpandableObjectConverterWithPicker : ExpandableObjectConverter
{
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return true; }
public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; }
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(new string[] { "Description of Object 1", "Description of Object 2" });
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string strVal)
{
if (strVal == "Description of Object 1")
return new MyExpensiveObjectToCreate("Object 1");
else if (strVal == "Description of Object 2")
return new MyExpensiveObjectToCreate("Object 2");
else
throw new NotSupportedException();
}
return base.ConvertFrom(context, culture, value);
}
}
从下拉列表中选择值时,调试日志
Creating Expensive Object : Original
Creating Expensive Object : Object 1
Creating Expensive Object : Object 1
Creating Expensive Object : Object 1
Creating Expensive Object : Object 1
Creating Expensive Object : Object 1
Creating Expensive Object : Object 2
Creating Expensive Object : Object 1
Creating Expensive Object : Object 1
Creating Expensive Object : Object 2
Creating Expensive Object : Object 2
Creating Expensive Object : Object 2