1

I made a converter from string to color and back and it works fine when run but on the editor it just throws a "Token is not valid." error and prevents the editor from showing up, really annoying because it prevents me from using the visual editor.

I made the converter for the ColorPicker from extended WPF toolkit.

Here's the converter code:

public class MaddoColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Color color = Colors.Black;

        if (value != null && !string.IsNullOrWhiteSpace(value.ToString()))
        {
            string c = value.ToString();
            var convertedColor = ColorConverter.ConvertFromString(c);
            if (convertedColor != null)
            {
                color = (Color) convertedColor;
            }
        }

        return color;

    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            Color color = (Color)value;
            Debug.WriteLine(color.ToString());
            return color.ToString();
        }
        return string.Empty;
    }
}

And here are some relevant snippets from the form xaml:

<Window.Resources>        
    <wpfCatalog:MaddoColorConverter x:Key="ColorConverter" />
</Window.Resources>

<xctk:ColorPicker Grid.Row="3" Grid.Column="2" SelectedColor="{Binding ColoreTestoRGB, Converter={StaticResource ColorConverter}}"/>
MaddoScientisto
  • 189
  • 4
  • 17
  • What's the type of the ColoreTestoRGB source property and what value does it return? This needs to be a valid value that the ColorConverter actually understands such as for example "#000". – mm8 Mar 20 '17 at 13:34
  • it's a string property, it looks into a dictionary for the proper value or returns a default one public string ColoreTestoRGB { get { return PicSettings.GetString("coloreTestoRGB"); } set { PicSettings.Set("coloreTestoRGB", value); RaisePropertyChanged("ColoreTestoRGB"); } } – MaddoScientisto Mar 21 '17 at 11:43
  • Obviously you cannot pass the string "ColoreTestoRGB" to the ColorConverter.ConvertFromString method in your converter without getting an exception. – mm8 Mar 21 '17 at 11:47

1 Answers1

2

You need to add more checks to your MaddoColorConverter. For example, if binding fails, WPF will pass DependencyProperty.UnsetValue to your converter. Your converter does not check for this case but instead just converts whatever is passed to string. Change your converter like this (note I've updated only Convert method, did not touch ConvertBack which might need fixes to, but that is not relevant to this question):

public class MaddoColorConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        Color color = Colors.Black;

        if (value != null && value != DependencyProperty.UnsetValue && value is string && !String.IsNullOrWhiteSpace((string) value)) {
            string c = (string) value;
            object convertedColor = null;
            try {
                convertedColor = ColorConverter.ConvertFromString(c);
            }
            catch (Exception ex) {
                throw new FormatException($"String {c} does not represent a valid color", ex);
            }
            if (convertedColor != null) {
                color = (Color) convertedColor;
            }
        }

        return color;
    }
}

If for whatever reason it is expected to have invalid color values at design time - do not throw exception when at design time, like this:

private static readonly DependencyObject _dummy = new DependencyObject();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
    System.Windows.Media.Color color = Colors.Black;

    if (value != null && value != DependencyProperty.UnsetValue && value is string && !String.IsNullOrWhiteSpace((string) value)) {
        string c = (string) value;
        object convertedColor = null;
        try {
            convertedColor = ColorConverter.ConvertFromString(c);
        }
        catch (Exception ex) {
            if (!DesignerProperties.GetIsInDesignMode(_dummy)) {
                throw new FormatException($"String {c} does not represent a valid color", ex);
            }
        }
        if (convertedColor != null) {
            color = (Color) convertedColor;
        }
    }

    return color;
}
Evk
  • 98,527
  • 8
  • 141
  • 191