J'ai une situation dans laquelle j'ai besoin d'afficher une valeur entière, liée à une propriété sur mon contexte de données, après l'avoir mise à travers deux conversions distinctes:
Je me rends compte que je pourrais faire les deux étapes en créant mon propre convertisseur (qui implémente IValueConverter). Cependant, j'ai déjà un convertisseur de valeur séparé qui ne fait que la première étape, et la deuxième étape est couverte par Int32Converter.
Existe-t-il un moyen de chaîner ces deux classes existantes en XAML sans avoir à créer une autre classe qui les agrège?
Si j'ai besoin de clarifier tout cela, faites-le moi savoir. :)
Merci.
J'ai utilisé cette méthode par Gareth Evans dans mon projet Silverlight.
Voici ma mise en œuvre de celui-ci:
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
}
Qui peut ensuite être utilisé en XAML comme ceci:
<c:ValueConverterGroup x:Key="InvertAndVisibilitate">
<c:BooleanInverterConverter/>
<c:BooleanToVisibilityConverter/>
</c:ValueConverterGroup>
Trouvé exactement ce que je cherchais, gracieuseté de Josh Smith: Piping Value Converters(lien archive.org) .
Il définit une classe ValueConverterGroup
, dont l'utilisation en XAML est exactement celle que j'espérais. Voici un exemple:
<!-- 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>
Super truc. Merci, Josh. :)
implémentation de Town of projet Silverlight de Gareth Evans est génial, mais il ne prend pas en charge différents paramètres de convertisseur.
Je l'ai modifié pour que vous puissiez fournir des paramètres délimités par des virgules (sauf si vous y échappez bien sûr).
Convertisseur:
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;
}
}
Remarque: ConvertBack n'est pas implémenté ici, voir mon Gist pour la version complète.
Implémentation:
<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>
Oui, il existe des moyens de chaîner les convertisseurs, mais cela n'a pas l'air joli et vous n'en avez pas besoin ici. Si jamais vous en avez besoin, demandez-vous si c'est vraiment la voie à suivre? Simple fonctionne toujours mieux même si vous devez écrire votre propre convertisseur.
Dans votre cas particulier, il vous suffit de formater une valeur convertie en chaîne. StringFormat
propriété sur un Binding
est votre ami ici.
<TextBlock Text="{Binding Value,Converter={StaticResource myConverter},StringFormat=D}" />