Поиск…


параметры

параметр подробности
значение Значение, полученное источником связывания.
ценности Массив значений, созданный источником связывания.
TargetType Тип целевого свойства привязки.
параметр Используемый параметр преобразователя.
культура Культура для использования в конвертере.

замечания

Что такое IValueConverter и IMultiValueConverterthey

IValueConverter и IMultiValueConverter - интерфейсы, которые обеспечивают способ применения пользовательской логики к привязке.

Что они полезны для

  1. У вас есть какое-то значение типа, но вы хотите показать нулевые значения одним способом и положительные числа по-другому
  2. У вас есть какое-то значение типа и вы хотите показать элемент в одном случае и спрятать в другом
  3. У вас есть числовое значение денег, но вы хотите показать это как слова
  4. У вас есть числовое значение, но вы хотите показать разные изображения для дефрантных чисел

Это некоторые из простых случаев, но их гораздо больше.

Для таких случаев вы можете использовать преобразователь значений. Эти небольшие классы, которые реализуют интерфейс IValueConverter или IMultiValueConverter, будут действовать как посредники и переводят значение между источником и пунктом назначения. Таким образом, в любой ситуации, когда вам нужно преобразовать значение до того, как оно снова достигнет цели или вернется к его источнику, вам, вероятно, понадобится конвертер.

Встроенный BooleanToVisibilityConverter [IValueConverter]

Конвертер между булевым и видимым. Получить значение bool для ввода и Visibility значение Visibility .

ПРИМЕЧАНИЕ. Этот конвертер уже существует в System.Windows.Controls имен System.Windows.Controls .

public sealed class BooleanToVisibilityConverter : IValueConverter
{
    /// <summary>
    /// Convert bool or Nullable bool to Visibility
    /// </summary>
    /// <param name="value">bool or Nullable bool</param>
    /// <param name="targetType">Visibility</param>
    /// <param name="parameter">null</param>
    /// <param name="culture">null</param>
    /// <returns>Visible or Collapsed</returns>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool bValue = false;
        if (value is bool)
        {
            bValue = (bool)value;
        }
        else if (value is Nullable<bool>)
        {
            Nullable<bool> tmp = (Nullable<bool>)value;
            bValue = tmp.HasValue ? tmp.Value : false;
        }
        return (bValue) ? Visibility.Visible : Visibility.Collapsed;
    }

    /// <summary>
    /// Convert Visibility to boolean
    /// </summary>
    /// <param name="value"></param>
    /// <param name="targetType"></param>
    /// <param name="parameter"></param>
    /// <param name="culture"></param>
    /// <returns></returns>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is Visibility)
        {
            return (Visibility)value == Visibility.Visible;
        }
        else
        {
            return false;
        }
    }
}

Использование преобразователя

  1. Определить ресурс
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
  1. Используйте его в привязке
<Button Visibility="{Binding AllowEditing, 
                             Converter={StaticResource BooleanToVisibilityConverter}}"/>

Конвертер с свойством [IValueConverter]

Покажите, как создать простой конвертер с параметром через свойство, а затем передать его в объявлении. Преобразование значения bool в Visibility . Разрешить инвертировать значение результата, установив Inverted свойство в значение True .

public class BooleanToVisibilityConverter : IValueConverter
{
    public bool Inverted { get; set; }

    /// <summary>
    /// Convert bool or Nullable bool to Visibility
    /// </summary>
    /// <param name="value">bool or Nullable bool</param>
    /// <param name="targetType">Visibility</param>
    /// <param name="parameter">null</param>
    /// <param name="culture">null</param>
    /// <returns>Visible or Collapsed</returns>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool bValue = false;
        if (value is bool)
        {
            bValue = (bool)value;
        }
        else if (value is Nullable<bool>)
        {
            Nullable<bool> tmp = (Nullable<bool>)value;
            bValue = tmp ?? false;
        }

        if (Inverted)
            bValue = !bValue;
        return (bValue) ? Visibility.Visible : Visibility.Collapsed;
    }

    /// <summary>
    /// Convert Visibility to boolean
    /// </summary>
    /// <param name="value"></param>
    /// <param name="targetType"></param>
    /// <param name="parameter"></param>
    /// <param name="culture"></param>
    /// <returns>True or False</returns>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is Visibility)
        {
            return ((Visibility) value == Visibility.Visible) && !Inverted;
        }

        return false;
    }
}

Использование преобразователя

  1. Определение пространства имен

xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"

  1. Определить ресурс
<converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityInvertedConverter"
                                         Inverted="False"/>
  1. Используйте его в привязке
<Button Visibility="{Binding AllowEditing, Converter={StaticResource BoolToVisibilityConverter}}"/>

Простой добавочный конвертер [IMultiValueConverter]

Покажите, как создать простой конвертер IMultiValueConverter и использовать MultiBinding в xaml. Получите суммирование всех значений, переданных массивом values .

public class AddConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        decimal sum = 0M;

        foreach (string value in values)
        {
            decimal parseResult;
            if (decimal.TryParse(value, out parseResult))
            {
                sum += parseResult;
            }
        }

        return sum.ToString(culture);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

Использование преобразователя

  1. Определение пространства имен
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
  1. Определить ресурс
<converters:AddConverter x:Key="AddConverter"/>
  1. Используйте его в привязке
<StackPanel Orientation="Vertical">
    <TextBox x:Name="TextBox" />
    <TextBox x:Name="TextBox1" />
    <TextBlock >
        <TextBlock.Text>
            <MultiBinding Converter="{StaticResource AddConverter}">
                <Binding Path="Text" ElementName="TextBox"/>
                <Binding Path="Text" ElementName="TextBox1"/>
            </MultiBinding>
         </TextBlock.Text>
    </TextBlock>
