有没有办法在XAML中链接多个值转换器?

Mal*_*oss 117 data-binding wpf xaml ivalueconverter

我有一种情况需要显示一个整数值,绑定到我的数据上下文中的属性,然后通过两次单独的转换:

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

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

有没有办法在XAML中链接这两个现有的类而不必创建另一个聚合它们的类?

如果我需要澄清这些,请告诉我.:)

谢谢.

Tow*_*own 188

我在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
}
Run Code Online (Sandbox Code Playgroud)

然后可以在XAML中使用它,如下所示:

<c:ValueConverterGroup x:Key="InvertAndVisibilitate">
   <c:BooleanInverterConverter/>
   <c:BooleanToVisibilityConverter/>
</c:ValueConverterGroup>
Run Code Online (Sandbox Code Playgroud)

  • @DLeh这不是很优雅,因为它不起作用.它为所有转换器提供最终目标类型而不是正确的目标类型... (5认同)
  • 是最好的,对于ConvertBack的实现来制作集合的副本并将其反转,然后对其进行聚合?所以ConvertBack将是`return this.Reverse <IValueConverter>().Aggregate(value,(current,converter)=> converter.ConvertBack(current,targetType,parameter,culture));` (3认同)

Mal*_*oss 53

找到我正在寻找的东西,由Josh Smith提供:Piping Value Converters (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> 
Run Code Online (Sandbox Code Playgroud)

好东西.谢谢,乔希.:)

  • 请发布实施; 否则,linkrot (9认同)
  • 在此解决方案中,每个转换器必须仅处理一种类型(必须在单值ValueConversion属性中声明).@Town解决方案也可以应对多转换器. (2认同)

Tre*_*ter 9

TownGareth 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:此处未实现ConvertBack,请参阅我的Gist了解完整版.

执行:

<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>
Run Code Online (Sandbox Code Playgroud)

  • 做得好,最完整的答案在这里。 (2认同)

wpf*_*abe 6

是的,有链接转换器的方法,但它看起来不漂亮,你不需要它.如果你曾经需要这个,那么问问自己这是真的要走的路吗?即使你必须编写自己的转换器,简单总是更好.

在您的特定情况下,您需要做的就是将转换后的值格式化为字符串.StringFormata上的房产Binding是你的朋友.

 <TextBlock Text="{Binding Value,Converter={StaticResource myConverter},StringFormat=D}" />
Run Code Online (Sandbox Code Playgroud)

  • 如果你大量使用绑定,那么将自定义转换器写入链式转换器会导致大量的哑转换器出现在各种配置中.在这种情况下,接受的答案是一个很好的解决方案 (4认同)