在 XAML 中是否有方法链接多个值转换器?

我有一个情况,我需要显示一个整数值,绑定到我的数据上下文中的一个属性,在进行两个单独的转换之后:

  1. 反转范围内的值(例如,范围是1到100; 数据上下文中的值是90; 用户看到的值是10)
  2. 将数字转换为字符串

我意识到我可以通过创建自己的转换器(实现 IValueConverter)来完成这两个步骤。但是,我已经有了一个单独的值转换器,它只执行第一步,第二步由 Int32Converter 负责。

有没有一种方法,我可以链接这两个现有的类 在 XAML 中,而不必创建一个进一步的类,聚合它们?

如果我需要澄清这些,请让我知道。 :)

谢谢。

53363 次浏览

是的,有方法链转换器,但它看起来不漂亮,你不需要它在这里。如果你需要这个,问问你自己这真的是正确的方法吗?即使您必须编写自己的转换器,简单总是能够更好地工作。

在您的特定情况下,您所需要做的就是将转换后的值格式化为字符串。Binding上的 StringFormat属性是你的朋友在这里。

 <TextBlock Text="{Binding Value,Converter={StaticResource myConverter},StringFormat=D}" />

找到我要找的东西了,感谢 Josh Smith: 管道价值转换器 (Archive.org 链接)

他定义了一个 ValueConverterGroup类,该类在 XAML 中的使用正如我所希望的那样:

<!-- 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>

很好,谢谢,乔什

我在 Silverlight 项目中使用了 Gareth Evans 的 这种方法

下面是我的实现方法:

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
}

然后可以像下面这样在 XAML 中使用:

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

Town 对 Gareth Evans 的 Silverlight 项目的 实现非常好,但是它不支持不同的转换器参数。

我修改了它,以便您可以提供参数,逗号分隔(当然,除非您转义它们)。

转换器:

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;
}
}

注意: ConvertBack 在这里没有实现,请参阅我的 要点了解完整版本。

实施方法:

<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>

下面是 镇上的答案的一个小扩展,以支持多绑定:

public class ValueConverterGroup : List<IValueConverter>, IValueConverter, IMultiValueConverter
{
#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();
}


public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return Convert(values as object, targetType, parameter, culture);
}
    

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
    

#endregion
}