views:

504

answers:

0

I'm restating this problem to summarise what I've already found:

I have a test TypeConverter, (MyConverter), that for a ConvertToString will output "Converted To String", no matter what the input.

To ensure this is picked up by GetConverter for Int32, I add the following line:

(1) Dim tcp As TypeDescriptionProvider = TypeDescriptor.AddAttributes(GetType(Int32), New TypeConverterAttribute(GetType(MyConverter)))

Next:

(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"

Next:

(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"

However:

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"

It seems that line (2) is creating some other association that isn't being removed with RemoveProvider, since RemoveProvider works before that line, but not after.

Also, between lines (4) & (5), if I do TypeDescriptor.GetAttributes(GetType(Int32)), the TypeConverterAttribute has, as expected, been removed.

Groan...Yet another ETA.

If before line (1) I add...

Dim OriginalProvider As TypeDescriptionProvider = TypeDescriptor.GetProvider(GetType(Int32))

And then after line(4) I add...

TypeDescriptor.AddProvider(OriginalProvider, GetType(Int32))

It works. But the original provider should have been the next on the stack anyway after I had removed my custom provider.

ETA. I think I've nailed it.

Ignore the last comment about re-adding the OriginalProvider. Instead, after the line(4), add...

TypeDescriptor.Refresh(GetType(Int32))

For some reason, Refresh is not being called after the Remove.

If you'd used GetConverter on the Nullable Of the Type, you'll need to refresh the nullable as well. So if I'd said:

Dim tc As TypeConverter = TypeDescriptor.GetConverter(GetType(Nullable(Of Int32)))

After removing the provider, I'd need to type:

TypeDescriptor.Refresh(GetType(Int32))
TypeDescriptor.Refresh(GetType(Nullable(Of Int32)))

----Original Question----

In order to force a nullable type to use a custom converter, I add a TypeConverterAttribute with the line:

TypeDescriptor.AddAttributes(GetType(Int32), New TypeConverterAttribute(GetType(MyConverter)))

That way, the following line will pick up a nullable converter with MyConverter as the underlying converter:

Converter = TypeDescriptor.GetConverter(GetType(Int32))

However, once I am finished, I can't see a way to disassociate MyConverter from Int32 as there is no TypeDescriptor.RemoveAttribute.

Any ideas?

ETA:

Ok, I'm half way there.

I found out that TypeDescriptor.AddAttributes returns a TypeDescriptionProvider that I can then remove. However, it's not working as expected.

This works:

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

As expected, the original converter is picked up, and MyConverter is ignored.

However, this doesn't work:

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))

After the RemoveProvider, the GetConverter still picks up MyConverter - just because I've moved it after the original GetConverter!

Again, any ideas?

ETA2:

I've got a work around by specifying the noCustomTypeDesc flag on the GetConverter Method, but I'd still like to know what's going on.

I've used TypeDescriptor.GetAttributes(GetType(Int32)) to list all the attributes after I've removed the provider, and the TypeConverterAttribute is, indeed, gone yet GetConverter continues to pick up MyConverter.