Ricerca…


Parametri

Parametro Dettagli
valore Il valore prodotto dalla sorgente di associazione.
valori La matrice dei valori, prodotta dalla sorgente di associazione.
targetType Il tipo della proprietà target vincolante.
parametro Il parametro del convertitore da usare.
cultura La cultura da utilizzare nel convertitore.

Osservazioni

Cosa sono IValueConverter e IMultiValueConverter

IValueConverter e IMultiValueConverter: interfacce che consentono di applicare una logica personalizzata a un binding.

Per cosa sono utili

  1. Hai un valore di tipo ma vuoi mostrare valori zero in un modo e numeri positivi in ​​un altro modo
  2. Hai un valore di tipo e vuoi mostrare l'elemento in un caso e nasconderlo in un altro
  3. Hai un valore numerico di denaro ma vuoi mostrarlo come parole
  4. Hai un valore numerico ma vuoi mostrare immagini diverse per numeri decrittivi

Questi sono alcuni dei casi semplici, ma ce ne sono molti altri.

Per casi come questo, è possibile utilizzare un convertitore di valori. Queste classi di piccole dimensioni, che implementano l'interfaccia IValueConverter o IMultiValueConverter, fungeranno da intermediari e tradurranno un valore tra l'origine e la destinazione. Pertanto, in qualsiasi situazione in cui è necessario trasformare un valore prima che raggiunga la sua destinazione o di nuovo alla sua origine, è probabile che sia necessario un convertitore.

Build-In BooleanToVisibilityConverter [IValueConverter]

Convertitore tra booleano e visibilità. Ottieni valore bool sull'input e restituisce il valore di Visibility .

NOTA: questo convertitore è già presente nello spazio dei nomi 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;
        }
    }
}

Utilizzando il convertitore

  1. Definisci risorsa
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
  1. Usalo in associazione
<Button Visibility="{Binding AllowEditing, 
                             Converter={StaticResource BooleanToVisibilityConverter}}"/>

Convertitore con proprietà [IValueConverter]

Mostra come creare un convertitore semplice con parametro tramite la proprietà e quindi passarlo nella dichiarazione. Converti valore bool in Visibility . Consenti valore di risultato invertito impostando la proprietà Inverted su 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;
    }
}

Utilizzando il convertitore

  1. Definisci spazio dei nomi

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

  1. Definisci risorsa
<converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityInvertedConverter"
                                         Inverted="False"/>
  1. Usalo in associazione
<Button Visibility="{Binding AllowEditing, Converter={StaticResource BoolToVisibilityConverter}}"/>

Semplice convertitore add [IMultiValueConverter]

Mostra come creare un semplice convertitore IMultiValueConverter e utilizzare MultiBinding in xaml. Ottieni un riepilogo di tutti i valori passati dall'array dei 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();
    }
}

Utilizzando il convertitore

  1. Definisci spazio dei nomi
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
  1. Definisci risorsa
<converters:AddConverter x:Key="AddConverter"/>
  1. Usalo in associazione
<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>

Convertitori di utilizzo con ConverterParameter

Mostra come creare un convertitore semplice e utilizzare ConverterParameter per passare il parametro al convertitore. Moltiplicare il valore per coefficiente passato in 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();
    }
}

Utilizzando il convertitore

  1. Definisci spazio dei nomi
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
  1. Definisci risorsa
<converters:MultiplyConverter x:Key="MultiplyConverter"/>
  1. Usalo in associazione
<StackPanel Orientation="Vertical">
    <TextBox x:Name="TextBox" />
    <TextBlock Text="{Binding Path=Text, 
                              ElementName=TextBox, 
                              Converter={StaticResource MultiplyConverter},
                              ConverterParameter=10}"/>
</StackPanel>

Raggruppa più convertitori [IValueConverter]

Questo convertitore riunirà più convertitori.

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

In questo esempio, il risultato booleano di EnumToBooleanConverter viene utilizzato come input in BooleanToVisibilityConverter .

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

Il pulsante sarà visibile solo quando la proprietà CurrentMode è impostata su Ready .

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

Utilizzo di MarkupExtension con i convertitori per saltare la dichiarazione delle risorse

Solitamente per utilizzare il convertitore, dobbiamo definirlo come risorsa nel modo seguente:

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

È possibile saltare questo passaggio definendo un convertitore come MarkupExtension e implementando il metodo ProvideValue . L'esempio seguente converte un valore in negativo:

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

Utilizzando il convertitore:

  1. Definisci spazio dei nomi

    xmlns: convertitori = "CLR-namespace: MyProject.Converters; assemblaggio = MyProject"

  2. Esempio di utilizzo di questo convertitore in associazione

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

Usa IMultiValueConverter per passare più parametri a un comando

È possibile passare più valori associati come un CommandParameter usando MultiBinding con un IMultiValueConverter molto semplice:

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

Utilizzando il convertitore:

  1. Esempio di implementazione: metodo chiamato quando viene eseguito il SomeCommand ( nota: DelegateCommand è un'implementazione di ICommand che non è fornita in questo esempio ):

     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. Definisci spazio dei nomi

xmlns: convertitori = "CLR-namespace: MyProject.Converters; assemblaggio = MyProject"

  1. Esempio di utilizzo di questo convertitore in associazione

    <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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow