Add docs about FuncValueConverter

This commit is contained in:
timunie 2023-12-25 17:47:26 +01:00
Родитель 2f85c3f624
Коммит ee5dcf5639
5 изменённых файлов: 93 добавлений и 10 удалений

Просмотреть файл

@ -83,7 +83,7 @@ Each sample is tagged with it's difficulty. The degree of difficulty describes h
| link:src/Avalonia.Samples/MVVM/ValueConversionSample[ValueConverter Sample]
| 🐥 Easy
| Converter, Binding, MultiBinding, IValueConverter, IMultiValueConverter, MVVM
| Converter, Binding, MultiBinding, IValueConverter, IMultiValueConverter, MVVM, FuncValueConverter
| link:src/Avalonia.Samples/MVVM/ValidationSample[Validation Sample]
| 🐥 Easy

Просмотреть файл

@ -6,17 +6,17 @@ namespace ValueConversionSample.Converter;
/// A static class holding our FuncValueConverter
/// </summary>
/// <remarks>
/// Consume it from XAML via <code>{x:Static conv:FuncValueMathConverters.MyConverter}</code>
/// Consume it from XAML via <code>{x:Static conv:FuncValueStringConverters.MyConverter}</code>
/// </remarks>
public static class FuncValueMathConverters
public static class FuncValueStringConverters
{
/// <summary>
/// Gets a Converter that returns true if a number is 0, otherwise false
/// Gets a Converter that returns true if a string is null or empty, otherwise false
/// </summary>
public static FuncValueConverter<int, bool> IsZero { get; } = new FuncValueConverter<int, bool>(i => i == 0);
public static FuncValueConverter<string?, bool> IsEmpty { get; } = new FuncValueConverter<string?, bool>(s => string.IsNullOrEmpty(s));
/// <summary>
/// Gets a Converter that returns true if a number is not 0, otherwise false
/// Gets a Converter that returns true if a string is not null or empty, otherwise false
/// </summary>
public static FuncValueConverter<int, bool> IsNotZero { get; } = new FuncValueConverter<int, bool>(i => i != 0);
public static FuncValueConverter<string?, bool> IsNotEmpty { get; } = new FuncValueConverter<string?, bool>(s => !string.IsNullOrEmpty(s));
}

Просмотреть файл

@ -27,7 +27,7 @@ toc::[]
=== Buzz-Words
Converter, Binding, MultiBinding, IValueConverter, IMultiValueConverter, MVVM
Converter, Binding, MultiBinding, IValueConverter, IMultiValueConverter, MVVM, FuncValueConverter
== Before we start
@ -172,6 +172,26 @@ Now we can add two https://docs.avaloniaui.net/docs/controls/numericupdown[[`Num
TIP: `ConverterParameter` can only be a static value. You cannot bind to it and you cannot use `DynamicResource`. If you need more flexibility, consider to do your calculations in your `ViewModel` or use a `MultiValueConverter`.
[NOTE]
====
If you want to, you can also define the converter as a static member and use it without the need to add it to the `Resources`
[source,cs]
----
/// <summary>
/// Gets a static instance of the MathAddConverter
/// </summary>
public static MathAddConverter AddConverter { get; } = new MathAddConverter();
----
[source,xml]
----
<NumericUpDown Grid.Row="1" Grid.Column="1"
Value="{Binding Number1, Converter={x:Static MathAddConverter.AddConverter}, ConverterParameter={StaticResource MyConverterParameter}}" />
----
====
=== Step 4: See it in action
In your IDE select `[Run]` or `[Debug]` to see the result in action. Try to change the value in both input boxes and see how they update each other.
@ -391,6 +411,69 @@ In your IDE select `[Run]` or `[Debug]` to see the result in action. Try to chan
image::_docs/result_02.png[IMultiValueConverter sample]
== Solution 3 : Using FuncValueConverter
In case you need a converter that only converts a given input in one direction without the need of a `ConverterParameter`, you can also use a `FuncValueConverter`. The benefit is that the converter is much shorter to write. In this sample we will add two `FuncValueConverter` which will check if a given string is empty or not. We will consume the converters to show and hide content based on some user inout.
=== Step 1 : Create the FuncValueConverters
TIP: We can use a static class here as the converters will not change.
The `FuncValueConverter` has two generic parameters:
TIn:: This parameter defines the expected input type. This can also be an array in case you want to use this converter in a `MultiBinding`.
TOut:: This parameter defines the expected output type.
The constructor expects a lambda defining the function to convert.
[source,c#]
----
/// <summary>
/// A static class holding our FuncValueConverter
/// </summary>
/// <remarks>
/// Consume it from XAML via <code>{x:Static conv:FuncValueStringConverters.MyConverter}</code>
/// </remarks>
public static class FuncValueStringConverters
{
/// <summary>
/// Gets a Converter that returns true if a string is null or empty, otherwise false
/// </summary>
public static FuncValueConverter<string?, bool> IsEmpty { get; } = new FuncValueConverter<string?, bool>(s => string.IsNullOrEmpty(s));
/// <summary>
/// Gets a Converter that returns true if a string is not null or empty, otherwise false
/// </summary>
public static FuncValueConverter<string?, bool> IsNotEmpty { get; } = new FuncValueConverter<string?, bool>(s => !string.IsNullOrEmpty(s));
}
----
=== Step 2: Setup the View
Our view will be made of one `TextBox` called "Input" and two `TextBlocks` while only one of them is visible at a time using our converter bound to the length of the text typed.
[source,xml]
----
<StackPanel Spacing="5">
<TextBox x:Name="Input" Watermark="Type anything" />
<!-- Visible when no text input -->
<TextBlock Text="You can only see me if the TextBox is empty"
IsVisible="{Binding #Input.Text, Converter={x:Static conv:FuncValueStringConverters.IsEmpty}}" />
<!-- Visible when text is present -->
<TextBlock Text="{Binding #Input.Text.Length, StringFormat='You have typed {0:N0} chars'}"
IsVisible="{Binding #Input.Text, Converter={x:Static conv:FuncValueStringConverters.IsNotEmpty}}" />
</StackPanel>
----
=== Step 3: See it in action
In your IDE select `[Run]` or `[Debug]` to see the result in action. Try to change the value in the input box and see how it updates the result below.
image::_docs/result_03.png[FuncValueConverter sample]
== Related
Avalonia has some really nice built-in `Converters` for you. Read more about in the https://docs.avaloniaui.net/docs/data-binding/converting-binding-values[[Docs\]].

Просмотреть файл

@ -77,11 +77,11 @@
<!-- Visible when no text input -->
<TextBlock Text="You can only see me if the TextBox is empty"
IsVisible="{Binding #Input.Text.Length, Converter={x:Static conv:FuncValueMathConverters.IsZero}}" />
IsVisible="{Binding #Input.Text, Converter={x:Static conv:FuncValueStringConverters.IsEmpty}}" />
<!-- Visible when text is present -->
<TextBlock Text="{Binding #Input.Text.Length, StringFormat='You have typed {0:N0} chars'}"
IsVisible="{Binding #Input.Text.Length, Converter={x:Static conv:FuncValueMathConverters.IsNotZero}}" />
IsVisible="{Binding #Input.Text, Converter={x:Static conv:FuncValueStringConverters.IsNotEmpty}}" />
</StackPanel>
</TabItem>
</TabControl>

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 22 KiB