我有一种情况需要在通过两次单独的转换后显示一个整数值,绑定到我的数据上下文中的属性:
我意识到我可以通过创建自己的转换器(实现IValueConverter)来完成这两个步骤。但是,我已经有一个单独的值转换器,只执行第一步,第二步由Int32Converter覆盖。
有没有办法可以在XAML 中链接这两个现有的类而无需创建另一个聚合它们的类?
如果我需要澄清其中任何一项,请告诉我。 :)
感谢。
答案 0 :(得分:182)
我在我的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>
答案 1 :(得分:52)
找到我正在寻找的东西,由Josh Smith提供: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>
好东西。谢谢,乔希。 :)
答案 2 :(得分:6)
是的,有链接转换器的方法,但它看起来不漂亮,你不需要它。如果你曾经需要这个,那么问问自己这是真的要走的路吗?即使你必须编写自己的转换器,简单总是更好。
在您的特定情况下,您需要做的就是将转换后的值格式化为字符串。 Binding
上的StringFormat
属性是您的朋友。
<TextBlock Text="{Binding Value,Converter={StaticResource myConverter},StringFormat=D}" />
答案 3 :(得分:6)
我修改了它,所以你可以提供参数,用逗号分隔(除非你当然要逃避它们)。
<强>转换器:强>
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>
答案 4 :(得分:0)
这里是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
}