</StackPanel>

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

Покажите, как создать простой конвертер и использовать ConverterParameter для передачи параметра в конвертер. Значение умножения по коэффициенту, переданному в ConverterParameter.

public class MultiplyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return 0;

        if (parameter == null)
            parameter = 1;

        double number;
        double coefficient;

        if (double.TryParse(value.ToString(), out number) && double.TryParse(parameter.ToString(), out coefficient))
        {
            return number * coefficient;
        }

        return 0;
    }

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

Использование преобразователя

  1. Определение пространства имен
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
  1. Определить ресурс
<converters:MultiplyConverter x:Key="MultiplyConverter"/>
  1. Используйте его в привязке
<StackPanel Orientation="Vertical">
    <TextBox x:Name="TextBox" />
    <TextBlock Text="{Binding Path=Text, 
                              ElementName=TextBox, 
                              Converter={StaticResource MultiplyConverter},
                              ConverterParameter=10}"/>
</StackPanel>

Групповые мультиконвертеры [IValueConverter]

Этот преобразователь объединяет несколько преобразователей.

public class ValueConverterGroup : List<IValueConverter>, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return this.Aggregate(value, (current, converter) => converter.Convert(current, targetType, parameter, culture));
    }

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

В этом примере логический результат из EnumToBooleanConverter используется в качестве входа в BooleanToVisibilityConverter .

<local:ValueConverterGroup x:Key="EnumToVisibilityConverter">
    <local:EnumToBooleanConverter/>
    <local:BooleanToVisibilityConverter/>
</local:ValueConverterGroup>

Кнопка будет видна только тогда, когда для свойства CurrentMode установлено значение « Ready .

<Button Content="Ok" Visibility="{Binding Path=CurrentMode, Converter={StaticResource EnumToVisibilityConverter}, ConverterParameter={x:Static local:Mode.Ready}"/>

Использование MarkupExtension с конвертерами для пропуска декларации ресурсов

Обычно для использования конвертера мы должны определить его как ресурс следующим образом:

<converters:SomeConverter x:Key="SomeConverter"/>

Этот шаг можно пропустить, MarkupExtension преобразователь как MarkupExtension и реализуя метод ProvideValue . Следующий пример преобразует значение в отрицательный:

namespace MyProject.Converters
{
public class Converter_Negative : MarkupExtension, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return this.ReturnNegative(value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return this.ReturnNegative(value);
    }

    private object ReturnNegative(object value)
    {
        object result = null;
        var @switch = new Dictionary<Type, Action> {
            { typeof(bool), () => result=!(bool)value },
            { typeof(byte), () => result=-1*(byte)value },
            { typeof(short), () => result=-1*(short)value },
            { typeof(int), () => result=-1*(int)value },
            { typeof(long), () => result=-1*(long)value },
            { typeof(float), () => result=-1f*(float)value },
            { typeof(double), () => result=-1d*(double)value },
            { typeof(decimal), () => result=-1m*(decimal)value }
        };

        @switch[value.GetType()]();
        if (result == null) throw new NotImplementedException();
        return result;
    }

    public Converter_Negative()
        : base()
    {
    }

    private static Converter_Negative _converter = null;

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (_converter == null) _converter = new Converter_Negative();
        return _converter;
    }
}
}

Использование преобразователя:

  1. Определение пространства имен

    Xmlns: преобразователи = "CLR-имена: MyProject.Converters; сборка = MyProject"

  2. Пример использования этого конвертера в привязке

    <RichTextBox IsReadOnly="{Binding Path=IsChecked, ElementName=toggleIsEnabled, Converter={converters:Converter_Negative}}"/>
    

Используйте IMultiValueConverter для передачи нескольких параметров команде

В качестве параметра CommandParameter использовать несколько связанных значений с помощью MultiBinding с очень простым IMultiValueConverter :

namespace MyProject.Converters
{
    public class Converter_MultipleCommandParameters : MarkupExtension, IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            return values.ToArray();
        }
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }

        private static Converter_MultipleCommandParameters _converter = null;

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (_converter == null) _converter = new Converter_MultipleCommandParameters();
            return _converter;
        }

        public Converter_MultipleCommandParameters()
            : base()
        {
        }
    }
}

Использование преобразователя:

  1. Пример реализации - метод, вызываемый при выполнении SomeCommand ( примечание: DelegateCommand - это реализация ICommand которая не представлена ​​в этом примере ):

     private ICommand _SomeCommand;
     public ICommand SomeCommand
     {
         get { return _SomeCommand ?? (_SomeCommand = new DelegateCommand(a => OnSomeCommand(a))); }
     }
    
     private void OnSomeCommand(object item)
     {
         object[] parameters = item as object[];
    
         MessageBox.Show(
             string.Format("Execute command: {0}\nParameter 1: {1}\nParamter 2: {2}\nParamter 3: {3}",
             "SomeCommand", parameters[0], parameters[1], parameters[2]));
     }
    
  2. Определение пространства имен

Xmlns: преобразователи = "CLR-имена: MyProject.Converters; сборка = MyProject"

  1. Пример использования этого конвертера в привязке

    <Button Width="150" Height="23" Content="Execute some command" Name="btnTestSomeCommand"
         Command="{Binding Path=SomeCommand}" >
         <Button.CommandParameter>
             <MultiBinding Converter="{converters:Converter_MultipleCommandParameters}">
                 <Binding RelativeSource="{RelativeSource Self}" Path="IsFocused"/>
                 <Binding RelativeSource="{RelativeSource Self}" Path="Name"/>
                 <Binding RelativeSource="{RelativeSource Self}" Path="ActualWidth"/>
             </MultiBinding>
         </Button.CommandParameter>
     </Button>
    


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow