Xamarin Community Toolkit カタログ（ビヘイビア・コンバーター編）

この記事は、[Xamarin Advent Calendar 2020](https://qiita.com/advent-calendar/2020/xamarin) 16日目の記事です。

# はじめに
[Xamarin Community Toolkit](https://github.com/xamarin/XamarinCommunityToolkit) は、Xamarin.Formsで使用できる便利ツール群です。ビヘイビア、コンバーター、エフェクトなどの汎用的な機能が揃っています。
この記事では、Xamarin Community Toolkitの機能を紹介していきます。執筆時点でのバージョンは、1.0.0-pre6 です。

記事内のコードは、GitHubにあげてあります。
[XamarinCommunityToolkitCatalog](https://github.com/f-miyu/XamarinCommunityToolkitCatalog)

この記事では、ビヘイビア、コンバーターについて紹介します。
他の機能については、以下の記事で紹介しています。

* [Xamarin Community Toolkit カタログ（エフェクト・XAMLマークアップ拡張・コントロール編）](https://qiita.com/f-miyu/items/bb3959645879fd6f6abb)
* [Xamarin Community Toolkit カタログ（MVVM編）](https://qiita.com/f-miyu/items/6c7114bd36a641a226b8)

# 使い方
プレビュー版ですが、NuGetでインストールできます。
[Xamarin.CommunityToolkit](https://www.nuget.org/packages/Xamarin.CommunityToolkit/)

xamlでのネームスペースは、以下のように指定します。

```xml
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
```

# ビヘイビア

## AnimationBehavior
タップ時にアニメーションが行われるようにするビヘイビアです。設定できるアニメーションの種類は以下の通りです。

* FadeAnimation （フェード）
* FlipHorizontalAnimation （横フリップ）
* FlipVerticalAnimation （縦フリップ）
* RotateAnimation （回転）
* ScaleAnimation （スケール）
* ShakeAnimation （シェイク）

`Command`で、アニメーション終了時に実行するコマンドを設定できます。ただし、仕様なのかバグなのか分かりませんが、２回実行されるので注意が必要です。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.AnimationBehaviorPage"
             Title="AnimationBehavior">
    <StackLayout VerticalOptions="Center"
                 Padding="32, 0"
                 Spacing="16">
        <Label Text="Fade" HorizontalTextAlignment="Center" >
            <Label.Behaviors>
                <xct:AnimationBehavior Command="{Binding FinishedCommand}">
                    <xct:AnimationBehavior.AnimationType>
                        <xct:FadeAnimation />
                    </xct:AnimationBehavior.AnimationType>
                </xct:AnimationBehavior>
            </Label.Behaviors>
        </Label>

        <Label Text="FlipHorizontal" HorizontalTextAlignment="Center" >
            <Label.Behaviors>
                <xct:AnimationBehavior Command="{Binding FinishedCommand}">
                    <xct:AnimationBehavior.AnimationType>
                        <xct:FlipHorizontalAnimation />
                    </xct:AnimationBehavior.AnimationType>
                </xct:AnimationBehavior>
            </Label.Behaviors>
        </Label>

        <Label Text="FlipHorizontal" HorizontalTextAlignment="Center" >
            <Label.Behaviors>
                <xct:AnimationBehavior Command="{Binding FinishedCommand}">
                    <xct:AnimationBehavior.AnimationType>
                        <xct:FlipVerticalAnimation />
                    </xct:AnimationBehavior.AnimationType>
                </xct:AnimationBehavior>
            </Label.Behaviors>
        </Label>

        <Label Text="Rotate" HorizontalTextAlignment="Center" >
            <Label.Behaviors>
                <xct:AnimationBehavior Command="{Binding FinishedCommand}">
                    <xct:AnimationBehavior.AnimationType>
                        <xct:RotateAnimation Rotation="360" Duration="1000" />
                    </xct:AnimationBehavior.AnimationType>
                </xct:AnimationBehavior>
            </Label.Behaviors>
        </Label>

        <Label Text="Scale" HorizontalTextAlignment="Center" >
            <Label.Behaviors>
                <xct:AnimationBehavior Command="{Binding FinishedCommand}">
                    <xct:AnimationBehavior.AnimationType>
                        <xct:ScaleAnimation Scale="2" />
                    </xct:AnimationBehavior.AnimationType>
                </xct:AnimationBehavior>
            </Label.Behaviors>
        </Label>

        <Button Text="Shake">
            <Button.Behaviors>
                <xct:AnimationBehavior EventName="Clicked"
                                       Command="{Binding FinishedCommand}">
                    <xct:AnimationBehavior.AnimationType>
                        <xct:ShakeAnimation />
                    </xct:AnimationBehavior.AnimationType>
                </xct:AnimationBehavior>
            </Button.Behaviors>
        </Button>
    </StackLayout>
</ContentPage>
```

## EventToCommandBehavior
指定したイベントの発火時にコマンドを実行するビヘイビアです。`EventName`でイベント名を、`Command`でコマンドを設定します。また、`CommandParameter`でコマンドのパラメータ、`EventArgsConverter`で`EventArgs`のコンバーターの設定もできます。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.EventToCommandBehaviorPage"
             Title="EventToCommandBehavior">
    <Button Text="Button"
            VerticalOptions="Center"
            Margin="32, 0">
        <Button.Behaviors>
            <xct:EventToCommandBehavior EventName="Clicked"
                                        Command="{Binding ClickedCommand}" />
        </Button.Behaviors>
    </Button>
</ContentPage>
```

## ImpliedOrderGridBehavior
`Grid`で`Grid.Column`や`Grid.Row`を指定しなくても、暗黙的に設定を行うビヘイビアです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.ImpliedOrderGridBehaviorPage"
             Title="ImpliedOrderGridBehavior">
    <Grid>
        <Grid.Behaviors>
            <xct:ImpliedOrderGridBehavior />
        </Grid.Behaviors>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Label Text="0,0" />
        <Label Text="1,0" />
        <Label Text="2,0" />

        <Label Text="0,1" />
        <Label Text="1,1" />
        <Label Text="2,1" />
    </Grid>
</ContentPage>
```

## MaskedBehavior
入力した文字列を指定したパターンに合わせるビヘイビアです。`Mask`でパターンを設定します。パターンでの任意の文字はデフォルトでは`X`で表します。この文字は、`UnMaskedCharacter`で変更することが可能です。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.MaskedBehaviorPage"
             Title="MaskedBehavior">
    <Entry VerticalOptions="Center" Margin="32, 0">
        <Entry.Behaviors>
            <xct:MaskedBehavior Mask="XXXX-XX" />
        </Entry.Behaviors>
    </Entry>
</ContentPage>
```

## MaxLengthReachedBehavior
`Entry`や`Editor`の最大入力文字（`MaxLength`）に達した時にイベントのやコマンドを実行するビヘイビアです。イベントは`MaxLengthReached`、コマンドは`Command`で設定します。また、`ShouldDismissKeyboardAutomatically`を`true`にすることで、最大入力文字に達した時に、キーボードを閉じるようにすることもできます。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.MaxLengthReachedBehaviorPage"
             Title="MaxLengthReachedBehavior">
    <Entry MaxLength="6"
           VerticalOptions="Center"
           Margin="32, 0">
        <Entry.Behaviors>
            <xct:MaxLengthReachedBehavior Command="{Binding MaxLengthReachedCommand}"
                                          ShouldDismissKeyboardAutomatically="True" />
        </Entry.Behaviors>
    </Entry>
</ContentPage>
```

## UserStoppedTypingBehavior
`Entry`や`Editor`で入力を終えてから一定時間後にコマンドを実行するビヘイビアです。`StoppedTypingTimeThreshold`でコマンド実行までの時間（ミリ秒）を、`Command`で実行するコマンドを設定します。また、`MinimumLengthThreshold`でコマンドの実行を行う最小文字数を設定できたり、`ShouldDismissKeyboardAutomatically`を`true`にすることで、コマンド実行時にキーボードを閉じるようにすることもできます。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.UserStoppedTypingBehaviorPage"
             Title="UserStoppedTypingBehavior">
    <Entry VerticalOptions="Center" Margin="32, 0">
        <Entry.Behaviors>
            <xct:UserStoppedTypingBehavior Command="{Binding UserStoppedTypingCommand}"
                                           StoppedTypingTimeThreshold="500"
                                           MinimumLengthThreshold="3"
                                           ShouldDismissKeyboardAutomatically="True" />
        </Entry.Behaviors>
    </Entry>
</ContentPage>
```

## ValidationBehavior
バリデーションを行うためのビヘイビアです。`ValidStyle`で有効時、`InvalidStyle`で無効時のスタイルを設定できます。また、`IsValid`で、有効かどうかを取得できます。
`ValidationBehavior`は抽象クラスで、以下が実装してあるクラスです。

### CharactersValidationBehavior
指定した種類の文字が指定数分含まれているかどうかのバリデーションを行うビヘイビアです。`CharacterType`で文字の種類、`MinimumCharacterCount`で最小数、`MaximumCharacterCount`で最大数を指定します。
指定できる文字の種類は以下の通りです。

* LowercaseLetter （小文字）
* UppercaseLetter （大文字）
* Letter （LowercaseLetter または UppercaseLetter）
* Digit （数字）
* Alphanumeric （Letter または Digit）
* Whitespace （空白文字）
* NonAlphanumericSymbol （文字、数字、空白文字以外）
* LowercaseLatinLetter （a〜z）
* UppercaseLatinLetter （A〜Z）
* LatinLetter （LowercaseLatinLetter または UppercaseLatinLetter）
* Any （Alphanumeric または NonAlphanumericSymbol または Whitespace）

フラグなので組み合わせることもできます。ただし、`LowercaseLetter`、`UppercaseLetter`では日本語の文字は含まれないので、必然的に`Letter`でも含まれないので注意が必要です。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.CharactersValidationBehaviorPage"
             Title="CharactersValidationBehavior">
    <ContentPage.Resources>
        <Style x:Key="invalidEntryStyle" TargetType="Entry">
            <Setter Property="TextColor" Value="Red" />
        </Style>
    </ContentPage.Resources>

    <Entry VerticalOptions="Center" Margin="32, 0">
        <Entry.Behaviors>
            <xct:CharactersValidationBehavior InvalidStyle="{StaticResource invalidEntryStyle}"
                                              CharacterType="Letter"
                                              MinimumCharacterCount="2"
                                              MaximumCharacterCount="5" />
        </Entry.Behaviors>
    </Entry>
</ContentPage>
```

### EmailValidationBehavior
Eメールの書式になっているかどうかのバリデーションを行うビヘイビアです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.EmailValidationBehaviorPage"
             Title="EmailValidationBehavior">
    <ContentPage.Resources>
        <Style x:Key="invalidEntryStyle" TargetType="Entry">
            <Setter Property="TextColor" Value="Red" />
        </Style>
    </ContentPage.Resources>

    <Entry VerticalOptions="Center" Margin="32, 0">
        <Entry.Behaviors>
            <xct:EmailValidationBehavior InvalidStyle="{StaticResource invalidEntryStyle}" />
        </Entry.Behaviors>
    </Entry>
</ContentPage>
```

### MultiValidationBehavior
複数の`ValidationBehavior`を組み合わせてバリデーションを行うビヘイビアです。バリデーション毎に`Error`で無効時の値を設定でき、`Errors`で無効と判定されているバリデーションの`Error`の値を取得できます。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.MultiValidationBehaviorPage"
             Title="MultiValidationBehavior">
    <ContentPage.Resources>
        <Style x:Key="invalidEntryStyle" TargetType="Entry">
            <Setter Property="TextColor" Value="Red" />
        </Style>
    </ContentPage.Resources>

    <StackLayout VerticalOptions="Center" Margin="32, 0">
        <Entry>
            <Entry.Behaviors>
                <xct:MultiValidationBehavior x:Name="multiValidationBehavior"
                                             InvalidStyle="{StaticResource invalidEntryStyle}" >
                    <xct:CharactersValidationBehavior CharacterType="Digit"
                                                      MinimumCharacterCount="1"
                                                      xct:MultiValidationBehavior.Error="数字1文字以上" />
                    <xct:CharactersValidationBehavior CharacterType="UppercaseLetter"
                                                      MinimumCharacterCount="1"
                                                      xct:MultiValidationBehavior.Error="大文字1文字以上" />
                    <xct:CharactersValidationBehavior CharacterType="Any"
                                                      MinimumCharacterCount="8"
                                                      xct:MultiValidationBehavior.Error="8文字以上" />
                </xct:MultiValidationBehavior>
            </Entry.Behaviors>
        </Entry>
        <Label Text="{Binding Errors[0], Source={x:Reference multiValidationBehavior}}" />
    </StackLayout>
</ContentPage>
```

### NumericValidationBehavior
数値の範囲や小数点以下の桁数のバリデーションを行うビヘイビアです。`MinimumValue`で最小値、`MaximumValue`で最大値、`MinimumDecimalPlaces`で小数点以下の最小桁数、`MaximumDecimalPlaces`で小数点以下の最大桁数を設定します。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.NumericValidationBehaviorPage"
             Title="NumericValidationBehavior">
    <ContentPage.Resources>
        <Style x:Key="invalidEntryStyle" TargetType="Entry">
            <Setter Property="TextColor" Value="Red" />
        </Style>
    </ContentPage.Resources>

    <Entry VerticalOptions="Center" Margin="32, 0">
        <Entry.Behaviors>
            <xct:NumericValidationBehavior InvalidStyle="{StaticResource invalidEntryStyle}"
                                           MinimumValue="1.0"
                                           MaximumValue="10.0"
                                           MinimumDecimalPlaces="1"
                                           MaximumDecimalPlaces="3" />
        </Entry.Behaviors>
    </Entry>
</ContentPage>
```

### RequiredStringValidationBehavior
指定した文字列が入力されているかどうかのバリデーションを行うビヘイビアです。`RequiredString`で対象の文字列を設定します。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.RequiredStringValidationBehaviorPage"
             Title="RequiredStringValidationBehavior">
    <ContentPage.Resources>
        <Style x:Key="invalidEntryStyle" TargetType="Entry">
            <Setter Property="TextColor" Value="Red" />
        </Style>
    </ContentPage.Resources>

    <Entry VerticalOptions="Center" Margin="32, 0">
        <Entry.Behaviors>
            <xct:RequiredStringValidationBehavior InvalidStyle="{StaticResource invalidEntryStyle}"
                                                  RequiredString="hoge" />
        </Entry.Behaviors>
    </Entry>
</ContentPage>
```

### TextValidationBehavior
文字列の長さや、正規表現によるバリデーションを行うビヘイビアです。`MinimumLength`で最小の長さ、`MaximumLength`最大の長さ、`RegexPattern`で正規表現のパターンを設定できます。また、`DecorationFlags`を設定することで、文字列を加工した後にバリデーションを行うことが可能です。`DecorationFlags`は以下のものが用意されています。

* TrimStart （先頭の空白文字を削除）
* TrimEnd （末尾の空白文字を削除）
* Trim （先頭と末尾の空白文字を削除）
* NullToEmpty （nullを空文字に変換）
* ReduceWhiteSpaces （空白文字を削除）

ちなみに、`CharactersValidationBehavior`、`EmailValidationBehavior`、`UriValidationBehavior`は、`TextValidationBehavior`のサブクラスです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.TextValidationBehaviorPage"
             Title="TextValidationBehavior">
    <ContentPage.Resources>
        <Style x:Key="invalidEntryStyle" TargetType="Entry">
            <Setter Property="TextColor" Value="Red" />
        </Style>
    </ContentPage.Resources>

    <Entry VerticalOptions="Center" Margin="32, 0">
        <Entry.Behaviors>
            <xct:TextValidationBehavior InvalidStyle="{StaticResource invalidEntryStyle}"
                                        MinimumLength="4"
                                        MaximumLength="8"
                                        DecorationFlags="Trim"
                                        RegexPattern="^\w+$" />
        </Entry.Behaviors>
    </Entry>
</ContentPage>
```

### UriValidationBehavior
URIのフォーマットであるかどうかのバリデーションを行うビヘイビアです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.UriValidationBehaviorPage"
             Title="UriValidationBehavior">
    <ContentPage.Resources>
        <Style x:Key="invalidEntryStyle" TargetType="Entry">
            <Setter Property="TextColor" Value="Red" />
        </Style>
    </ContentPage.Resources>

    <Entry VerticalOptions="Center" Margin="32, 0">
        <Entry.Behaviors>
            <xct:UriValidationBehavior InvalidStyle="{StaticResource invalidEntryStyle}" />
        </Entry.Behaviors>
    </Entry>
</ContentPage>
```

# コンバーター
## BoolToObjectConverter
`bool`値を任意の値に変換するコンバーターです。`TrueObject`には`true`の時の値、`FalseObject`には`false`の時の値を設定します。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.BoolToObjectConverterPage"
             Title="BoolToObjectConverter">
    <ContentPage.Resources>
        <xct:BoolToObjectConverter x:Key="boolToObjectConverter"
                                   x:TypeArguments="x:String"
                                   TrueObject="真"
                                   FalseObject="偽"/>
        <x:Boolean x:Key="value">true</x:Boolean>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource boolToObjectConverter}}" />
</ContentPage>
```

## ByteArrayToImageSourceConverter
`byte`配列を`ImageSource`に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.ByteArrayToImageSourceConverterPage"
             Title="ByteArrayToImageSourceConverter">
    <ContentPage.Resources>
        <xct:ByteArrayToImageSourceConverter x:Key="byteArrayToImageSourceConverter" />
    </ContentPage.Resources>

    <Image VerticalOptions="Center" HorizontalOptions="Center"
           Source="{Binding ImageBytes,
                    Converter={StaticResource byteArrayToImageSourceConverter}}" />
</ContentPage>
```

## DateTimeOffsetConverter
`DateTimeOffset`を`DateTime`に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             xmlns:sys="clr-namespace:System;assembly=netstandard"
             x:Class="XamarinCommunityToolkitCatalog.Views.DateTimeOffsetConverterPage"
             Title="DateTimeOffsetConverter">
    <ContentPage.Resources>
        <xct:DateTimeOffsetConverter x:Key="dateTimeOffsetConverter" />
        <sys:DateTimeOffset x:Key="value">
            <x:Arguments>
                <x:Int32>2020</x:Int32>
                <x:Int32>12</x:Int32>
                <x:Int32>16</x:Int32>
                <x:Int32>0</x:Int32>
                <x:Int32>0</x:Int32>
                <x:Int32>0</x:Int32>
                <x:TimeSpan />
            </x:Arguments>
        </sys:DateTimeOffset>
    </ContentPage.Resources>

    <DatePicker VerticalOptions="Center" HorizontalOptions="Center"
                Date="{Binding ., Source={StaticResource value},
                       Converter={StaticResource dateTimeOffsetConverter}}" />
</ContentPage>
```

## DoubleToIntConverter
`double`を`int`に変換するコンバーターです。`Math.Round`で丸められます。パラメーターで、乗数を指定することもできます。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.DoubleToIntConverterPage"
             Title="DoubleToIntConverter">
    <ContentPage.Resources>
        <xct:DoubleToIntConverter x:Key="doubleToIntConverter" />
        <x:Double x:Key="value">1.25</x:Double>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource doubleToIntConverter},
                  ConverterParameter=10}" />
</ContentPage>
```

## EqualConverter
パラメーターの値と等しければ`true`、違っていれば`false`に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.EqualConverterPage"
             Title="EqualConverter">
    <ContentPage.Resources>
        <xct:EqualConverter x:Key="equalConverter" />
        <x:String x:Key="value">value</x:String>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource equalConverter},
                  ConverterParameter=value}" />
</ContentPage>
```

## IndexToArrayItemConverter
パラメーターに設定した`Array`のインデックスの値に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.IndexToArrayItemConverterPage"
             Title="IndexToArrayItemConverter">
    <ContentPage.Resources>
        <xct:IndexToArrayItemConverter x:Key="indexToArrayItemConverter" />
        <x:Int32 x:Key="value">1</x:Int32>
        <x:Array x:Key="array" Type="{x:Type x:String}">
            <x:String>value0</x:String>
            <x:String>value1</x:String>
            <x:String>value2</x:String>
        </x:Array>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource indexToArrayItemConverter},
                  ConverterParameter={StaticResource array}}" />
</ContentPage>
```

## IntToBoolConverter
0なら`false`、0以外なら`true`に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.IntToBoolConverterPage"
             Title="IntToBoolConverter">
    <ContentPage.Resources>
        <xct:IntToBoolConverter x:Key="intToBoolConverter" />
        <x:Int32 x:Key="value">0</x:Int32>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource intToBoolConverter}}" />
</ContentPage>
```

## InvertedBoolConverter
`true`なら`false`、`false`なら`true`に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.InvertedBoolConverterPage"
             Title="InvertedBoolConverter">
    <ContentPage.Resources>
        <xct:InvertedBoolConverter x:Key="invertedBoolConverter" />
        <x:Boolean x:Key="value">true</x:Boolean>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource invertedBoolConverter}}" />
