Set an Enum Dependency Property with XAML

April 23, 2009 09:10 by wjchristenson2

Some new light has been shed on this topic in a Silverlight.net forum thread found here: http://silverlight.net/forums/t/91790.aspx

My explanation below assumes that custom logic is needed when converting from a string to an enumerated type.  The above thread shows how to setup an Enumurated Type dependency property and .NET will convert from string the the enumerated type just fine.

I'm going to leave the post below as there are going to be situations where you may want to use a TypeConverter.

***************************************************************************

There are situations where you want to set a property's value in XAML and .NET is unable to convert the string value to the property's type.  I’ve created a solution which provides an example of how to fix this using a TypeConverter.

The TypeConverter will basically tell .NET that we can convert a string to our type and furthermore, we will provide the logic on how to convert it to our custom type.

First step is to create our TypeConverter.  In my example, I have a vehicle control and we are going to set the type of vehicle.  Here is the code for our VehicleTypeConverter.


   1:  Imports System.ComponentModel
   2:   
   3:  Public Class VehicleTypeConverter
   4:      Inherits TypeConverter
   5:   
   6:      Public Overrides Function CanConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean
   7:          If sourceType.Equals(GetType(String)) Then
   8:              Return True
   9:          Else
  10:              Return MyBase.CanConvertFrom(context, sourceType)
  11:          End If
  12:      End Function
  13:   
  14:      Public Overrides Function CanConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean
  15:          If destinationType.Equals(GetType(String)) Then
  16:              Return True
  17:          Else
  18:              Return MyBase.CanConvertTo(context, destinationType)
  19:          End If
  20:      End Function
  21:   
  22:      Public Overrides Function ConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object) As Object
  23:          If TypeOf value Is String Then
  24:              Try
  25:                  Return CType([Enum].Parse(GetType(Vehicle.VehicleType), value, True), Vehicle.VehicleType)
  26:              Catch
  27:                  Throw New InvalidCastException(value)
  28:              End Try
  29:          Else
  30:              Return MyBase.ConvertFrom(context, culture, value)
  31:          End If
  32:      End Function
  33:   
  34:      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
  35:          If destinationType.Equals(GetType(String)) Then
  36:              Return value.ToString()
  37:          Else
  38:              Return MyBase.ConvertTo(context, culture, value, destinationType)
  39:          End If
  40:      End Function
  41:  End Class

As I noted earlier, this class tells .NET that strings are allowed to be converted to our type property and we also provide the logic on how to convert the string value to the type.  Now that we have this converter defined, we can use it in our control, page, or wherever our type property is being used.  I’m using it in the vehicle control.  Here’s how we use the TypeConverter.


   1:  Imports System.ComponentModel
   2:   
   3:  Partial Public Class Vehicle
   4:      Inherits UserControl
   5:   
   6:      Public Enum VehicleType
   7:          NA = 0
   8:          Car = 1
   9:          Bus = 2
  10:          Truck = 3
  11:      End Enum
  12:   
  13:      Public Shared ReadOnly TypeProperty As DependencyProperty = DependencyProperty.Register("Type", GetType(VehicleType), GetType(Vehicle), New PropertyMetadata(VehicleType.NA, AddressOf TypeChangedHandler))
  14:   
  15:      <TypeConverter(GetType(VehicleTypeConverter))> _
  16:      Public Property Type() As VehicleType
  17:          Get
  18:              Return DirectCast(GetValue(Vehicle.TypeProperty), VehicleType)
  19:          End Get
  20:          Set(ByVal value As VehicleType)
  21:              SetValue(Vehicle.TypeProperty, value)
  22:          End Set
  23:      End Property
  24:   
  25:      Public Sub New()
  26:          InitializeComponent()
  27:      End Sub
  28:   
  29:      Private Shared Sub TypeChangedHandler(ByVal o As DependencyObject, ByVal args As DependencyPropertyChangedEventArgs)
  30:          DirectCast(o, Vehicle).OnTypeChanged(DirectCast(args.NewValue, VehicleType))
  31:      End Sub
  32:   
  33:      Private Sub OnTypeChanged(ByVal newValue As VehicleType)
  34:          Me.tbkTest.Text = "The vehicle type is a " & newValue.ToString() & "."
  35:      End Sub
  36:   
  37:  End Class

Everything is straight forward here except for how we wire in our VehicleTypeConverter.  We add attributes to our Type property to tell the property that we will handle the converting from and to the VehicleType.

Below you’ll find the entire solution if you wish to see it in action.

EnumDependencyProperty_Soln.zip (597.05 kb)


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments