WpfMart 1.0.1
dotnet add package WpfMart --version 1.0.1
NuGet\Install-Package WpfMart -Version 1.0.1
<PackageReference Include="WpfMart" Version="1.0.1" />
paket add WpfMart --version 1.0.1
#r "nuget: WpfMart, 1.0.1"
// Install WpfMart as a Cake Addin #addin nuget:?package=WpfMart&version=1.0.1 // Install WpfMart as a Cake Tool #tool nuget:?package=WpfMart&version=1.0.1
WpfMart
A set of WPF helpers and utilities such as value converters, markup-extensions, behaviors, etc.
GitHub Source Code Repo.
WpfMart NuGet Package.
Table of content
- Markup extensions
- Value Converters
- Multi Value Converters
Markup-extensions
Casting markup-extension
WpfMart.Markup.CastExtension
WpfMart.Markup.IntExtension
WpfMart.Markup.DoubleExtension
WpfMart.Markup.LongExtension
WpfMart.Markup.LongExtension
WpfMart.Markup.DateTimeExtension
WpfMart.Markup.TimeSpanExtension
WpfMart.Markup.CharExtension
WpfMart.Markup.BoolExtension
Provides type conversion to the specified type, mainly from a string written in XAML.
Used as shorthand for writing values of primitive type in XAML in places the expected type is System.Object
.
Please note that it's not necessary to do any casting when assigning to a Property of the desired type.
<ComboBox SelectedIndex="1" />
<ComboBox SelectedIndex="{z:Int 1}" />
<ComboBox Tag="{z:Int 1}" />
<ComboBox Tag="1" />
The CastExtension
is used by specifying its target type either through constructor or its ToType property.
Whenever possible use the more specific cast markups such as
BoolExtension
,IntExtension
,DoubleExtension
, etc. instead of the general purposeCastExtension
<Control><Control.Tag><sys:Int32>-1</sys:Int32></Control.Tag></Control>
<Control Tag="{z:Int -1}" />
<ContentControl><ContentControl.Content><sys:Double>0.5</sys:Double></ContentControl.Content></ContentControl>
<ContentControl Content="{z:Double 0.5}" />
<ContentControl><ContentControl.Content><sysio:SeekOrigin>-1</sysio:SeekOrigin></ContentControl.Content></ContentControl>
<ContentControl Content="{z:Cast -1, sysio:SeekOrigin}" />
<ContentControl Content="{z:Cast en-us, globalization:CultureInfo}" />
EnumValues markup-extension
WpfMart.Markup.EnumValuesExtension
Provides Enum's values for the provided Enum type.
<ComboBox ItemsSource="{z:EnumValues sysio:SeekOrigin}" />
Simplify the ability to get enum values as ItemsSource.
- Some values can be excluded from the list by specifying them using the Exclude property
as comma delimited names or numbers.
<ComboBox ItemsSource="{z:EnumValues globalization:GregorianCalendarTypes, Exclude=11,22}" />
- Can also extract the enum value names as string, int number of description of DescriptionAttribute,
by setting the Mode property.
<ComboBox ItemsSource="{z:EnumValues globalization:GregorianCalendarTypes, Mode=Name}" />
- Can provide a value-converter to perform conversion of the results, using the Converter property
enum MachineStateEnum
{
None,
[Description("Wax On")]
On,
[Description("Wax Off")]
Off,
[Description("Wax Burn")]
Faulted
}
<ComboBox ItemsSource="{z:EnumValues local:MachineStateEnum}" />
<ComboBox ItemsSource="{z:EnumValues local:MachineStateEnum, Exclude=None,Faulted}" />
<ComboBox ItemsSource="{z:EnumValues local:MachineStateEnum, Exclude=0,2}" />
<ComboBox ItemsSource="{z:EnumValues local:MachineStateEnum, Mode=Number}" />
<ComboBox ItemsSource="{z:EnumValues local:MachineStateEnum, Mode=Description}" />
<ComboBox ItemsSource="{z:EnumValues local:MachineStateEnum, Converter={myconv:EnumToStringResourceConverter}" />
<ComboBox ItemsSource="{z:EnumValues local:MachineStateEnum, Converter={myconv:EnumToReadableStringConverter}" />
<ComboBox ItemsSource="{z:EnumValues local:MachineStateEnum, Mode=Name, Converter={myconv:ToUpperCaseConverter}" />
Value Converters
GroupConverter
WpfMart.Converters.GroupConverter
Groups several value-converters together.
Performs Convert from top to bottom converter and ConvertBack from bottom to top converter.
If one of the converter's return value is either Binding.DoNothing
or DependencyProperty.UnsetValue
, the conversion stop.
When converting back, if one of the converter implement interface ICantConvertBack, it's skipped from conversion
<Control.Resources>
<conv:GroupConverter x:Key="IsMotorCurrentInRangeConverter">
<conv:NumInRangeConverter From="10" To="20" TrueValue="{x:Null}" FalseValue="{conv:UseInputValue}" />
<conv:NumInRangeConverter From="-20" To="-10" NullValue="{x:Static conv:Boxed.True}" />
</conv:GroupConverter>
<conv:GroupConverter x:Key="NullSafeNumberToGregorianCalendarTypes">
<conv:CastConverter ToType="glob:GregorianCalendarTypes" />
<conv:TargetNullValueConverter Value="{x:Static glob:GregorianCalendarTypes.Localized}" />
<conv:InRangeConverter From="{x:Static glob:GregorianCalendarTypes.Localized}"
To="{x:Static glob:GregorianCalendarTypes.Arabic}"
TrueValue="{conv:UseInputValue}",
FalseValue="{x:Static glob:GregorianCalendarTypes.Localized}" />
</conv:GroupConverter>
</Control.Resources>
<ContentControl Content="{Binding NullableInt, Converter={StaticResouces NullSafeNumberToGregorianCalendarTypes}" />
<CheckBox IsEnabled="{Binding MeasuredElectricCurrent, Converter={StaticResource IsMotorCurrentInRangeConverter}}" />
BoolConverter
WpfMart.Converters.BoolConverter
Converts a bool or nullable bool value to another value specified by properties TrueValue
, FalseFalue
and NullValue
.
<Control.Resources>
<conv:BoolConverter x:Key="BoolToOnOffConverter" TrueValue="On" FalseValue="Off" />
<conv:BoolConverter x:Key="IsTrueToMachineStateEnum"
TrueValue="{x:Static local:MachineState.On}"
FalseValue="{x:Static local:MachineState.Off}" />
</Control.Resources>
Nullable bool
In order to support nullable bool, either set NullValue
property to a desired value to return when converting a null
value
or set IsNullable
to true and by that, NullValue
property will have its default value of null
.
(which is same as setting NullValue
property to {x:Null}
. )
if none of the above properties are set,
null
is not converted and considered as false.
Consider using the Binding'sTargetNullValue
instead.
<CheckBox IsThreeState="True" IsChecked="{Binding IsChecked, Converter={conv:BoolConverter IsNullable=True}}" />
<ComboBox SelectedItem="{Binding IsMachineOn, Converter={conv:BoolConverter
TrueValue={x:Static local:MachineState.On}
FalseValue={x:Static local:MachineState.Off}
NullValue={x:Static local:MachineState.None}}}" />
IsNegative
Converter can be negative, meaning comparing to false
instead of true
, by setting IsNegative
property to true.
Although, for that purpose there is a predefined converter:
NegativeBoolConverter
WpfMart.Converters.NegativeBoolConverterExtension
<CheckBox x:Name= IsThreeState="True" Content="{Binding IsKnownToBeClosed, Converter={conv:NegativeBoolConverter IsNullable=True}}" />
<ContentControl Content="{Binding IsOff, Converter={StaticResource IsTrueToMachineStateEnum}, ConverterParameter=True}" />
Reverse conversion
There is ability to switch between Convert and ConvertBack, by setting IsReversed
property to True
.
It will check if converted value equals to TrueValue
property and return true
otherwise false
.
If null
is supported, it's also compared to NullValue
property and returns null
if equals.
enum MachineState { None, On, Off }
<Control.Resources>
<conv:BoolConverter x:Key="EnumToIsCheckedConverter"
IsReversed="True"
TrueValue="{x:Static local:MachineState.On}"
FalseValue="{x:Static local:MachineState.Off}"
NullValue="{x:Static local:MachineState.None}" />
</Control.Resources>
<StackPanel>
<ComboBox x:Name="combobox" ItemsSource="{z:EnumValues local:MachineState}" SelectedIndex="0" />
<CheckBox IsThreeState="True"
IsChecked="{Binding SelectedItem, ElementName=combobox, Converter={StaticResource EnumToIsCheckedConverter}}"/>
</StackPanel>
BoolToVisibilityConverter
WpfMart.Converters.BoolToVisibilityConverter
The difference between this converter and built-in WPF converter System.Windows.Data.BooleanToVisibilityConverter
Is that with this converter has additional abilities as follow:
Hidden instead of Collapsed
it's possible to use Visibility.Hidden
instead of Visibility.Collapsed
<Border x:Name="ContentPlaceHolder" Visibility="{Binding IsMissings, Converter={conv:BoolToVisibilityConverter UseHidden=True}}" />
IsNegative
Converter can be negative, meaning comparing to false
instead of true
, by setting IsNegative
property to true
.
Another way to look at it is, return
Visibility.Visible
when converting fromfalse
,
otherwiseVisibility.Collapsed
(orVisibility.Hidden
ifUseHidden
property is true)
<TextBlock Visibility="{Binding HasLicense, Converter={conv:BoolToVisibilityConverter IsNegative=True}}">
<Hyperlink NavigateUri="http://www.url.com/license" >Acquire license here...</Hyperlink>
</TextBlock>
IsReversed
There is ability to switch between Convert and ConvertBack, by setting IsReversed
property to True
.
It will check if converted value equals to Visibility.Visible
and then return true
, otherwise false
.
(Unless IsNegative
property is true, and therefore the conversion is opposite)
<StackPanel>
<ContentControl x:Name="MovieDetailsViewPlaceHolder" />
<TextBox Text="{Binding EditorComments}"
IsEnabled="{Binding Content.Visibility, ElementName=MovieDetailsViewPlaceHolder,
Converter={conv:BoolToVisibilityConverter IsRevered=True}}"/>
</StackPanel>
There are predefined converters of BoolToVisibilityConverter
, that are configured to common needs, such as:
TrueToCollapsedConverter
WpfMart.Converters.TrueToCollapsedConverterExtension
Converts from true to Visibility.Collapsed
, otherwise to Visibility.Visible
<TextBlock Visibility="{Binding HasLicense, Converter={conv:TrueToCollapsedConverter}}">
<Hyperlink NavigateUri="http://www.url.com/license" >Acquire license here...</Hyperlink>
</TextBlock>
TrueToHiddenConverter
WpfMart.Converters.TrueToHiddenConverterExtension
Converts from true to Visibility.Hidden
, otherwise to Visibility.Visible
<Border x:Name="ContentPlaceHolder" Visibility="{Binding IsMissings, Converter={conv:TrueToHiddenConverter}}" />
FalseToHiddenConverter
WpfMart.Converters.FalseToHiddenConverterxtension
Converts from false to Visibility.Hidden
, otherwise to Visibility.Visible
Converter special values
In some of the converters, where it has a property that can be set to any object,
i.e. BoolConverter.TrueValue
, BoolConverter.FalseValue
, EqualityComparer.CompareTo
It's possible to provide special values from WpfMart.Converters.ConverterSpecialValue
class
That will affect the desired behavior of the converter.
<conv:BoolConverter TrueValue="{x:Static conv:ConverterSpecialValue.UseConverterParameter}" />
For each of the special values there is also a corresponding markup-extension that is simpler to use than the {x:Static}
syntax.
The special values are:
- UseInputValue -
{conv:UseInputValue}
Indicates that the converter should use the 'value' parameter passed to the Convert method. - UseConverterParameter -
{conv:UseConverterParameter}
Indicates that the converter should use the ConverterParameter value used inBinding.ConverterParameter
to the Convert method. - ThrowException -
{conv:ThrowException}
Indicates that the converter should throwSystem.InvalidOperationException
.
Used only as rare option to cause exception in case developer requires that certain conditions won't go unnoticed.
Such as to trigger theSystem.Windows.Data.Binding.ValidatesOnExceptions
property.
<Control.Resources>
<conv:EqualityConverter x:Key="CompareToParameterReturnBackground"
CompareTo="{conv:UseConverterParameter}"
TrueValue="Green", FalseValue="Red" />
</Control.Resources>
<TextBlock Text="On"
Background="{Binding MachineState,
Converter={StaticResource CompareToParameterReturnBackground},
ConverterParameter={x:Static local:MachineState.On}}}" />
<TextBlock Text="Off"
Background="{Binding MachineState,
Converter={StaticResource CompareToParameterReturnBackground},
ConverterParameter={x:Static local:MachineState.Off}}}" />
<TextBox Text="{Binding Name, ValidatesOnExceptions=True,
Converter={conv:EqualityConverter TrueValue={conv:ThrowException}, FalseValue={conv:UseInputValue}}}" />
Please note that the built-in WPF special values such as:
DependencyProperty.UnsetValue
,Binding.DoNothing
are still valid.
but now they got markup-extension to make it simpler to use from XAML:
{conv:UnsetValue}
,{conv:DoNothing}
<conv:EqualityConverter x:Key="CompareToParameterReturnBackground"
CompareTo="{conv:UseConverterParameter}"
TrueValue="Green", FalseValue="{Conv:UnsetValue}" />
CastConverter
Converts a value to another type
The difference between
CastConverter
andCastExtension
is thatCastConverter.ProvideValue
returnsIValueConverter
,
whileCastExtension
performs the conversion and returns the value after conversion.
<ComboBox SelectedItem="{Binding MachineStateNumber, Converter={conv:CastConverter ToType={x:Type local:MachineState}}" />
In order to be able to convert-back, the ConvertBackToType
property should be set.
<ComboBox SelectedItem="{Binding MachineStateNumber,
Converter={conv:CastConverter ToType={x:Type local:MachineState}, ConvertBackToType={x:Type sys:Int32}}" />
Chaining converters
When used as markup-extension it's possible to chain another converter to convert from.
using the FromConverter
property as follow:
<TextBlock Text="{Binding NullableMachineStateId,
Converter={conv:CastConverter {x:Type local:MachineState},
FromConverter={conv:EqualityConverter TrueValue={z:Int 0}, FalseValue={conv:UseInputValue}}}" />
the chaining ability apply most of the value-converters in the package.
This ability should not be abused. use it intelligently, in most of the cases a single converter can do the job.
When not used with markup-extension syntax, wrap with GroupConverter to chain several converters.
enum MachineState { None, On, Off }
<Control.Resources>
<conv:GroupConverter x:Key="NullSafeNumberToMachineStateEnum">
<conv:TargetNullValueConverter Value="{z:Int 0}" />
<conv:CastConverter ToType="{x:Type local:MachineState}" />
</conv:GroupConverter>
</Control.Resources>
<TextBlock Text="{Binding NullableMachineStateId, Converter={StaticResource NullSafeNumberToMachineStateEnum}}" />
EqualityConverter
WpfMart.Converters.EqualityConverter
Checks if converted value equals to the value of CompareTo
property,
if equals, return value of TrueValue
property, otherwise FalseValue
property.
<CheckBox IsChecked="{Binding SeekOrigin, CompareTo={x:Static sysio:SeekOrigin.Current}}" />
enum MachineState { None, On, Off }
<ComboBox SelectedItem="{Binding MachineState, Converter={conv:EqualityConverter
CompareTo={x:Static local:MachineState.None}
TrueValue={x:Null}
FalseValue={conv:UseInputValue}}}">
<x:Static Member="local:MachineState.On" />
<x:Static Member="local:MachineState.Off" />
</ComboBox>
If the CompareTo
property is not set, then by default it's null
and therefore the converter can be used to check for null value.
<CheckBox Content="Use default" IsChecked="{Binding SelectedItem, Converter={conv:EqualityConverter}}" />
IsNegative
Converter can be negative, meaning checking if the value is not equals to the CompareTo
property,
by setting IsNegative
property to true.
<ComboBox SelectedIndex="0"
IsEnabled="{Binding Items.Count, RelativeSource={RelativeSource Self},
Converter={conv:EqualityConverter IsNegative=True, CompareTo={z:Int 0}}}" />
null value
In order to additionally handle conversion from a null
value (in addition for comparing to desired value),
either set NullValue
property to a desired value to return when converting a null
value,
or set IsNullable
to true and by that, NullValue
property will have its default value of null
.
(which is same as setting NullValue
property to {x:Null}
. )
if none of the above properties are set, no special handling for
null
is done, and only comparing toCompareTo
property.
Consider using the Binding's TargetNullValue instead.
Chaining converters
When used as markup-extension it's possible to chain another converter to convert from.
using the FromConverter
property as follow:
<TextBlock Text="{Binding UserInput,
Converter={conv:EqualityConverter CompareTo='YES', TrueValue='Confirmed', FalseValue='---', NullValue='invalid'
FromConverter={notmyconv:ToUpperCaseConverter}}} />
There are predefined converters of EqualityConverter
, that are configured to common needs, such as:
EqualityToVisibilityConverter
WpfMart.Converters.EqualityToVisibilityConverterExtension
Checks if converted value equals to the value of CompareTo
property,
if equals, return value of Visibility.Visible
, otherwise Visibility.Collapsed
.
- The converter can be negative (checking it's not equals to
CompareTo
property), by setting theIsNegative
property totrue
. - The converter can return
Visibility.Hidden
instead ofVisibility.Collapsed
, by setting theUseHidden
property totrue
.
IsNotNullConverter
WpfMart.Converters.IsNotNullConverterExtension
convert a null to false
and non-null value to true
.
NullToInvisibleConverter
WpfMart.Converters.NullToInvisibleConverterExtension
Converts a null to Visiblity.Collapsed
, otherwise to Visiblity.Visible
.
InRangeConverter
WpfMart.Converters.InRangeConverter
Check if value is in range of lower and/or upper bounds.
if in range, returns TrueValue
property , otherwise FalseValue
property.
The range of values is specified using:
From
property, for inclusive lower bound, orAfter
property, for exclusive lower bound.To
property, for inclusive upper bound, orBefore
property, for exclusive upper bound.
The more interesting aspect of the converter is to perform greater-than/less-than conditions
by only specifying one of the bounds (lower or upper) as follow:
<conv:InRangeConverter From="{x:Static diag:TraceLevel.Error}" />
<conv:InRangeConverter After="{x:Static diag:TraceLevel.Error}" />
<conv:InRangeConverter To="{x:Static diag:TraceLevel.Info}" />
<conv:InRangeConverter Before="{x:Static diag:TraceLevel.Info}" />
<TextBlock
Visibility="{Binding TraceLevel, Converter={conv:InRangeConverter
From={x:Static diag:TraceLevel.Info},
TrueValue=Visible, FalseValue=Collapsed}}"
Text="Note: Log file might contain too many entries and get over sized" />
Some notes:
- Avoid setting upper to be less than or equals to the lower bound, as the converter won't function as expected.
- In case setting same value for lower and upper bound, it's same as comparing to a specific value,
therefore prefer using
EqualityConverter
converter instead.
IsNegative
Converter can be negative, meaning checking if the value is not in range,
by setting IsNegative
property to true.
Note:
null
value is considered out of range.
enum CustomerType { Regular, Repeating, Loyal, Vip, OurEmployee }
<Window.Resources>
<conv:InRangeConverter x:Key="IsNotPreferredCustomer" IsNegative="True"
From="{x:Static local:CustomerType.Repeating}"
To="{x:Static local:CustomerType.Vip}" />
</Window.Resources>
<TextBox Text="{Binding PromoCode}" IsReadOnly="{Binding CustomerType, Converter={StaticResource IsNotPreferredCustomer}}"/>
null value
In order to specially handle conversion from a null
value,
either set NullValue
property to a desired value to return when converting a null value,
or set IsNullable
to true and by that, NullValue
property will have its default value of null
.
(which is same as setting NullValue
property to {x:Null}
. )
if none of the above properties are set, no special handling for
null
is done and it's considered not in range,
but resulting value depends on theIsNegative
property.
Consider using the Binding's TargetNullValue instead.
In order to specify range value of numeric types of date-time, it's possible to use the CastExtension
parts,
such as {z:Int}
, {z:Double}
, {z:DateTime}
, etc...
But, there are predefined InRangeConverter
converters configured for common usages such as that:
NumInRangeConverter
WpfMart.Converters.NumInRangeConverter
A InRangeConverter
that used numeric values as lower/upper bounds.
It From
,After
,To
,Before
properties are of type Decimal
.
<ComboBox ItemsSource="{Binding Users}" SelectedIndex="0"
IsEnabled="{Binding Items, RelativeSource={RelativeSource Self}, Converter={conv:NumInRangeConverter From=2}}" />
<TextBlock Text="Angle will be fixed to value between 0 to 360 (not including)"
Visibility="{Binding Angle, Converter={conv:NumInRangeConverter From=0, Before=360, TrueValue=Collapsed, FalseValue=Visible}}"/>
DateInRangeConverter
WpfMart.Converters.NumInRangeConverter
A InRangeConverter
that used DateTime
values as lower/upper bounds.
It's advised to specify the dates is xaml in universal format: 'yyyy-MM-dd'
<TextBlock Text="Windows XP updates are only available after October 25, 2001 and before April 8, 2014"
Visibility="{Binding OSVersionDate, Converter={conv:DateInRangeConverter
After=2001-10-25, Before=2014-04-8, TrueValue=Collapsed, FalseValue=Visible}}" />
Chaining converters
When used as markup-extension it's possible to chain another converter to convert from.
using the FromConverter
property as follow:
<TextBlock Text="{Binding KeyCode}"
Background="{Binding KeyCode, Converter={conv:InRangeConverter From=1, Before=a,
NullValue=LightYellow, TrueValue=LightGreen, FalseValue=Coral,
FromConverter={conv:NullOrEmptyConverter TrueValue={x:Null}, FalseValue={conv:UseInputValue}}}" />
Recap examples
enum CustomerType { Regular, Repeating, Loyal, VIP, OurEmployee}
<ListBox HorizontalContentAlignment="Stretch">
<CheckBox IsChecked="{Binding RedeemPreferredCustomerDiscount}" Content="Redeem valuable customer 5% discount"
Visibility="{Binding CustomerType, Converter={conv:InRangeConverter
From={x:Static local:CustomerType.Loyal},
To={x:Static local:CustomerType.VIP},
TrueValue=Visible, FalseValue=Collapsed}}" />
<TextBlock Text="Coupon code:" />
<TextBox Text="{Binding CouponCode, UpdateSourceTrigger=PropertyChanged}"
Background="{Binding CouponCode, Converter={conv:InRangeConverter NullValue={conv:UnsetValue},
From=1, Before=a, TrueValue={conv:UnsetValue}, FalseValue=Coral,
FromConverter={conv:NullOrEmptyConverter TrueValue={x:Null}, FalseValue={conv:UseInputValue}}}}" />
</ListBox>
MapConverter
WpfMart.Converters.MapConverter
Converts a key to a mapped value.
Defines a dictionary of key-value pairs for which a converted value is considered a key in the dictionary
and the matching value for the key is returned as result.
The dictionary is defined in the same manner as a ResourceDictionary
is defined in XAML.
<Window.Resources>
<conv:MapConverter x:Key="SeekOriginToIcon">
<BitmapImage x:Key="{x:Static sysio:SeekOrigin.Begin}" UriSource="../Assets/SeekBegin.png" />
<BitmapImage x:Key="{x:Static sysio:SeekOrigin.Current}" UriSource="../Assets/SeekCurrent.png" />
<BitmapImage x:Key="{x:Static sysio:SeekOrigin.End}" UriSource="../Assets/SeekEnd.png" />
</conv:MapConverter>
</Window.Resources>
<Button Command="{Binding SeekToCommand}" >
<Image Source="{Binding SelectedSeekOrigin, Converter={StaticResource SeekOriginToIcon}}" />
</Button>
In case the key not found in the dictionary, there will be an attempt to located by its ToString()
value.
This in order to make it more flexible to specify some keys in XAML.
(Illustration on the above example)
<conv:MapConverter x:Key="SeekOriginToIcon">
<BitmapImage x:Key="Begin" UriSource="../Assets/SeekBegin.png" />
<BitmapImage x:Key="Current" UriSource="../Assets/SeekCurrent.png" />
<BitmapImage x:Key="End" UriSource="../Assets/SeekEnd.png" />
</conv:MapConverter>
Fallback value
If the key couldn't be found in the dictionary, a fallback-value is used,
by setting the desired value in the FallbackValue
property.
by default it will return the key itself, which is actually the input value to be converted.
<Window.Resources>
<conv:MapConverter x:Key="GregorianCalendarTypesToText" FallbackValue="-----">
<sys:String x:Key="{x:Static glob:GregorianCalendarTypes.Localized}" >Local</sys:String>
<sys:String x:Key="{x:Static glob:GregorianCalendarTypes.USEnglish}" >English</sys:String>
<sys:String x:Key="{x:Static glob:GregorianCalendarTypes.Arabic}" >Arabic</sys:String>
</conv:MapConverter>
</Window.Resources>
<TextBlock Text="{Binding SelectedCalendarType, Converter={StaticResource GregorianCalendarTypesToText}}" />
null value
In order to map a null
to a value, it's not possible to set it as a key in a dictionary.
<conv:MapConverter><sys:String x:Key={x:Null}>No value</sys:String></conv:MapConverter>
For this purpose use the NullValue
property to set the value to return when converting from null
.
Consider using the Binding's TargetNullValue instead.
enum MachineState { None, On, Off, Faulted, Maintenance }
<Window.Resources>
<SolidColorBrush x:Key="GrayBrush" Color="Gray" />
<conv:MapConverter x:Key="MachineStateToBackground" NullValue="{StaticResource GrayBrush}" FallbackValue="{conv:UnsetValue}" >
<SolidColorBrush x:Key="{x:Static local:MachineState.On}" Color="Green" />
<SolidColorBrush x:Key="{x:Static local:MachineState.Off}" Color="Red" />
<SolidColorBrush x:Key="{x:Static local:MachineState.Faulted}" Color="Orange" />
</conv:MapConverter>
</Window.Resources>
Converting back
The MapConverter
also performs convert-back.
To specify a fallback value in case convert-back cannot find value in the dictionary,
use the ConvertBackFallbackValue
property. by default it cancel the conversion (Binding.DoNothing
).
in case more than one key mapped to the same value,
The resulting key from convert-back can be any of them.
Mapping to another converter
If a mapped value in the dictionary is a value-converter, by default it will be used in order to produce the final value.
to disable this ability, set ConvertAlsoFoundValueConverter
property to false.
Also be aware that performing convert-back won't work if involving embedded value-converter.
<conv:MapConverter x:Key="AngleToNameOrRoundedAngle" FallbackValue="{conv:CastConverter ToType={x:Type sys:Int32}}" >
<sys:String x:Key="{z:Double 0.0}" >Zero</sys:String>
<sys:String x:Key="{z:Double 90.0}" >Ninty</sys:String>
<sys:String x:Key="{z:Double 180.0}">One hundred eighty</sys:String>
</conv:MapConverter>
<TextBlock Text="{Binding Angle, Converter={StaticResource AngleToNameOrRoundedAngle}}" />
Recap Examples
enum MachineState { None, On, Off, Faulted, Maintenance }
<Window.Resources>
<conv:MapConverter x:Key="MachineStateToIsChecked" FallbackValue="{x:Null}"
ConvertBackFallbackValue="{x:Static local:MachineState.None}" >
<sys:Boolean x:Key="{x:Static local:MachineState.On}" >True</sys:Boolean>
<sys:Boolean x:Key="{x:Static local:MachineState.Off}" >False</sys:Boolean>
</conv:MapConverter>
<conv:MapConverter x:Key="MachineStateToForeground" FallbackValue="{conv:UnsetValue}">
<SolidColorBrush x:Key="{x:Static local:MachineState.On}" Color="Green" />
<SolidColorBrush x:Key="{x:Static local:MachineState.Off}" Color="Red" />
<SolidColorBrush x:Key="{x:Static local:MachineState.Faulted}" Color="Orange" />
</conv:MapConverter>
<conv:MapConverter x:Key="ForegroundToTextConverter" NullValue="{x:Null}" >
<sys:String x:Key="#FF008000" >Green</sys:String>
<sys:String x:Key="#FFFF0000" >Red</sys:String>
<sys:String x:Key="#FFFFA500" >Orange</sys:String>
<conv:MapConverter.FallbackValue>
<Rectangle Width = "50" Height="2" StrokeThickness="2" Stroke="Blue" StrokeDashArray="1,2,1,2" Margin="1,7" />
</conv:MapConverter.FallbackValue>
</conv:MapConverter>
</Window.Resources>
<CheckBox x:Name="MachineStateToThreeStateCheck" IsThreeState="True"
IsChecked="{Binding MachineState, Converter={StaticResource MachineStateToIsChecked}}"
Content="{Binding Foreground, RelativeSource={RelativeSource Self}, Mode=OneWay,
Converter={StaticResource ForegroundToTextConverter}}"
Foreground="{Binding MachineState, Mode=OneWay, Converter={StaticResource MachineStateToForeground}}" />
NullOrEmptyConverter
WpfMart.Converters.NullOrEmptyConverter
Checks if converted value is either null or empty string or empty collection (IEnumerable
),
if equals, return value of TrueValue
property, otherwise FalseValue
property.
<TextBlock IsEnabled="{Binding DevicesList, Converter={conv:NullOrEmptyConverter}}">
<Hyperlink NavigateUri="http://www.url.com/license" >Scan devices...</Hyperlink>
</TextBlock>
<Border BorderBrush="{Binding Username, Converter={conv:NullOrEmptyConverter TrueValue=Orange, FalseValue=Green}}" BorderThickness="2">
<TextBox Text="{Binding Username}" />
</Border>
In order to check only for empty string/collection, change the Mode
property from IsNullOrEmpty
(default) to IsEmpty
.
<conv:NullOrEmptyConverter Mode=IsEmpty />
IsNegative
Converter can be negative, and check if the value is neither null nor empty string/collection,
by setting IsNegative
property to true
.
<ComboBox SelectedIndex="0"
IsEnabled="{Binding Items, RelativeSource={RelativeSource Self},
Converter={conv:NullOrEmptyConverter IsNegative=True}}" />
There are predefined converters of NullOrEmptyConverter
, that are configured to common needs, such as:
IsNotNullOrEmptyConverter
WpfMart.Converters.IsNotNullOrEmptyConverterExtension
Convert a null or empty string/collection to false
, otherwise to true
.
<ComboBox SelectedIndex="0"
IsEnabled="{Binding Items, RelativeSource={RelativeSource Self}, Converter={conv:IsNotNullOrEmptyConverter}}" />
NullOrEmptyToInvisibleConverter
WpfMart.Converters.NullOrEmptyToInvisibleConverterExtension
Convert a null or empty string/collection to Visibility.Collapsed
, otherwise Visibility.Visible
.
<ComboBox SelectedIndex="0"
Visibility="{Binding Items, RelativeSource={RelativeSource Self}, Converter={conv:NullOrEmptyToInvisibleConverter}}" />
Chaining converters
This converter also has the ability to chain another converter to convert from.
using the FromConverter
property. (see previous examples).
Multi Value Converters
EqualityMultiConverter
WpfMart.Converters.EqualityMultiConverter
Checks equality of two values provided by bindings.
(The array of values passed to the converter's Convert method contains the two values)
if equals, return value of TrueValue
property, otherwise FalseValue
property.
<CheckBox IsEnabled="False" Content="Reached max attempts">
<CheckBox.IsChecked>
<MultiBinding Converter="{conv:EqualityMultiConverter}" >
<Binding Path="RetryCount" />
<Binding Path="MaxRetries" />
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
<StackPanel>
<ComboBox x:Name="SaladDressing1" ItemsSource="{Binding AvailableSaladDressing}"/>
<ComboBox x:Name="SaladDressing2" ItemsSource="{Binding AvailableSaladDressing}" />
<TextBlock Text="Please notice you picked the same salad dressing for both options" >
<TextBlock.Visibility>
<MultiBinding Converter="{conv:EqualityMultiConverter TrueValue=Collapsed, FalseValue=Visible}" >
<Binding Path="SelectedItem" ElementName="SaladDressing1" TargetNullValue="DiffFromOption2" />
<Binding Path="SelectedItem" ElementName="SaladDressing2" TargetNullValue="DiffFromOption1" />
</MultiBinding>
</TextBlock.Visibility>
</TextBlock>
</StackPanel>
IsNegative
Converter can be negative, meaning checking if values are not equals to each other,
by setting IsNegative
property to true.
<TextBox Text="{Binding CouponCode}" >
<TextBox.IsReadOnly>
<MultiBinding Converter="{conv:EqualityMultiConverter IsNegative=True}" >
<Binding Path="CouponsUsedsoFar" />
<Binding Path="MaxCouponsAllowed" />
</MultiBinding>
</TextBox.IsReadOnly>
</TextBox>
InRangeMultiConverter
WpfMart.Converters.InRangeMultiConverter
Check if value is in range of lower and/or upper bounds.
if in range, returns TrueValue
property , otherwise FalseValue
property.
The array of values passed to the converter's Convert method is treated as follow:
- The value to check if in range - values[0]
- By default values[1] is the lower bound of the range and values[2] is the upper bound of the range.
The converter is very similar to InRangeConverter
except that the lower/upper bounds are provided usingBinding
inside aMultiBinding
.
<TextBlock Text="{Binding MeasuredValue}" >
<TextBlock.Background>
<MultiBinding Converter="{conv:InRangeMultiConverter TrueValue=Green, FalseValue=Red}">
<Binding Path="MeasuredValue" />
<Binding Path="MinAllowedValue" />
<Binding Path="MaxAllowedValue" />
</MultiBinding>
</TextBlock.Background>
</TextBlock>
To specify if lower/upper bounds are inclusive or exclusive,
set properties LowerInclusive
and/or UpperInclusive
to true
or false
.
By default the bounds are inclusive.
<TextBlock Text="{Binding MeasuredValue}" >
<TextBlock.Background>
<MultiBinding Converter="{conv:InRangeMultiConverter LowerInclusive=False, UpperInclusive=False, TrueValue=Green, FalseValue=Red}">
<Binding Path="MeasuredValue" />
<Binding Path="LowerOutOfRangeValue" />
<Binding Path="UpperOutOfRangeValue" />
</MultiBinding>
</TextBlock.Background>
</TextBlock>
The more interesting aspect of the converter is to perform greater-than/less-than conditions
by only specifying one of the bounds (lower or upper) by binding to only a value and a single limit,
and in addition set only one of the properties LowerInclusive
or UpperInclusive
to indicate which limit to use.
(otherwise it defaults to lower inclusive).
<CheckBox Content="Passed the test" IsEnabled="False">
<CheckBox.IsChecked>
<MultiBinding Converter="{conv:InRangeMultiConverter LowerInclusive=True}" >
<Binding Path="Grade" />
<Binding Path="MinGrade" />
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
- Setting only
LowerInclusive
toTrue
performs Greater than or Equals to. setting toFalse
performs Greater than. - Setting only
UpperInclusive
toTrue
performs Less than or Equals to. setting toFalse
performs Less than.
The above is true only if binding to 1 limit. if binding to 2 limits (see very first example),
then in-range check is done on both limits.
<StackPanel Orientation="Horizontal">
<DatePicker x:Name="FromDatePicker" />
<DatePicker x:Name="ToDatePicker" />
<TextBlock Text="From date should be less than To date">
<TextBlock.Visibility>
<MultiBinding Converter="{conv:InRangeMultiConverter UpperInclusive=False, TrueValue=Collapsed, FalseValue=Visible}" >
<Binding Path="SelectedDate" ElementName="FromDatePicker" />
<Binding Path="SelectedDate" ElementName="ToDatePicker" />
</MultiBinding>
</TextBlock.Visibility>
</TextBlock>
</StackPanel>
IsNegative
Converter can be negative, meaning checking if the value is not in range,
by setting IsNegative
property to true.
Note:
null
value is considered out of range.
enum CustomerType { Regular, Repeating, Loyal, Vip, OurEmployee }
<Window.Resources>
<conv:InRangeMultiConverter x:Key="IsRangeToVisibility" LowerInclusive="True" TrueValue="Visible", FalseValue="Collapsed" />
</Window.Resources>
<Button Content="Try again">
<Button.Visibility>
<MultiBinding Converter="{StaticResource IsRangeToVisibility}" ConverterParameter="True" >
<Binding Path="Grade" />
<Binding Path="MinGrade" />
</MultiBinding>
</Button.Visibility>
</Button>
<TextBlock Content="You passed the test">
<TextBlock.Visibility>
<MultiBinding Converter="{StaticResource IsRangeToVisibility}" >
<Binding Path="Grade" />
<Binding Path="MinGrade" />
</MultiBinding>
</TextBlock.Visibility>
</TextBlock>
null value
In order to specially handle conversion from a null
value,
either set NullValue
property to a desired value to return when converting a null value,
or set IsNullable
to true and by that, NullValue
property will have its default value of null
.
(which is same as setting NullValue
property to {x:Null}
. )
if none of the above properties are set, no special handling for
null
is done and it's considered not in range,
but resulting value depends on theIsNegative
property.
Consider using the Binding's TargetNullValue instead.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.1 is compatible. |
.NET Framework | net452 is compatible. net46 was computed. net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 is compatible. net481 was computed. |
-
.NETCoreApp 3.1
- No dependencies.
-
.NETFramework 4.5.2
- No dependencies.
-
.NETFramework 4.8
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.