</ContentPage>
```

## IsNotNullOrEmptyConverter
`null`、空文字、空白文字のみではない場合は`true`、それ以外は`false`に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.IsNotNullOrEmptyConverterPage"
             Title="IsNotNullOrEmptyConverter">
    <ContentPage.Resources>
        <xct:IsNotNullOrEmptyConverter x:Key="isNotNullOrEmptyConverter" />
        <x:String x:Key="value">　</x:String>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource isNotNullOrEmptyConverter}}" />
</ContentPage>
```

## IsNullOrEmptyConverter
`null`、空文字、空白文字のみである場合は`true`、それ以外は`false`に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.IsNullOrEmptyConverterPage"
             Title="IsNullOrEmptyConverter">
    <ContentPage.Resources>
        <xct:IsNullOrEmptyConverter x:Key="isNullOrEmptyConverter" />
        <x:String x:Key="value">　</x:String>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource isNullOrEmptyConverter}}" />
</ContentPage>
```

## ItemSelectedEventArgsConverter
`ListView`の`ItemSelected`イベントの引数である`SelectedItemChangedEventArgs`を、そのプロパティである`SelectedItem`の値に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.ItemSelectedEventArgsConverterPage"
             Title="ItemSelectedEventArgsConverter">
    <ContentPage.Resources>
        <xct:ItemSelectedEventArgsConverter x:Key="itemSelectedEventArgsConverter" />
    </ContentPage.Resources>

    <ListView>
        <ListView.ItemsSource>
            <x:Array Type="{x:Type x:String}">
                <x:String>value0</x:String>
                <x:String>value1</x:String>
                <x:String>value2</x:String>
            </x:Array>
        </ListView.ItemsSource>
        <ListView.Behaviors>
            <xct:EventToCommandBehavior EventName="ItemSelected"
                                        Command="{Binding ItemSelectedCommand}"
                                        EventArgsConverter="{StaticResource itemSelectedEventArgsConverter}" />
        </ListView.Behaviors>
    </ListView>
</ContentPage>
```

