Git Product home page Git Product logo

lambda-converters's Introduction

Lambda Converters NuGet ReSharper Extension

The library allows to create IValueConverter, IMultiValueConverter, DataTemplateSelector, and ValidationRule objects with the most convenient syntax available, ideally, using the lambda expressions.

Lambda Value Converters

First create a (static) class and define your converters as static fields (or properties):

internal static class Converters
{
    public static readonly IValueConverter VisibleIfTrue =
        ValueConverter.Create<bool, Visibility>(e => e.Value ? Visibility.Visible : Visibility.Collapsed);

    public static readonly IValueConverter VisibleIfNotNull =
        ValueConverter.Create<object, Visibility>(e => e.Value != null ? Visibility.Visible : Visibility.Collapsed);

    public static readonly IValueConverter ToUpperCase =
        ValueConverter.Create<string, string>(e => e.Value.ToUpper());
}

You're done! Just reference the converters with the x:Static expressions from your XAML files (assuming that c is the namespace definition for the Converters class):

<Button Visibility="{Binding model.IsAvailable, Converter={x:Static c:Converters.VisibleIfTrue}}" />

<TextBlock Text="{Binding model.Heading, Converter={x:Static c:Converters.ToUpperCase}}" />

Features

  • 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 and ConvertBack methods: the culture and the parameter (also strongly-typed) are accessible as well
  • if the conversion fails due to unexpected value types the optional error strategy can be specified

Lambda Data Template Selectors

The library also allows to create DataTemplateSelector 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:

internal static class TemplateSelector
{
    public static DataTemplateSelector AlternatingText =
        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 the x:Static markup extention (assuming that s is the namespace definition for the TemplateSelector class):

<UserControl.Resources>
    <DataTemplate x:Key="BlackWhite">
        <TextBlock Text="{Binding}" Foreground="Black" Background="White" />
    </DataTemplate>
    <DataTemplate x:Key="WhiteBlack">
        <TextBlock Text="{Binding}" Foreground="White" Background="Black" />
    </DataTemplate>
</UserControl.Resources>
<DockPanel>
    <ListBox ItemsSource="{Binding IntNumbers}"
             ItemTemplateSelector="{x:Static s:TemplateSelector.AlternatingText}">
    </ListBox>
</DockPanel>

Tada! All even numbers from IntNumbers are displayed with black font and white background and the odd numbers get the inverse font and background colors.

Features

  • 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 a DataTemplate from where the selector is use (see the example above).

Lambda Validation Rules

Furthermore, you'll get Lambda ValidationRules on top. By now you know "the drill". First, define a ValidationRuleobject like this:

public static class Rule
{
    public static ValidationRule IsNumericString =
        LambdaConverters.Validator.Create<string>(
            e => e.Value.All(char.IsDigit)
                ? ValidationResult.ValidResult
                : new ValidationResult(false, "Text has non-digit characters!"));
}

And then reference your new rule in vour View (assuming that r is the namespace definition for the Rule class):

<TextBox>
    <TextBox.Text>
        <Binding Path="Text" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <x:Static Member="r:Rule.IsNumericString"/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

Now, you made sure that only strings which consists of digits are passed to your ViewModel.

Features

  • 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

Installation

Use the NuGet package manager to install the package.

๐Ÿ’ก ReSharper users: use the Extension Manager to install the external annotations for the library.

Limitations

The library currently supports the WPF only.

Bugs? Questions? Suggestions?

Please feel free to report them.

lambda-converters's People

Contributors

alexhelms avatar michael-damatov avatar yeah69 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lambda-converters's Issues

Value converter is not firing

I have the following lambda converter:

    public static readonly IValueConverter SignalStrengthImage = ValueConverter.Create<int, string>(e =>
    {
        logger.Info("wtf");
        var root = "pack://application:,,,/MyLibrary;component";
        var path = $"{root}/assets/signal_strength_unknown.png";
        switch ((int)e.Value)
        {
            case 0: path = $"{root}/assets/signal_strength_0.png"; break;
            case int n when n <= 20: path = $"{root}/assets/signal_strength_20.png"; break;
            case int n when n <= 40: path = $"{root}/assets/signal_strength_40.png"; break;
            case int n when n <= 60: path = $"{root}/assets/signal_strength_60.png"; break;
            case int n when n <= 80: path = $"{root}/assets/signal_strength_80.png"; break;
            default: path = $"{root}/assets/signal_strength_100.png"; break;
        }
        return path;
    });

With the corresponding xaml:

    <Image Source="{Binding Status.SignalStrength, Converter={x:Static c:Converters.SignalStrengthImage}, FallbackValue={StaticResource UnknownSignalStrength}}" Width="70" Height="70"/>

Unfortunately, the converter seems as though it is never called. When the property on the viewmodel is updated, the Image goes from displaying the fallback image to displaying nothing. The log statement in the converter is never fired, and if I set a breakpoint it is never reached.

If I create a normal IValueConverter class the traditional way, with the exact same code, it works properly.

ValueConverter.Create with ConverterParameter does not get called

Thanks for this very convenient library!

I was having issues getting the following converter to be called:
public static readonly IValueConverter ResultToColor = ValueConverter.Create<IResult, Brush, int>(e =>...)

Here's the corresponding xaml:
<Label Style="{StaticResource ResultLabel}" Background="{Binding Result, ConverterParameter = 1, Converter={x:Static local:Converters.ResultToColor}}"/>

However, changing the parameter type to object fixed the issue. This gets called correctly:
public static readonly IValueConverter ResultToColor = ValueConverter.Create<IResult, Brush, object>(e =>...)

I'm curious how you get ConverterParameter to be strongly typed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.