代码之家  ›  专栏  ›  技术社区  ›  Oleg Sakharov

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

  •  113
  • Oleg Sakharov  · 技术社区  · 16 年前

    我遇到了一种情况,在将一个整数值通过两个独立的转换之后,我需要将它显示出来,并绑定到数据上下文中的一个属性:

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

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

    有没有办法把这两个现有的类连接起来 在XAML中 不需要创建一个进一步的类来聚合它们?

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

    谢谢。

    4 回复  |  直到 8 年前
        1
  •  179
  •   Hakan Fıstık MuriloKunze    9 年前

    我用 this method 我的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>
    
        2
  •  52
  •   Aleksandar Toplek    11 年前

    找到了我想要的东西,由乔希·史密斯提供: Piping Value Converters (archive.org link) .

    他定义了一个 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> 
    

    很棒的东西。谢谢,乔希。:)

        3
  •  6
  •   wpfwannabe    16 年前

    是的,有方法链转换器,但它不好看,你不需要它在这里。如果你需要这个,问问你自己,这真的是一条路吗?即使必须编写自己的转换器,simple也总是能更好地工作。

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

     <TextBlock Text="{Binding Value,Converter={StaticResource myConverter},StringFormat=D}" />
    
        4
  •  5
  •   Trevi Awater    8 年前

    Town's implementation 属于 Gareth Evans's Silverlight project 很好,但是它不支持不同的转换器参数。

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

    转换器:

    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,请参阅 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>
    
    推荐文章