## ItemTappedEventArgsConverter
`ListView`の`ItemTapped`イベントの引数である`ItemTappedEventArgs`を、そのプロパティである`Item`の値に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.ItemTappedEventArgsConverterPage"
             Title="ItemTappedEventArgsConverter">
    <ContentPage.Resources>
        <xct:ItemTappedEventArgsConverter x:Key="itemTappedEventArgsConverter" />
    </ContentPage.Resources>

    <ListView>
        <ListView.ItemsSource>
            <x:Array Type="{x:Type x:String}">
                <x:String>value0</x:String>
                <x:String>value1</x:String>
                <x:String>value2</x:String>
            </x:Array>
        </ListView.ItemsSource>
        <ListView.Behaviors>
            <xct:EventToCommandBehavior EventName="ItemTapped"
                                        Command="{Binding ItemTappedCommand}"
                                        EventArgsConverter="{StaticResource itemTappedEventArgsConverter}" />
        </ListView.Behaviors>
    </ListView>
</ContentPage>
```

## ListIsNotNullOrEmptyConverter
`null`ではない、もしくは、`IEnumerable`が空ではない場合は`true`、それ以外は`false`に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"
             x:Class="XamarinCommunityToolkitCatalog.Views.ListIsNotNullOrEmptyConverterPage"
             Title="ListIsNotNullOrEmptyConverter">
    <ContentPage.Resources>
        <xct:ListIsNotNullOrEmptyConverter x:Key="listIsNotNullOrEmptyConverter" />
        <scg:List x:Key="value" x:TypeArguments="x:Int32">
            <x:Int32>0</x:Int32>
        </scg:List>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource listIsNotNullOrEmptyConverter}}" />
</ContentPage>
```

