wpf
Wert- und Multivalue-Konverter
Suche…
Parameter
Parameter | Einzelheiten |
---|---|
Wert | Der von der Bindungsquelle erzeugte Wert. |
Werte | Das Werte-Array, das von der Bindungsquelle erzeugt wird. |
targetType | Der Typ der Bindungszieleigenschaft. |
Parameter | Der zu verwendende Konverter-Parameter. |
Kultur | Die im Konverter zu verwendende Kultur. |
Bemerkungen
Was sind IValueConverter und IMultiValueConvertert
IValueConverter und IMultiValueConverter - Schnittstellen, mit denen eine benutzerdefinierte Logik auf eine Bindung angewendet werden kann.
Wofür sind sie nützlich?
- Sie haben einen Typwert, möchten aber Nullwerte auf eine Art und positive Zahlen auf andere Weise anzeigen
- Sie haben einen Typwert und möchten ein Element in einem Fall anzeigen und in einem anderen ausblenden
- Sie haben einen numerischen Geldwert, möchten ihn aber als Wörter anzeigen
- Sie haben einen numerischen Wert, möchten jedoch unterschiedliche Bilder für andere Nummern anzeigen
Dies sind einige der einfachen Fälle, aber es gibt noch viele mehr.
Für diesen Fall können Sie einen Wertkonverter verwenden. Diese kleinen Klassen, die die IValueConverter-Schnittstelle oder IMultiValueConverter implementieren, fungieren als Zwischenhändler und übersetzen einen Wert zwischen Quelle und Ziel. In einer Situation, in der Sie einen Wert transformieren müssen, bevor er sein Ziel erreicht oder wieder zu seiner Quelle zurückkehrt, benötigen Sie wahrscheinlich einen Konverter.
Build-In BooleanToVisibilityConverter [IValueConverter]
Konverter zwischen Boolean und Sichtbarkeit. Holen Sie sich einen bool
Wert für die Eingabe und gibt den Visibility
.
HINWEIS: Dieser Konverter ist bereits im Namespace 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;
}
}
}
Verwendung des Konverters
- Ressource definieren
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
- Verwenden Sie es verbindlich
<Button Visibility="{Binding AllowEditing,
Converter={StaticResource BooleanToVisibilityConverter}}"/>
Konverter mit Eigenschaft [IValueConverter]
Zeigen Sie, wie Sie einen einfachen Konverter mit einem Parameter über die Eigenschaft erstellen, und übergeben Sie ihn in der Deklaration. Konvertieren Sie den bool
Wert in Visibility
. Erlauben Sie den invertierten Ergebniswert, indem Sie die Inverted
Eigenschaft auf 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;
}
}
Verwendung des Konverters
- Namensraum definieren
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
- Ressource definieren
<converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityInvertedConverter"
Inverted="False"/>
- Verwenden Sie es verbindlich
<Button Visibility="{Binding AllowEditing, Converter={StaticResource BoolToVisibilityConverter}}"/>
Einfacher Add-Converter [IMultiValueConverter]
Zeigen Sie, wie Sie einen einfachen IMultiValueConverter
Konverter erstellen und MultiBinding
in xaml verwenden. Holen Sie sich die Summe aller Werte, die vom values
Array übergeben werden.
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();
}
}
Verwendung des Konverters
- Namensraum definieren
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
- Ressource definieren
<converters:AddConverter x:Key="AddConverter"/>
- Verwenden Sie es verbindlich
<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>
Nutzungskonverter mit ConverterParameter
Zeigen Sie, wie Sie einen einfachen Konverter erstellen und mit ConverterParameter
Parameter an den Konverter übergeben. Multiplizieren Sie den Wert mit dem in ConverterParameter übergebenen Koeffizienten.
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();
}
}
Verwendung des Konverters
- Namensraum definieren
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
- Ressource definieren
<converters:MultiplyConverter x:Key="MultiplyConverter"/>
- Verwenden Sie es verbindlich
<StackPanel Orientation="Vertical">
<TextBox x:Name="TextBox" />
<TextBlock Text="{Binding Path=Text,
ElementName=TextBox,
Converter={StaticResource MultiplyConverter},
ConverterParameter=10}"/>
</StackPanel>
Mehrere Konverter gruppieren [IValueConverter]
Dieser Konverter kettet mehrere Konverter zusammen.
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 diesem Beispiel wird das boolesche Ergebnis von EnumToBooleanConverter
als Eingabe in BooleanToVisibilityConverter
.
<local:ValueConverterGroup x:Key="EnumToVisibilityConverter">
<local:EnumToBooleanConverter/>
<local:BooleanToVisibilityConverter/>
</local:ValueConverterGroup>
Die Schaltfläche ist nur sichtbar, wenn die CurrentMode
Eigenschaft auf Ready
.
<Button Content="Ok" Visibility="{Binding Path=CurrentMode, Converter={StaticResource EnumToVisibilityConverter}, ConverterParameter={x:Static local:Mode.Ready}"/>
Verwendung von MarkupExtension mit Konvertern zum Überspringen der Deklaration der Ressource
Um den Konverter zu verwenden, müssen Sie ihn normalerweise wie folgt als Ressource definieren:
<converters:SomeConverter x:Key="SomeConverter"/>
Sie können diesen Schritt überspringen, indem Sie einen Konverter als MarkupExtension
und die Methode ProvideValue
. Im folgenden Beispiel wird ein Wert in einen negativen Wert konvertiert:
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;
}
}
}
Verwendung des Konverters:
Namensraum definieren
xmlns: converters = "clr-namespace: MyProject.Converters; assembly = MyProject"
Beispiel Verwendung dieses Konverters in der Bindung
<RichTextBox IsReadOnly="{Binding Path=IsChecked, ElementName=toggleIsEnabled, Converter={converters:Converter_Negative}}"/>
Verwenden Sie IMultiValueConverter, um mehrere Parameter an einen Befehl zu übergeben
Es ist möglich, mehrere gebundene Werte als CommandParameter
mit MultiBinding
mit einem sehr einfachen 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()
{
}
}
}
Verwendung des Konverters:
Beispielimplementierung - Methode, die aufgerufen wird, wenn
SomeCommand
ausgeführt wird ( Hinweis:DelegateCommand
ist eine Implementierung vonICommand
, die in diesem Beispiel nicht bereitgestellt wird ):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])); }
Namensraum definieren
xmlns: converters = "clr-namespace: MyProject.Converters; assembly = MyProject"
Beispiel Verwendung dieses Konverters in der Bindung
<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>