views:

229

answers:

2

A converter such as what follows will cause the 2008 visual studio designer to not display the xaml, and error out with a "Specified cast is not valid." exception.

public class ItemsVisibilityToGridColumnWidthConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        //THE TWO OFFENDING LINES...
        var itemsVisibility = (Visibility)values[0];
        var orientation = (Orientation)values[1];

        if (orientation == Orientation.Horizontal && itemsVisibility != Visibility.Visible)
        {
            return new GridLength(0);
        }

        return new GridLength(4, GridUnitType.Star);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Changing the cast to use a method such as this fixes the issue:

static class EnumCaster
{
    internal static Orientation CastAsOrientation(object value)
    {
        if (value is Enum)
        {
            return (Orientation)value;
        }
        return Orientation.Horizontal;
    }
    internal static Visibility CastAsVisibility(object value)
    {
        if (value is Enum)
        {
            return (Visibility)value;
        }
        return Visibility.Visible;
    }
}

My question is, wtf is wrong with the Visual Studio designer? And, is there a better way to cast these objects to their corresponding Enum in such a way that the designer doesn't throw a fit?

+1  A: 

I think the designer is processing the converter in the first example and is unable to cast because values[0] and values[1] are null. If you do checks for null then this should resolve the problem. The second example is essentially checking for null whilst using the "is" keyword.

mattythomas2000
Casting null to anything (reference type) doesn't throw an exception. The more likely reason is that values[0] and values[1] should be swapped around...
Aviad P.
@Aviad, enums are not reference types, they are value types... casting null to a value type throws a NullReferenceException
Thomas Levesque
+4  A: 

I think it might happen because at some point, the converter is called with bad arguments. You can debug the call the converter in the designer by following these steps :

  • start a new instance of Visual Studio
  • attach to the first VS instance (Tools -> Attach to process)
  • open the converter source file
  • put a breakpoint in the Convert method
  • reload the WPF designer in the first VS instance

That way you should be able to examine the arguments passed to the converter

Thomas Levesque
+1 for the nice tip on debugging converters in the designer
mattythomas2000
The designer is sending a DependencyProperty.UnsetValue. Thanks for the tip on debugging the designer.
Eric Dahlvang