Search code examples
wpfconvertersivalueconverter

Binding Converter with paramater in one line syntax


I am basically trying to formulate the following Binding conditions in one line/tag:

<Rectangle.Fill>
     <Binding Path="Contents.Value">
          <Binding.Converter>
               <localVM:SquareConverter Empty="White" Filled="Black" Unknown="Gray"/>
           </Binding.Converter>
      </Binding>
</Rectangle.Fill>

I can't seem to figure out how to specify the parameters above Empty="white" Filled="Black" Unkown="gray"

What I have so far:

 <Button Background="{Binding Path=Contents.Value, Converter={StaticResource localVM:SquareConverter}, ConverterParameter={ }}">

I give it the resource fine I think, now I can't find out how to specify the parameters syntactically correct?

P.S. Don't worry about the context, the button background is mapped to a rectangle fill via control template etc.


Solution

  • You might have noticed that the number of parameters that you can pass to Converter is just 1. You may pass an array of string or whatsoever, but I believe having all of your arguments in a single string would be easier to write and handle. For ex: "Empty=White|Filled=Black|Unknown=Gray"

    Your converter should look like this:

    public class SquareConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is string arg && parameter is string str)
            {
                string[] splits = str.Split("|"); // split by the delimiter
                var colorConverter = new ColorConverter(); // required to convert invariant string to color
                foreach (var kv in splits)
                {
                    if(kv.StartsWith(arg, StringComparison.OrdinalIgnoreCase))
                    {
                        var v = kv.Split("=")[1]; // get the value from key-value
                        var color = (Color)colorConverter.ConvertFromInvariantString(v); // convert string to color
                        var brush = new SolidColorBrush(color); // convert color to solid color brush
                        return brush;
                    }
                }
            }
    
            return default;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    in your xaml

    xmlns:c="clr-namespace:WpfApp.Converters"
    
    <Window.Resources>
        <c:SquareConverter x:Key="SquareConverter"/>
    </Window.Resources>
    
    <Rectangle Fill="{Binding Path=Contents.Value,
                              Converter={StaticResource SquareConverter},
                              ConverterParameter='Empty=White|Filled=Black|Unknown=Gray'}"/>