## ListIsNullOrEmptyConverter
`null`、もしくは、`IEnumerable`が空である場合は`true`、それ以外は`false`に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"
             x:Class="XamarinCommunityToolkitCatalog.Views.ListIsNullOrEmptyConverterPage"
             Title="ListIsNullOrEmptyConverter">
    <ContentPage.Resources>
        <xct:ListIsNullOrEmptyConverter x:Key="listIsNullOrEmptyConverter" />
        <scg:List x:Key="value" x:TypeArguments="x:Int32">
            <x:Int32>0</x:Int32>
        </scg:List>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource listIsNullOrEmptyConverter}}" />
</ContentPage>
```

## ListToStringConverter
`IEnumerable`の各値を文字列にして、`Separator`もしくはパラメーターで指定した区切り文字を使用して連結した文字列に変換するコンバーターです。区切り文字は、パラメーターで指定した方が優先されます。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"
             x:Class="XamarinCommunityToolkitCatalog.Views.ListToStringConverterPage"
             Title="ListToStringConverter">
    <ContentPage.Resources>
        <xct:ListToStringConverter x:Key="listToStringConverter"
                                   Separator=", " />
        <scg:List x:Key="value" x:TypeArguments="x:String">
            <x:String>value0</x:String>
            <x:String>value1</x:String>
            <x:String>value2</x:String>
        </scg:List>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource listToStringConverter}}" />
</ContentPage>
```

