我正在重述这个问题,总结一下我已经找到的东西:
我有一个测试TypeConverter,(MyConverter),对于ConvertToString,无论输入是什么,都会输出“Converted To String”。
为了确保Get32verter for Int32选择了这个,我添加以下行:
(1) Dim tcp As TypeDescriptionProvider = TypeDescriptor.AddAttributes(GetType(Int32), New TypeConverterAttribute(GetType(MyConverter)))
下一步:
(2) Dim tc As TypeConverter = TypeDescriptor.GetConverter(GetType(Int32)) // Get the Int32 converter
(3) Console.WriteLine(tc.ConvertToString(12)) // The output is, as expected, "Converted To String"
下一步:
(4) TypeDescriptor.RemoveProvider(tcp, GetType(Int32)) //Remove the TypeConverterAttribute associated with int32
(5) tc = TypeDescriptor.GetConverter(GetType(Int32)) //Get Int32 TypeConverter
(6) Console.WriteLine(tc.ConvertToString(12)) //The output is STILL "Converted To String"
然而:
Dim tcp As TypeDescriptionProvider = TypeDescriptor.AddAttributes(GetType(Int32), New TypeConverterAttribute(GetType(MyConverter)))
TypeDescriptor.RemoveProvider(tcp, GetType(Int32)) //Immediately remove the provider
Dim tc As TypeConverter = TypeDescriptor.GetConverter(GetType(Int32))
Console.WriteLine(tc.ConvertToString(12)) //The output is, as expected, "12"
似乎第(2)行正在创建一些其他未使用RemoveProvider删除的关联,因为RemoveProvider在该行之前工作,但不在之后。
此外,在第(4)行和第4行之间。 (5),如果我执行TypeDescriptor.GetAttributes(GetType(Int32)),则TypeConverterAttribute已按预期删除。
呻吟......还有另一个ETA。
如果在第(1)行之前我添加......
Dim OriginalProvider As TypeDescriptionProvider = TypeDescriptor.GetProvider(GetType(Int32))
然后在第(4)行之后我添加......
TypeDescriptor.AddProvider(OriginalProvider, GetType(Int32))
有效。但是,在删除我的自定义提供程序后,原始提供程序应该是堆栈中的下一个。
ETA。我想我已经钉了它。
忽略有关重新添加OriginalProvider的最新评论。 相反,在第(4)行之后,添加......
TypeDescriptor.Refresh(GetType(Int32))
由于某种原因,在删除后没有调用Refresh。
如果你在Type的Nullable上使用了GetConverter,你也需要刷新可空。所以,如果我说:
Dim tc As TypeConverter = TypeDescriptor.GetConverter(GetType(Nullable(Of Int32)))
删除提供程序后,我需要输入:
TypeDescriptor.Refresh(GetType(Int32))
TypeDescriptor.Refresh(GetType(Nullable(Of Int32)))
----原创问题----
为了强制可以为空的类型使用自定义转换器,我添加了一个TypeConverterAttribute:
TypeDescriptor.AddAttributes(GetType(Int32), New TypeConverterAttribute(GetType(MyConverter)))
这样,以下行将选择一个可以使用MyConverter作为底层转换器的可空转换器:
Converter = TypeDescriptor.GetConverter(GetType(Int32))
然而,一旦我完成,我就看不到将MyConverter与Int32取消关联的方法,因为没有TypeDescriptor.RemoveAttribute。
有什么想法吗?
ETA:
好的,我已经到了一半。
我发现TypeDescriptor.AddAttributes返回一个TypeDescriptionProvider然后可以删除。但是,它没有按预期工作。
这有效:
Dim tcp As TypeDescriptionProvider = TypeDescriptor.AddAttributes(GetType(Int32), New TypeConverterAttribute(GetType(MyConverter)))
TypeDescriptor.RemoveProvider(tcp, GetType(Int32))
Dim tc As TypeConverter = TypeDescriptor.GetConverter(GetType(Nullable(Of Int32)))
Console.WriteLine(tc.ConvertToString(12)) '12 is output
正如预期的那样,拾取原始转换器,并忽略MyConverter。
然而,这不起作用:
Dim tcp As TypeDescriptionProvider = TypeDescriptor.AddAttributes(GetType(Int32), New TypeConverterAttribute(GetType(MyConverter)))
Dim tc As TypeConverter = TypeDescriptor.GetConverter(GetType(Nullable(Of Int32)))
Console.WriteLine(tc.ConvertToString(12))
TypeDescriptor.RemoveProvider(tcp, GetType(Int32))
tc = TypeDescriptor.GetConverter(GetType(Nullable(Of Int32)))
Console.WriteLine(tc.ConvertToString(12))
在RemoveProvider之后,GetConverter仍然会选择MyConverter - 只是因为我在原始GetConverter之后移动了它!
再次,任何想法?
ETA2:
我通过在GetConverter方法上指定noCustomTypeDesc标志来解决这个问题,但我仍然想知道发生了什么。
我已经使用TypeDescriptor.GetAttributes(GetType(Int32))列出了我删除提供程序后的所有属性,而且TypeConverterAttribute确实已经消失了但GetConverter继续选择MyConverter。