Add docs about FuncValueConverter
This commit is contained in:
Родитель
2f85c3f624
Коммит
ee5dcf5639
|
@ -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]
|
| link:src/Avalonia.Samples/MVVM/ValueConversionSample[ValueConverter Sample]
|
||||||
| 🐥 Easy
|
| 🐥 Easy
|
||||||
| Converter, Binding, MultiBinding, IValueConverter, IMultiValueConverter, MVVM
|
| Converter, Binding, MultiBinding, IValueConverter, IMultiValueConverter, MVVM, FuncValueConverter
|
||||||
|
|
||||||
| link:src/Avalonia.Samples/MVVM/ValidationSample[Validation Sample]
|
| link:src/Avalonia.Samples/MVVM/ValidationSample[Validation Sample]
|
||||||
| 🐥 Easy
|
| 🐥 Easy
|
||||||
|
|
|
@ -6,17 +6,17 @@ namespace ValueConversionSample.Converter;
|
||||||
/// A static class holding our FuncValueConverter
|
/// A static class holding our FuncValueConverter
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <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>
|
/// </remarks>
|
||||||
public static class FuncValueMathConverters
|
public static class FuncValueStringConverters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <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>
|
/// </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>
|
/// <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>
|
/// </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
|
=== Buzz-Words
|
||||||
|
|
||||||
Converter, Binding, MultiBinding, IValueConverter, IMultiValueConverter, MVVM
|
Converter, Binding, MultiBinding, IValueConverter, IMultiValueConverter, MVVM, FuncValueConverter
|
||||||
|
|
||||||
|
|
||||||
== Before we start
|
== 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`.
|
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
|
=== 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.
|
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]
|
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
|
== 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\]].
|
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 -->
|
<!-- Visible when no text input -->
|
||||||
<TextBlock Text="You can only see me if the TextBox is empty"
|
<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 -->
|
<!-- Visible when text is present -->
|
||||||
<TextBlock Text="{Binding #Input.Text.Length, StringFormat='You have typed {0:N0} chars'}"
|
<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>
|
</StackPanel>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</TabControl>
|
</TabControl>
|
||||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 22 KiB |
Загрузка…
Ссылка в новой задаче