By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,853 Members | 1,012 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,853 IT Pros & Developers. It's quick & easy.

Problem with type converter

P: n/a
I have written a component with a property IPAdrress of type
System.Net.IPAddress. To ease the configuration of the component at design
time, I have written a type converter for the type System.Net.IPAddress. The
type System.Net.IPAddress, as you know, is provided by Microsoft and I have
no choice but to apply the type converter on the IPAddress property of the
component itself (instead of the type System.Net.IPAddress). All normal
features of a type converter are working perfectly but I just couldn't get
VS.NET 2003 to produce constructor-based property initialization code for the
IPAddress property of the component as follow

this.myComponent.IPAddress = new System.Net.IPAddress(0);

instead of

this.myComponent.IPAddress.Address = 0;
or
this.myComponent.IPAddress =
((System.Net.IPAddress)(resources.GetObject("myCom ponent.IPAddress")));

This wouldn't have happened if I were able to apply the type converter on
the type System.Net.IPAddress itself. How do I get around this? Thanks.

Code of the component (extract) and the type converter follow:

// MyComponent.cs
public class MyComponent : System.ComponentModel.Component
{
// ...
[TypeConverter(typeof(IPAddressConverter))]
public IPAddress IPAddress
{
get
{
return ipAddr;
}
set
{
if(value == null)
throw new ArgumentNullException("IPAddress");
ipAddr = value;
}
}
// ...
}

// IPAddressConverter.cs
using System;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Net;
using System.Net.Sockets;
using System.Reflection;

