web-dev-qa-db-fra.com

Convertisseur avec plusieurs paramètres

Est-ce que quelqu'un sait comment utiliser le convertisseur avec plusieurs paramètres dans une application Windows Phone 7?

Merci d'avance.

23
Harshad Bhola

Les convertisseurs implémentent toujours IValueConverter . Cela signifie qu'un appel à Convert ou ConvertBack transmet un seul paramètre supplémentaire. Ce paramètre est extrait du XAML.

Comme Hitesh Patel le suggère, rien ne vous empêche de mettre plus d'une valeur dans le paramètre, tant que vous avez un délimiteur pour les séparer plus tard, mais vous ne pouvez pas utiliser de virgule car cela délimite le XAML!

par exemple. 

XAML

<TextBlock Text="{Binding Path=ReleaseDate, Mode=OneWay,
                        Converter={StaticResource MyConverter}, 
                        ConverterParameter=Param1|Param2}" />

Convertisseur

public object Convert(object value, Type targetType, object parameter,
    System.Globalization.CultureInfo culture)
{
    string parameterString = parameter as string;
    if (!string.IsNullOrEmpty(parameterString))
    {
        string[] parameters = parameterString.Split(new char[]{'|'});
        // Now do something with the parameters
    }
}

Remarque, je ne l'ai pas vérifié pour voir si un caractère Pipe "|" est valide dans XAML (devrait l'être), mais sinon, choisissez simplement un autre caractère qui ne soit pas en conflit.

Les versions ultérieures de .Net ne nécessitent pas de tableau de caractères pour la version la plus simple de Split, vous pouvez donc utiliser ceci à la place:

string[] parameters = parameterString.Split('|');

Addenda:

Il y a des années, eBay avait l'habitude d'utiliser des astuces pour délimiter les données dans l'URL avec QQ. Un double-Q ne se produit pas naturellement dans les données de texte. Si jamais vous vous retrouvez coincé pour un délimiteur de texte évitant les problèmes d’encodage, utilisez simplement QQ ... Cela ne fonctionnera pas avec split (cela nécessite des caractères uniques, mais bon à savoir) :)

44
Gone Coding

Vous pouvez toujours dériver de la classe DependecyObject et ajouter autant de DependencyProperties que vous le souhaitez. Par exemple:

ExampleConverter.cs

public class ExampleConverter : DependencyObject, IValueConverter
{
    public string Example
    {
        get => GetValue(ExampleProperty).ToString();
        set => SetValue(ExampleProperty, value);
    }
    public static readonly DependencyProperty ExampleProperty =
        DependencyProperty.Register("Example", typeof(string), typeof(ExampleConverter), new PropertyMetadata(null));

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        //Do the convert
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Et puis en XAML:

ExampleView.xaml

<ResourceDictionary>
    <converters:ExampleConverter x:Key="ExampleConverter" Example="{Binding YourSecondParam}"/>
</ResourceDictionary>
...
<TextBlock Text="{Binding Path=ReleaseDate, Mode=OneWay,
                    Converter={StaticResource ExampleConverter}, 
                    ConverterParameter={Binding YourFirstParam}}" />
10
Kamil Stadryniak

Bien que les réponses ci-dessus puissent être réalisables, elles semblent trop compliquées. Utilisez simplement une IMultiValueConverter avec une MultiBinding appropriée dans le code XAML. En supposant que votre ViewModel ait les propriétés FirstValue, SecondValue et ThirdValue, qui sont respectivement une int, une double et une string, un convertisseur multiple valide pourrait ressembler à ceci:

C #

public class MyMultiValueConverter : IMultiValueConverter {
  public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
    int firstValue = (int)values[0];
    double secondValue = (double)values[1];
    string thirdValue = (string)values[2];

    return "You said " + thirdValue + ", but it's rather " + firstValue * secondValue;
  }

  public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) {
    throw new NotImplementedException("Going back to what you had isn't supported.");
  }
}

XAML

<TextBlock.Text>
  <MultiBinding Converter="{StaticResource myNs:MyMultiValueConverter}">
    <Binding Path="FirstValue" />
    <Binding Path="SecondValue" />
    <Binding Path="ThirdValue" />
  </MultiBinding>
</TextBlock.Text>

Puisqu'il ne nécessite ni de manipuler la méthode ProvideValue requise par MarkupExtension, ni de spécifier un convertisseur DependencyObject inside (!), Je pense que c'est la solution la plus élégante.

2
Informagic

Cela peut être fait en utilisant System.Windows.Markup.MarkupExtension ( docs ).

Cela vous permettra de transmettre au convertisseur des valeurs qui pourraient être utilisées comme arguments ou valeurs de retour, par exemple:

public class CustomNullToVisibilityConverter : MarkupExtension, IValueConverter
{
    public object NullValue { get; set; }
    public object NotNullValue { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null) return NullValue;

        return NotNullValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Usage:

...
Visibility="{Binding Property, Converter={cnv:CustomNullToVisibilityConverter NotNullValue=Visible, NullValue=Collapsed}}" />
...

Assurez-vous de référencer l'espace de noms du convertisseur dans le .xaml.

1
Alfie