Подтвердить что ты не робот

Преобразователь с несколькими параметрами

Кто-нибудь знает, как использовать конвертер с несколькими параметрами в приложении Windows Phone 7?

Заранее спасибо.

4b9b3361

Ответ 1

Конвертеры всегда реализуют IValueConverter. Это означает, что вызов Convert или ConvertBack передает один дополнительный параметр. Этот параметр извлекается из XAML.

Как предлагает Hitesh Patel, ничто не мешает вам вводить в параметр более одного значения, если у вас есть разделитель для их разделения позже, , но вы не можете использовать запятую, поскольку она разделяет XAML!

например

XAML

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

конвертер

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

Обратите внимание, я не проверял, чтобы увидеть, если pipe "|" символ действителен в XAML (должен быть), но если нет, просто выберите другой символ, который не конфликтует.

Более поздние версии .Net не требуют массива символов для самой простой версии Split, поэтому вы можете использовать это вместо этого:

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

Добавление:

Хитрость, которую eBay использовал в URL много лет назад, заключалась в разделении данных в URL с помощью QQ. Двойной Q не встречается в текстовых данных. Если вы когда-нибудь застряли за разделителем текста, который позволит избежать проблем с кодировкой, просто используйте QQ... Это не будет работать с расщеплением (которое требует одиночных символов, но приятно знать) :)

Ответ 2

Вы всегда можете получить класс DependecyObject и добавить столько DependencyProperties, сколько хотите. Например:

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

И затем в 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}}" />

Ответ 3

Хотя приведенные выше ответы могут быть возможными, они кажутся слишком сложными. Просто используйте IMultiValueConverter с соответствующим MultiBinding в коде XAML. Предполагая, что ваша ViewModel имеет свойства FirstValue, SecondValue и ThirdValue, которые соответственно являются int, double и string, допустимый мультиконвертер может выглядеть следующим образом:

С#

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

Поскольку для этого не требуется ни метод ProvideValue, требуемый для MarkupExtension, ни спецификация DependencyObject внутри (!) преобразователя, я считаю, что это наиболее элегантное решение.

Ответ 4

Это можно сделать с помощью System.Windows.Markup.MarkupExtension (документы).

Это позволит вам передавать значения в конвертер, которые можно использовать в качестве аргументов или возвращаемых значений, например:

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

Использование:

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

Обязательно укажите пространство имен конвертера в .xaml.

Ответ 5

Если ваш ввод не будет работать со строкой, и у вас есть несколько параметров (не привязок). Вы можете просто передать коллекцию. Определите любой тип, необходимый для избежания проблем с редактором пользовательского интерфейса с массивами:

public class BrushCollection : Collection<Brush>
{
}

Затем добавьте XAML, используя коллекцию

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

А затем приведите результат к массиву соответствующего типа в конвертере:

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

        BrushCollection brushes = (BrushCollection)parameter;