namespace Util.Net
{
public class IPAddressConverter : System.ComponentModel.TypeConverter
{
private const string ANY = "Any";
private const string LOOPBACK = "Loopback";
private const string ANYIPADDRESS = "0.0.0.0";
private const string LOOPBACKIPADDRESS = "127.0.0.1";

public IPAddressConverter()
{
}

public override bool
CanConvertFrom(System.ComponentModel.ITypeDescript orContext context,
System.Type sourceType)
{
if(sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}

public override object
ConvertFrom(System.ComponentModel.ITypeDescriptorC ontext context,
System.Globalization.CultureInfo culture, object value)
{
if(value is string)
{
if((string)value == ANY)
value = ANYIPADDRESS;
else if((string)value == LOOPBACK)
value = LOOPBACKIPADDRESS;
return IPAddress.Parse((string)value);
}
return base.ConvertFrom(context, culture, value);
}

public override bool
CanConvertTo(System.ComponentModel.ITypeDescriptor Context context,
System.Type destinationType)
{
if(destinationType == typeof(InstanceDescriptor))
return true;
return base.CanConvertTo(context, destinationType);
}

public override object
ConvertTo(System.ComponentModel.ITypeDescriptorCon text context,
System.Globalization.CultureInfo culture, object value, System.Type
destinationType)
{
if(destinationType == typeof(string) && value is IPAddress)
{
if(value.Equals(IPAddress.Any))
return ANY;
if(value.Equals(IPAddress.Loopback))
return LOOPBACK;
return value.ToString();
}
if(destinationType == typeof(InstanceDescriptor) && value is IPAddress &&
((IPAddress)value).AddressFamily == AddressFamily.InterNetwork)
{
ConstructorInfo constructorInfo = typeof(IPAddress).GetConstructor(
new Type[]{typeof(long)});
if(constructorInfo != null)
{
// return new InstanceDescriptor(constructorInfo, new long[]{
// ((IPAddress)value).Address});
byte[] addressBytes = ((IPAddress)value).GetAddressBytes();
long address = addressBytes[0] | (addressBytes[1] << 8) |
(addressBytes[2] << 16) | (addressBytes[3] << 24);
return new InstanceDescriptor(constructorInfo, new
long[]{address});
}
}
return base.ConvertTo(context, culture, value, destinationType);
}

public override bool
GetStandardValuesSupported(System.ComponentModel.I TypeDescriptorContext
context)
{
return true;
}

public override System.ComponentModel.TypeConverter.StandardValues Collection
GetStandardValues(System.ComponentModel.ITypeDescr iptorContext context)
{
// IPAddress[] specialIPAddresses = {
// new IPAddress(IPAddress.Any.Address),
// new IPAddress(IPAddress.Loopback.Address)};
IPAddress[] specialIPAddresses = {
new IPAddress(0),
new IPAddress(0x0100007F)};
return new StandardValuesCollection(specialIPAddresses);
}
}
}

Jul 21 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Hi,

First of all, I would like to confirm my understanding of your issue. From
your description, I'm not quite sure what you need to do. Do you mean that
a constructor that can convert as the type converter does, to initialize
the IPAddress? If there is any misunderstanding, please feel free to let me
know.

If so, I think we cannot do with the IPAddress class, since it doesn't have
a constructor that does so. I think you can try to overload the constructor
of IPAddressConverter to achieve this.

Please correct me if my understanding is wrong. Thanks!

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Jul 21 '05 #2

P: n/a
Hi Kevin,

I want my component to be able to generate a constructor-based
initialization for its IPAddress property. For example, if I set the
IPAddress property to be "127.0.0.1", it should generate in the
InitializeComponent() method of its container the following code

this.myComponent.IPAddress = new System.Net.IPAddress(16777343);
// 16777343 is the equivalent of 127.0.0.1

rather than

this.myComponent.IPAddress =
((System.Net.IPAddress)(resources.GetObject("myCom ponent.IPAddress")));

The System.Net.IPAddress type does have a constructor that takes a long
address as parameter. I've written the IPAddressConverter type to accomplish
this. The code is found in the overriden ConvertTo method below but
unfortunately it does not work as expected. Kindly advise. Thanks.

public override object
ConvertTo(System.ComponentModel.ITypeDescriptorCon text context,
System.Globalization.CultureInfo culture, object value, System.Type
destinationType)
{
if(destinationType == typeof(string) && value is IPAddress)
{
if(value.Equals(IPAddress.Any))
return ANY;
if(value.Equals(IPAddress.Loopback))
return LOOPBACK;
return value.ToString();
}
if(destinationType == typeof(InstanceDescriptor) && value is IPAddress &&
((IPAddress)value).AddressFamily == AddressFamily.InterNetwork)
{
ConstructorInfo constructorInfo = typeof(IPAddress).GetConstructor(
new Type[]{typeof(long)});
if(constructorInfo != null)
{
// return new InstanceDescriptor(constructorInfo, new long[]{
// ((IPAddress)value).Address});
byte[] addressBytes = ((IPAddress)value).GetAddressBytes();
long address = addressBytes[0] | (addressBytes[1] << 8) |
(addressBytes[2] << 16) | (addressBytes[3] << 24);
return new InstanceDescriptor(constructorInfo, new
long[]{address});
}
}
return base.ConvertTo(context, culture, value, destinationType);
}

"Kevin Yu [MSFT]" wrote:
Hi,

First of all, I would like to confirm my understanding of your issue. From
your description, I'm not quite sure what you need to do. Do you mean that
a constructor that can convert as the type converter does, to initialize
the IPAddress? If there is any misunderstanding, please feel free to let me
know.

If so, I think we cannot do with the IPAddress class, since it doesn't have
a constructor that does so. I think you can try to overload the constructor
of IPAddressConverter to achieve this.

Please correct me if my understanding is wrong. Thanks!

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Jul 21 '05 #3

P: n/a
Hi,

For this issue, we have reproduce out the problem, it seems that IPAddress
always use binary serialization for code generator. We will spend some more
time on it. We will update you ASAP. Thanks for your understanding.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

Jul 21 '05 #4

P: n/a
Hi,

My investigation shows that if I were able to apply the TypeConverter
attribute on the type itself (in my case the System.Net.IPAddress type)
rather than on the property of this type of the component (in my case the
MyComponent.IPAddress property), VS .NET would produce the correct
initialization code. This is hypothetical of course since the
System.Net.IPAddress type is provided by Microsoft. Thanks.

""Jeffrey Tan[MSFT]"" wrote:
Hi,

For this issue, we have reproduce out the problem, it seems that IPAddress
always use binary serialization for code generator. We will spend some more
time on it. We will update you ASAP. Thanks for your understanding.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

Jul 21 '05 #5

P: n/a
Hi,

I debugged the sample and can confirm that serialization indeed doesn't
seem to pick up type converters attached to properties. In this case, you
have a type converter attached to a property of type IPAddress and not the
IPAddress class itself, so it is by design that serialization doesn't find
it.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Jul 21 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.