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

xlpyo6sf  于 2022-12-07  发布在  其他
关注(0)|答案(5)|浏览(207)

我遇到了这样一种情况:需要显示一个整数值,它绑定到数据上下文中的一个属性,然后将其进行两次单独的转换:
1.反转一个范围内的值(如范围是1到100; datacontext中的值为90;用户看到值为10)
1.将数字转换为字符串
我意识到我可以通过创建自己的转换器(实现IValueConverter)来完成这两个步骤。但是,我已经有了一个单独的值转换器,它只完成第一步,第二步由Int32Converter完成。
有没有一种方法可以链接XAML * 中的这两个现有类 *,而不必创建另一个聚合它们的类?
如果我需要澄清任何这一点,请让我知道。:)

  • 谢谢-谢谢
bbmckpt7

bbmckpt71#

我在Silverlight项目中使用了Gareth Evans的this method
下面是我对它的实现:

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

uemypmqf2#

找到了我要找的东西,乔什·史密斯的礼貌:一对一对一
他定义了一个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>

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

zbwhf8kr

zbwhf8kr3#

Gareth Evans's Silverlight projectTown's implementation是伟大的,但它不支持不同的转换器参数。
我修改了它,这样您就可以提供参数,逗号分隔(当然除非您转义它们)。

转换器:

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

flseospp4#

是的,有一些方法可以链接转换器,但是它看起来不太好,你也不需要它。如果你需要它,问问自己这真的是要走的路吗?简单总是更好的工作,即使你必须编写自己的转换器。
在您的特定情况下,您所需要做的就是将转换后的值格式化为字符串。Binding上的StringFormat属性在这里是您的朋友。

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

t98cgbkg5#

下面是Town's answer的一个小扩展,用于支持多绑定:

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
}

相关问题