wake-up-neo.net

Konverter mit mehreren Parametern

Kann jemand einen Konverter mit mehreren Parametern in einer Windows Phone 7-Anwendung verwenden?

Danke im Voraus.

23
Harshad Bhola

Konverter implementieren immer IValueConverter . Das heißt, ein Aufruf von Convert oder ConvertBack gibt einen einzelnen zusätzlichen Parameter weiter. Dieser Parameter wird aus der XAML extrahiert.

Wie Hitesh Patel andeutet, gibt es nichts, was Sie daran hindern kann, mehr als einen Wert in den Parameter einzufügen, solange Sie ein Trennzeichen haben, um sie später zu trennen,, aber Sie können kein Komma verwenden, da dies die XAML begrenzt!

z.B. 

XAML

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

Konverter

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

Beachten Sie, ich habe es nicht geprüft, um zu sehen, ob ein Pipe "|" - Zeichen in XAML gültig ist (sollte sein), aber wenn Sie nicht einfach ein anderes Zeichen auswählen, das nicht kollidiert.

In späteren Versionen von .Net ist kein Zeichenarray für die einfachste Version von Split erforderlich. Daher können Sie stattdessen Folgendes verwenden:

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

Nachtrag:

Ein Trick, den eBay vor Jahren in URLs verwendete, war die Eingrenzung der Daten in der URL mit QQ. In Textdaten kommt natürlich kein Doppel-Q vor. Wenn Sie jemals an einem Textbegrenzer hängen bleiben, der Codierungsprobleme vermeidet, verwenden Sie einfach QQ ... Dies funktioniert jedoch nicht mit Split (was einzelne Zeichen erfordert, aber es ist gut zu wissen) :)

44
Gone Coding

Sie können immer von der DependecyObject-Klasse ableiten und beliebig viele DependencyProperties hinzufügen. Zum Beispiel:

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();
    }
}

Und dann in 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

Obgleich die obigen Antworten möglich sind, scheinen sie zu kompliziert zu sein. Verwenden Sie einfach eine IMultiValueConverter mit einer entsprechenden MultiBinding im XAML-Code. Angenommen, Ihr ViewModel verfügt über die Eigenschaften FirstValue, SecondValue und ThirdValue, die eine int, eine double und eine string sind. Ein gültiger Multi-Konverter könnte folgendermaßen aussehen:

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>

Da es weder mit der von ProvideValue erforderlichen MarkupExtension-Methode fummeln muss, noch mit der Angabe eines DependencyObject inside (!) Eines Konverters, denke ich, dass dies die eleganteste Lösung ist.

2
Informagic

Wenn Ihre Eingabe mit einer Zeichenfolge nicht funktioniert und Sie mehrere Parameter (keine Bindungen) haben. Sie können einfach eine Sammlung übergeben. Definieren Sie einen beliebigen Typ, um Probleme mit dem UI-Editor bei Arrays zu vermeiden:

public class BrushCollection : Collection<Brush>
{
}

Fügen Sie dann die XAML mithilfe der Auflistung hinzu

                <TextBox.Background >
                    <Binding Path="HasInitiativeChanged" Converter="{StaticResource changedToBrushConverter}">
                        <Binding.ConverterParameter>
                            <local:BrushCollection>
                                <SolidColorBrush Color="{DynamicResource ThemeTextBackground}"/>
                                <SolidColorBrush Color="{DynamicResource SecondaryColorBMedium}"/>
                            </local:BrushCollection>
                        </Binding.ConverterParameter>
                    </Binding>

                </TextBox.Background>

Und wandeln Sie das Ergebnis dann in ein Array des entsprechenden Typs im Konverter um:

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {

        BrushCollection brushes = (BrushCollection)parameter;
1
Kyle Olson

Dies kann mit System.Windows.Markup.MarkupExtension ( docs ) erfolgen.

Dadurch können Sie Werte an den Konverter übergeben, die als Argumente oder Rückgabewerte verwendet werden können, beispielsweise:

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();
    }
}

Verwendungszweck:

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

Stellen Sie sicher, dass Sie den Namespace des Konverters im .xaml angeben.

1
Alfie