## MultiConverter
複数のコンバーターを順番に適用して変換するコンバーターです。`MultiConverterParameter`で、適用するコンバーター毎にパラメーターを設定することができます。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.MultiConverterPage"
             Title="MultiConverter">
    <ContentPage.Resources>
        <xct:MultiConverter x:Key="multiConverter" >
            <xct:EqualConverter />
            <xct:BoolToObjectConverter x:TypeArguments="x:String"
                                       TrueObject="同じ"
                                       FalseObject="違う" />
        </xct:MultiConverter>
        <x:Array x:Key="multiParams"
                 Type="{x:Type xct:MultiConverterParameter}" >
            <xct:MultiConverterParameter
                ConverterType="{x:Type xct:EqualConverter}"
                Value="value" />
        </x:Array>
        <x:String x:Key="value">value</x:String>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource multiConverter},
                  ConverterParameter={StaticResource multiParams}}" />
</ContentPage>
```

## NotEqualConverter
パラメーターの値と違っていたら`true`、等しければ`false`に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.NotEqualConverterPage"
             Title="NotEqualConverter">
    <ContentPage.Resources>
        <xct:NotEqualConverter x:Key="notEqualConverter" />
        <x:String x:Key="value">value</x:String>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource notEqualConverter},
                  ConverterParameter=value}" />
</ContentPage>
```

