G
Guest
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("myComponent.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.ITypeDescriptorContext context,
System.Type sourceType)
{
if(sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override object
ConvertFrom(System.ComponentModel.ITypeDescriptorContext 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.ITypeDescriptorContext context,
System.Type destinationType)
{
if(destinationType == typeof(InstanceDescriptor))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object
ConvertTo(System.ComponentModel.ITypeDescriptorContext 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.ITypeDescriptorContext
context)
{
return true;
}
public override System.ComponentModel.TypeConverter.StandardValuesCollection
GetStandardValues(System.ComponentModel.ITypeDescriptorContext 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);
}
}
}
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("myComponent.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.ITypeDescriptorContext context,
System.Type sourceType)
{
if(sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override object
ConvertFrom(System.ComponentModel.ITypeDescriptorContext 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.ITypeDescriptorContext context,
System.Type destinationType)
{
if(destinationType == typeof(InstanceDescriptor))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object
ConvertTo(System.ComponentModel.ITypeDescriptorContext 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.ITypeDescriptorContext
context)
{
return true;
}
public override System.ComponentModel.TypeConverter.StandardValuesCollection
GetStandardValues(System.ComponentModel.ITypeDescriptorContext 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);
}
}
}