Sometimes when setting properties with XAML you may get the AG_E_PARSER_BAD_PROPERTY_VALUE error. This can mean a variety of things, but in this post we are going to visit a situation where .NET cannot convert the XAML string to the .NET object's type.
A good example of this is a Date property. Let's say we have a control that has a MaxDate property. If we set the property in XAML it may look like this: MaxDate="01-01-2009". Unfortunately this does not work. You'll get our fatal parser error because the parser is not smart enough to parse the string to a date type.
The workaround is to hold .NET parsers hand and tell it how to parse the string to our desired type (in this case a Date). We'll do this by first creating our own TypeConverter. I'll call it the DateTypeConverter. We'll inherit from the TypeConverter base class and override key methods used to detect if we can convert from/to a type and handle the actual conversion process. Here's our TypeConverter class for converting from and to a Date type.
Imports System.ComponentModel
Public Class DateTypeConverter
Inherits TypeConverter
Public Overrides Function CanConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean
If sourceType.Equals(GetType(String)) Then
Return True
Else
Return MyBase.CanConvertFrom(context, sourceType)
End If
End Function
Public Overrides Function CanConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean
If destinationType.Equals(GetType(String)) Then
Return True
Else
Return MyBase.CanConvertTo(context, destinationType)
End If
End Function
Public Overrides Function ConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object) As Object
If TypeOf value Is String Then
Try
Return Date.Parse(value.ToString())
Catch
Throw New InvalidCastException(value)
End Try
Else
Return MyBase.ConvertFrom(context, culture, value)
End If
End Function
Public Overrides Function ConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As System.Type) As Object
If destinationType.Equals(GetType(String)) Then
Return value.ToString()
Else
Return MyBase.ConvertTo(context, culture, value, destinationType)
End If
End Function
End Class
Now that we have our custom converter created, we need to tell our control's property to use this converter when being set via a property attribute. In our case, when the parser attempts to set the property, it will invoke our DateTypeConverter and parse the string to a date properly.
Public Shared ReadOnly MaxDateProperty As DependencyProperty = DependencyProperty.Register("MaxDate", GetType(Date), GetType(SilverlightControl1), New PropertyMetadata(Date.MaxValue, AddressOf MaxDateChangedHandler))
<TypeConverter(GetType(DateTypeConverter))> _
Public Property MaxDate() As Date
Get
Return DirectCast(GetValue(SilverlightControl1.MaxDateProperty), Date)
End Get
Set(ByVal value As Date)
SetValue(SilverlightControl1.MaxDateProperty, value)
End Set
End Property
Take note of line 3. Adding the TypeConverter attribute tells the .NET XAML parser to use our DateTypeConverter to parse the String to Date.
SiverlightDateTime_Soln.zip (593.57 kb)