6

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?

BIBD
  • 15,107
  • 25
  • 85
  • 137
Eric Dahlvang
  • 8,252
  • 4
  • 29
  • 50

2 Answers2

19

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
  • 286,951
  • 70
  • 623
  • 758
  • 2
    The designer is sending a DependencyProperty.UnsetValue. Thanks for the tip on debugging the designer. – Eric Dahlvang Jan 08 '10 at 23:29
  • 1
    Starting in Visual Studio 2012, the WPF Designer runs in a separate process named XDesProc.exe. You should attach to this process from the new instance of Visual Studio. – Chad Nouis Oct 31 '13 at 15:54
3

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
  • 599
  • 3
  • 9
  • 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. Jan 08 '10 at 21:18
  • 3
    @Aviad, enums are not reference types, they are value types... casting null to a value type throws a NullReferenceException – Thomas Levesque Jan 08 '10 at 21:27