- Notifications
You must be signed in to change notification settings - Fork15
Strongly-typed lambda expressions as value converters, data template selectors, and validation rules
License
michael-damatov/lambda-converters
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
The library allows to createIValueConverter
,IMultiValueConverter
,DataTemplateSelector
, andValidationRule
objects with the most convenient syntax available, ideally, using the lambda expressions.
First create a (static) class and define your converters as static fields (or properties):
internalstaticclassConverters{publicstaticreadonlyIValueConverterVisibleIfTrue=ValueConverter.Create<bool,Visibility>(e=>e.Value?Visibility.Visible:Visibility.Collapsed);publicstaticreadonlyIValueConverterVisibleIfNotNull=ValueConverter.Create<object,Visibility>(e=>e.Value!=null?Visibility.Visible:Visibility.Collapsed);publicstaticreadonlyIValueConverterToUpperCase=ValueConverter.Create<string,string>(e=>e.Value.ToUpper());}
You're done! Just reference the converters with thex:Static
expressions from your XAML files (assuming thatc
is the namespace definition for theConverters
class):
<ButtonVisibility="{Binding model.IsAvailable, Converter={x:Static c:Converters.VisibleIfTrue}}" /><TextBlockText="{Binding model.Heading, Converter={x:Static c:Converters.ToUpperCase}}" />
- strongly-typed converters
- resource declaration not needed, just use the
x:Static
expressions - separate class for each converter not needed anymore
- no redundant declarations: if you do not need the
ConvertBack
method, don't define it; otherwise, just put the second lambda expression - full support for the remaining parameters of the
Convert
andConvertBack
methods: theculture
and theparameter
(also strongly-typed) are accessible as well - if the conversion fails due to unexpected value types the optionalerror strategy can be specified
The library also allows to createDataTemplateSelector
objects in the same convenient way as value converters. In order to define a selector simply write a static field (or property) similar to this snippet:
internalstaticclassTemplateSelector{publicstaticDataTemplateSelectorAlternatingText=LambdaConverters.TemplateSelector.Create<int>( e=>e.Item%2==0?(DataTemplate)((FrameworkElement)e.Container)?.FindResource("BlackWhite"):(DataTemplate)((FrameworkElement)e.Container)?.FindResource("WhiteBlack"));}
Use your Lambda DataTemplateSelectors by referencing it with thex:Static
markup extention (assuming thats
is the namespace definition for theTemplateSelector
class):
<UserControl.Resources> <DataTemplatex:Key="BlackWhite"> <TextBlockText="{Binding}"Foreground="Black"Background="White" /> </DataTemplate> <DataTemplatex:Key="WhiteBlack"> <TextBlockText="{Binding}"Foreground="White"Background="Black" /> </DataTemplate></UserControl.Resources><DockPanel> <ListBoxItemsSource="{Binding IntNumbers}"ItemTemplateSelector="{x:Static s:TemplateSelector.AlternatingText}"> </ListBox></DockPanel>
Tada! All even numbers fromIntNumbers
are displayed with black font and white background and the odd numbers get the inverse font and background colors.
- strongly-typed Selectors
- resource declaration not needed, just use the
x:Static
expressions - separate class for each selector not needed anymore
- full support for the remaining parameter
container
. For example, if you need to grab aDataTemplate
from where the selector is use (see the example above).
Furthermore, you'll get Lambda ValidationRules on top. By now you know "the drill". First, define aValidationRule
object like this:
publicstaticclassRule{publicstaticValidationRuleIsNumericString=LambdaConverters.Validator.Create<string>( e=>e.Value.All(char.IsDigit)?ValidationResult.ValidResult:newValidationResult(false,"Text has non-digit characters!"));}
And then reference your new rule in vourView
(assuming thatr
is the namespace definition for theRule
class):
<TextBox> <TextBox.Text> <BindingPath="Text"UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <x:StaticMember="r:Rule.IsNumericString"/> </Binding.ValidationRules> </Binding> </TextBox.Text></TextBox>
Now, you made sure that only strings which consists of digits are passed to yourViewModel
.
- strongly-typed rules
- resource declaration not needed, just use the
x:Static
expressions - separate class for each rule not needed anymore
- full support for the remaining parameter
culture
Use the NuGet package manager to install the package.
💡ReSharper users: use the Extension Manager to install the external annotations for the library.
The library currently supports the WPF only.
Please feel free toreport them.
About
Strongly-typed lambda expressions as value converters, data template selectors, and validation rules