Is there a way to chain multiple value converters in XAML? Is there a way to chain multiple value converters in XAML? wpf wpf

Is there a way to chain multiple value converters in XAML?


I used this method by Gareth Evans in my Silverlight project.

Here's my implementation of it:

public class ValueConverterGroup : List<IValueConverter>, IValueConverter{    #region IValueConverter Members    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)    {        return this.Aggregate(value, (current, converter) => converter.Convert(current, targetType, parameter, culture));    }    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)    {        throw new NotImplementedException();    }    #endregion}

Which can then be used in XAML like this:

<c:ValueConverterGroup x:Key="InvertAndVisibilitate">   <c:BooleanInverterConverter/>   <c:BooleanToVisibilityConverter/></c:ValueConverterGroup>


Found exactly what I was looking for, courtesy of Josh Smith: Piping Value Converters (archive.org link).

He defines a ValueConverterGroup class, whose use in XAML is exactly as I was hoping for. Here's an example:

<!-- Converts the Status attribute text to a SolidColorBrush used to draw      the output of statusDisplayNameGroup. --><local:ValueConverterGroup x:Key="statusForegroundGroup">  <local:IntegerStringToProcessingStateConverter  />  <local:ProcessingStateToColorConverter />  <local:ColorToSolidColorBrushConverter /></local:ValueConverterGroup> 

Great stuff. Thanks, Josh. :)


Town's implementation of Gareth Evans's Silverlight project is great, however it does not support different converter parameters.

I modified it so you can provide parameters, comma delimited (unless you escape them of course).

Converter:

public class ValueConverterGroup : List<IValueConverter>, IValueConverter{    private string[] _parameters;    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)    {        if(parameter != null)            _parameters = Regex.Split(parameter.ToString(), @"(?<!\\),");        return (this).Aggregate(value, (current, converter) => converter.Convert(current, targetType, GetParameter(converter), culture));    }    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)    {        throw new NotImplementedException();    }    private string GetParameter(IValueConverter converter)    {        if (_parameters == null)            return null;        var index = IndexOf(converter as IValueConverter);        string parameter;        try        {            parameter = _parameters[index];        }        catch (IndexOutOfRangeException ex)        {            parameter = null;        }        if (parameter != null)            parameter = Regex.Unescape(parameter);        return parameter;    }}

Note: ConvertBack is not implemented here, see my Gist for the full version.

Implementation:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:converters="clr-namespace:ATXF.Converters;assembly=ATXF" x:Class="ATXF.TestPage">  <ResourceDictionary>    <converters:ValueConverterGroup x:Key="converters">      <converters:ConverterOne />      <converters:ConverterTwo />    </converters:ValueConverterGroup>  </ResourceDictionary>  <Label Text="{Binding InitialValue, Converter={StaticResource converters}, ConverterParameter='Parameter1,Parameter2'}" /></ContentPage>