## StateToBooleanConverter
`StateToCompare`や、パラメーターで指定した`LayoutState`と等しければ`true`、違っていれば`false`に変換するコンバーターです。`StateToCompare`とパラメーター両方指定した場合は、パラメーターが優先されます。`LayoutState`は、Xamarin Community Toolkitの機能である`StateLayout`で使用されます。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.StateToBooleanConverterPage"
             Title="StateToBooleanConverter">
    <ContentPage.Resources>
        <xct:StateToBooleanConverter x:Key="stateToBooleanConverter"
                                     StateToCompare="Success" />
        <x:Static x:Key="value" Member="xct:LayoutState.Error" />
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource stateToBooleanConverter}}" />
</ContentPage>
```

## TextCaseConverter
文字列を大文字や小文字に変換するコンバーターです。`Type`または、パラメーターで、大文字にする場合は`Upper`、小文字にする場合は`Lower`と指定します。`Type`とパラメーター両方指定した場合は、パラメーターが優先されます。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="XamarinCommunityToolkitCatalog.Views.TextCaseConverterPage"
             Title="TextCaseConverter">
    <ContentPage.Resources>
        <xct:TextCaseConverter x:Key="textCaseConverter"
                               Type="Upper" />
        <x:String x:Key="value">Value</x:String>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource textCaseConverter}}" />
</ContentPage>
```

## TimeSpanToDoubleConverter
`TimeSpan`をそれが表す秒数の合計（`TotalSeconds`）に変換するコンバーターです。

```xml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             xmlns:sys="clr-namespace:System;assembly=netstandard"
             x:Class="XamarinCommunityToolkitCatalog.Views.TimeSpanToDoubleConverterPage"
             Title="TimeSpanToDoubleConverter">
    <ContentPage.Resources>
        <xct:TimeSpanToDoubleConverter x:Key="timeSpanToDoubleConverter" />
        <sys:TimeSpan x:Key="value">
            <x:Arguments>
                <x:Int32>12</x:Int32>
                <x:Int32>30</x:Int32>
                <x:Int32>10</x:Int32>
            </x:Arguments>
        </sys:TimeSpan>
    </ContentPage.Resources>

    <Label VerticalOptions="Center" HorizontalOptions="Center"
           Text="{Binding ., Source={StaticResource value},
                  Converter={StaticResource timeSpanToDoubleConverter}}" />
</ContentPage>
```

# おわりに
Xamarin Community Toolkitのビヘイビア、コンバーターを紹介しました。自分で書こうと思えば簡単に書けるものも多いですが、あるものは積極的に使っていけばいいと思います。