Search code examples
c#wpfxamlivalueconverter

My custom value converter causes XAML validation tool to fail


I've created a custom converter that performs converting of values based on configured mapping. It looks like below

public class UniversalConverter : List<ConverterItem>, IValueConverter
{
    private bool useDefaultValue;

    private object defaultValue;

    public object DefaultValue
    {
        get { return defaultValue; }
        set
        {
            defaultValue = value;
            useDefaultValue = true;
        }
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        foreach (var item in this)
            if (Equals(item.From, value))
                return item.To;
        if (useDefaultValue)
            return DefaultValue;
        throw new ConversionException(string.Format("Value {0} can't be converted and default value is not allowed", value));
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        foreach (var item in this)
            if (Equals(item.To, value))
                return item.From;
        throw new ConversionException(string.Format("Value {0} can't be converted back", value));
    }
}

public class ConverterItem
{
    public object From { get; set; }

    public object To { get; set; }
}

public class ConversionException : Exception
{
    public ConversionException() { }

    public ConversionException(string message) : base(message) { }
}

Sample XAML is below

<core:UniversalConverter x:Key="ItemCountToVisiblityConverter" DefaultValue="{x:Static Visibility.Collapsed}">
    <core:ConverterItem To="{x:Static Visibility.Visible}">
        <core:ConverterItem.From>
            <system:Int32>0</system:Int32>
        </core:ConverterItem.From>
    </core:ConverterItem>
</core:UniversalConverter>

Now everything builds and works fine, but if I use it XAML Visual Studio underscores the whole file with curvy blue lines and shows two kind of mistakes:

1) If converter is put into ResourceDictionary AND is assigned an x:Key attribute it shows Missing key value on 'UniversalConverter' object

2) If I assign DefaultValue property any value (e.g {x:Null}) the message is XAML Node Stream: Missing EndMember for 'StuffLib.UniversalConverter.{http://schemas.microsoft.com/winfx/2006/xaml}_Items' before StartMember 'StuffLib.UniversalConverter.DefaultValue'

What is the reason for those messages? I can live with them but they hide all other compiler and ReSharper markings


Solution

  • Don't inherit from list, just create Items property in your converter:

    [ContentProperty("Items")]
    public class UniversalConverter : IValueConverter
    {
        public ConverterItem[] Items { get; set; }
    
        public object DefaultValue { get; set; }
        //all other stuff goes here
    }
    

    and xaml:

    <l:UniversalConverter x:Key="MyConverter">
      <x:Array Type="l:ConverterItem">
        <l:ConverterItem From="..." To="..." />