views:

317

answers:

2

Here is my data type:

using System;

namespace UI 
{
    public class AddressType
    {
        public byte ID { get; set; }
        public string Name { get; set; }
    } 
}

Here is my collection:

using System.Collections.ObjectModel;

namespace UI
{
    public class AddressTypes : ObservableCollection<AddressType>
    {
    }
}
Here is my XAML from my UserControl.Resources section of my page:

<local:AddressTypes x:Name="AddressTypesList">

    <local:AddressType ID="0" Name="Select"/>
    <local:AddressType ID="1" Name="Office"/>
    <local:AddressType ID="2" Name="Shipping"/>
    <local:AddressType ID="3" Name="Warehouse"/>
    <local:AddressType ID="4" Name="Home"/>
    <local:AddressType ID="5" Name="Foreign"/>

</local:AddressTypes>

When I try to assign a value in XAML to the ID property, I get a AG_E_PARSER_BAD_PROPERTY_VALUE [Line: 10 Position: 35] error. If I change the data type of the ID property to int, all is well. Doesn't Silverlight support the byte data type?

A: 

I would imagine that in order to save space in the downloadable runtime, the XAML parser only supports integers for numbers in XAML, hence the behavior you are seeing. In order for the XAML parser to know how to parse the XAML it would need to understand the code that takes the input first - it may be that it doesn't actually take this into account and therefore always parses using something like int.Parse.

In case the parser does support bytes but not in this way, you could test it by specifying the ID using hex notation or setting the property using element notation rather than attribute as in:

<local:AddressType Name="Select">
  <ID>0x00</ID>
</local:AddressType>
Jeff Yates
+1  A: 

Specifying byte values using the attribute syntax does not appear to work. However, it is possible to specify byte values using the property element syntax. Add the the following xmlns declaration:

xmlns:sys="clr-namespace:System;assembly=mscorlib"

The you should be able to specify the byte properties like so:

<local:AddressType Name="Select">
  <local:AddressType.ID>
    <sys:Byte>0</sys:Byte>
  </local:AddressType.ID>
</local:AddressType>

This is kind of messy though, so what you can do is implement a custom type converter, and mark up your property with an attribute to use that type converter.

The TypeConverter should look something like:

public class ByteTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        if (value is string)
        {
            return Byte.Parse(value as string);
        }
        else
        {
            return base.ConvertFrom(context, culture, value);
        }
    }
}

And you then want to modify your class so that the property points to this type converter:

public class AddressType
{
    [TypeConverter(typeof(ByteTypeConverter))]
    public byte ID { get; set; }
    public string Name { get; set; }
}

Now you should be able to use the regular property attribute syntax:

<local:AddressType ID="0" Name="Select"/>
KeithMahoney