Set an Enum Dependency Property with XAML

April 23, 2009 04: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.

Imports System.ComponentModel

Public Class VehicleTypeConverter
    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 CType([Enum].Parse(GetType(Vehicle.VehicleType), value, True), Vehicle.VehicleType)
            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

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.

Imports System.ComponentModel

Partial Public Class Vehicle
    Inherits UserControl

    Public Enum VehicleType
        NA = 0
        Car = 1
        Bus = 2
        Truck = 3
    End Enum

    Public Shared ReadOnly TypeProperty As DependencyProperty = DependencyProperty.Register("Type", GetType(VehicleType), GetType(Vehicle), New PropertyMetadata(VehicleType.NA, AddressOf TypeChangedHandler))

    <TypeConverter(GetType(VehicleTypeConverter))> _
    Public Property Type() As VehicleType
        Get
            Return DirectCast(GetValue(Vehicle.TypeProperty), VehicleType)
        End Get
        Set(ByVal value As VehicleType)
            SetValue(Vehicle.TypeProperty, value)
        End Set
    End Property

    Public Sub New()
        InitializeComponent()
    End Sub

    Private Shared Sub TypeChangedHandler(ByVal o As DependencyObject, ByVal args As DependencyPropertyChangedEventArgs)
        DirectCast(o, Vehicle).OnTypeChanged(DirectCast(args.NewValue, VehicleType))
    End Sub

    Private Sub OnTypeChanged(ByVal newValue As VehicleType)
        Me.tbkTest.Text = "The vehicle type is a " & newValue.ToString() & "."
    End Sub

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)

Bookmark and Share