次の方法で共有


How to get my XAML to show up in the WPF Designer: IMultiValueConverter

Recently I made a post about how to deal with Application.Current at design time.  I thought I'd follow that up with another example of why your XAML may not show up in the WPF Designer (Cider) due to assumptions that are not true at design time.

In this case, we're talking about implementing an IMultiValueConverter for a MultiBinding:

    public class SampleConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string text = (string)values[0];
            Brush backgroundBrush = (Brush) values[1];
            return text + backgroundBrush.ToString();
        }
        (. . .)
    }

In my sample, I am using this SampleConverter in a ControlTemplate that is defined in Application.Resources:

        <ControlTemplate x:Key="ReadOnlyTextBlockTemplate" TargetType="{x:Type TextBox}">
            <ControlTemplate.Resources>
                <loc:SampleConverter x:Key="SampleConverter"/>
            </ControlTemplate.Resources>
            <Border BorderBrush="Black" BorderThickness="1">
                <TextBlock>
                    <TextBlock.Text>
                        <MultiBinding Converter="{StaticResource SampleConverter}">
                        <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Text"/>
                        <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Background"/>
                        </MultiBinding>
                    </TextBlock.Text>
                </TextBlock>
            </Border>
        </ControlTemplate>

This all works fine at runtime but at design time, I fail to load with the error:

Error 1 Unable to cast object of type 'MS.Internal.NamedObject' to type 'System.String'. C:\Users\jnak.REDMOND\Desktop\MultiBindingExample\MultiBindingExample\App.xaml 13 21 MultiBindingExample

If you attach another instance of Visual Studio and debug into this, you'll find this:

Ahh, I made an assumption that is always true at runtime but is not always true at design time.

There are situations like this where some of our hookup is still being worked out and your code needs to handle this in order to work correctly in the designer.

The simple fix here is to deal with this exception being thrown or check the type before trying to cast it (or use a construct such as "as" and check for null).

-- Project is attached for full repro.

MultiBindingExample.zip

Comments