wpf
Waarde- en meerwaardige converters
Zoeken…
parameters
Parameter | Details |
---|---|
waarde | De waarde die wordt geproduceerd door de bindende bron. |
waarden | De waardenmatrix, geproduceerd door de bindende bron. |
TargetType | Het type bindende doeleigenschap. |
parameter | De te gebruiken converterparameter. |
cultuur | De te gebruiken cultuur in de converter. |
Opmerkingen
Wat IValueConverter en IMultiValueConverter zijn
IValueConverter en IMultiValueConverter - interfaces die een manier bieden om een aangepaste logica toe te passen op een binding.
Waar ze nuttig voor zijn
- U hebt een typewaarde, maar u wilt op een manier nulwaarden weergeven en op een andere manier positieve getallen
- U hebt een typewaarde en wilt in het ene geval het element weergeven en in het andere verbergen
- U hebt een numerieke waarde van geld, maar wilt dit als woorden weergeven
- U hebt een numerieke waarde, maar wilt verschillende afbeeldingen weergeven voor afwijkende getallen
Dit zijn enkele van de eenvoudige gevallen, maar er zijn er nog veel meer.
Voor dit soort gevallen kunt u een waardeomzetter gebruiken. Deze kleine klassen, die de IValueConverter-interface of IMultiValueConverter implementeren, werken als tussenpersonen en vertalen een waarde tussen de bron en de bestemming. Dus in elke situatie waarin u een waarde moet transformeren voordat deze zijn bestemming bereikt of weer terug naar de bron, heeft u waarschijnlijk een converter nodig.
Ingebouwde BooleanToVisibilityConverter [IValueConverter]
Converter tussen Boolean en zichtbaarheid. Krijg bool
bij invoer en retourneert Visibility
.
OPMERKING: deze converter bestaat al in de naamruimte 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;
}
}
}
De converter gebruiken
- Definieer bron
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
- Gebruik het als bindend
<Button Visibility="{Binding AllowEditing,
Converter={StaticResource BooleanToVisibilityConverter}}"/>
Converter met eigenschap [IValueConverter]
Laat zien hoe u een eenvoudige converter met parameter via eigenschap maakt en deze vervolgens doorgeeft in de aangifte. Converteer bool
waarde naar Visibility
. Sta geïnverteerde resultaatwaarde toe door de eigenschap Inverted
in te stellen op 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;
}
}
De converter gebruiken
- Definieer naamruimte
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
- Definieer bron
<converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityInvertedConverter"
Inverted="False"/>
- Gebruik het als bindend
<Button Visibility="{Binding AllowEditing, Converter={StaticResource BoolToVisibilityConverter}}"/>
Eenvoudig toevoegen converter [IMultiValueConverter]
Laat zien hoe u een eenvoudige IMultiValueConverter
omzetter maakt en MultiBinding
in xaml gebruikt. Krijg summ van alle waarden voorbij values
array.
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();
}
}
De converter gebruiken
- Definieer naamruimte
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
- Definieer bron
<converters:AddConverter x:Key="AddConverter"/>
- Gebruik het als bindend
<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>
Gebruik converters met ConverterParameter
Laat zien hoe u een eenvoudige converter maakt en ConverterParameter
om de parameter door te geven aan de converter. Waarde vermenigvuldigen met coëfficiënt doorgegeven 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();
}
}
De converter gebruiken
- Definieer naamruimte
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
- Definieer bron
<converters:MultiplyConverter x:Key="MultiplyConverter"/>
- Gebruik het als bindend
<StackPanel Orientation="Vertical">
<TextBox x:Name="TextBox" />
<TextBlock Text="{Binding Path=Text,
ElementName=TextBox,
Converter={StaticResource MultiplyConverter},
ConverterParameter=10}"/>
</StackPanel>
Groepeer meerdere converters [IValueConverter]
Deze converter zal meerdere converters samen ketenen.
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 dit voorbeeld wordt het booleaanse resultaat van EnumToBooleanConverter
gebruikt als invoer in BooleanToVisibilityConverter
.
<local:ValueConverterGroup x:Key="EnumToVisibilityConverter">
<local:EnumToBooleanConverter/>
<local:BooleanToVisibilityConverter/>
</local:ValueConverterGroup>
De knop is alleen zichtbaar wanneer de eigenschap CurrentMode
is ingesteld op Ready
.
<Button Content="Ok" Visibility="{Binding Path=CurrentMode, Converter={StaticResource EnumToVisibilityConverter}, ConverterParameter={x:Static local:Mode.Ready}"/>
MarkupExtension gebruiken met converters om de aangifte van bronnen over te slaan
Gewoonlijk moeten we de converter op de volgende manier definiëren als resource:
<converters:SomeConverter x:Key="SomeConverter"/>
Het is mogelijk om deze stap over te slaan door een converter te definiëren als MarkupExtension
en de methode ProvideValue
. In het volgende voorbeeld wordt een waarde omgezet in negatief:
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;
}
}
}
Met behulp van de converter:
Definieer naamruimte
xmlns: converters = "clr-naamruimte: MyProject.Converters; assemblage = MyProject"
Voorbeeld van gebruik van deze converter in binding
<RichTextBox IsReadOnly="{Binding Path=IsChecked, ElementName=toggleIsEnabled, Converter={converters:Converter_Negative}}"/>
Gebruik IMultiValueConverter om meerdere parameters aan een opdracht door te geven
Het is mogelijk om meerdere gebonden waarden door te geven als een CommandParameter
met behulp van MultiBinding
met een zeer eenvoudige 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()
{
}
}
}
Met behulp van de converter:
Voorbeeldimplementatie - methode aangeroepen wanneer
SomeCommand
wordt uitgevoerd ( opmerking:DelegateCommand
is een implementatie vanICommand
die in dit voorbeeld niet wordt verstrekt ):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])); }
Definieer naamruimte
xmlns: converters = "clr-naamruimte: MyProject.Converters; assemblage = MyProject"
Voorbeeld van gebruik van deze converter in binding
<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>