JokerMartini
JokerMartini

Reputation: 6147

wpf string convert path

I'm trying to create a custom converter which takes a string name and then returns the path designated for that class name. Think of it as a logo for each class name. It doesn't appear to be doing anything. Im not sure why. Here is my code. The ClassName can be Triangle, Camera. I think the problem is in the (value.ToString().ToLower()) it should be a string, but instead the output is this in the console

converter failed to convert

Usage

<Path Data="{Binding ClassName, Converter={local:ClassToPathConverter}}"
      Fill="Red" Width="16" Height="16" Stretch="Uniform"/>

The converter

using System;
using System.Windows.Data;
using System.Windows;
using System.Globalization;
using System.Windows.Markup;

namespace WpfApplication1
{
    internal class ClassToPathConverter : MarkupExtension, IValueConverter
    {
        private static ClassToPathConverter converter;

        public ClassToPathConverter() { }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {            
            switch (value.ToString().ToLower())
            {
                case "triangle":
                    return "M18,0C8.1,0,0,8.1,0,18c0,9.9,8.1,18,18,18s18 - 8.1,18 - 18 C36,8.1,27.9,0,18,0z M9,24.8l9 - 18l9,18H9z M21.4,21.4L18,13.5l - 3.4,7.9H21.4z";
                case "camera":
                    return "M18,36C8.1,36,0,27.9,0,18C0,8.1,8.1,0,18,0c9.9,0,18,8.1,18,18 C36,27.9,27.9,36,18,36z M28.1,12.4l - 5.6,4.5v - 3.4c0 - 0.6 - 0.5 - 1.1 - 1.1 - 1.1H10.1c - 0.6,0 - 1.1,0.5 - 1.1,1.1v9c0,0.6,0.5,1.1,1.1,1.1h11.3 c0.6,0,1.1 - 0.5,1.1 - 1.1v - 3.4l5.6,4.5V12.4z";
                default:
                    return "M 100,200 C 100,25 400,350 400,175 H 280";
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return converter ?? (converter = new ClassToPathConverter());
        }
    }
}

Upvotes: 0

Views: 651

Answers (1)

Mike Zboray
Mike Zboray

Reputation: 40818

Since Data is a Geometry object, not a string, you probably want to return a Geometry object using Geometry.Parse. You might want to cache them in static fields rather than parsing every time. Also, "ClassName" is going to be interpreted as the binding's Path, not the value in the converter, so I guess you want it to be the ConverterParameter. It is then the parameter argument in Convert):

<Path Data="{Binding ConverterParameter=ClassName, Converter={local:ClassToPathConverter}}"
  Fill="Red" Width="16" Height="16" Stretch="Uniform"/>

However, a binding seems kind of weird for this case, a markup extension is probably going to feel more natural. However, what you have is not the way to implement a markup extension. This blog post has a really basic example. The ProvideValue method would need to return the Geometry.

Upvotes: 1

Related Questions