ステッパ

.NET Multi-platform App UI (.NET MAUI) Stepper を使用すると、値の範囲から数値を選択できます。 これは、マイナス記号とプラス記号の付いた 2 つのボタンで構成されます。 ユーザーはこれらのボタンを操作して、値の範囲から double 値を段階的に選択できます。

Stepper では、double 型の 4 つのプロパティが定義されています。

  • Increment は、選択した値を変更する量で、既定値は 1 です。
  • Minimum は範囲の最小値で、既定値は 0 です。
  • Maximum は範囲の最大値で、既定値は 100 です。
  • Value はステッパーの値です。この値の範囲は MinimumMaximum の間で、既定値は 0 です。

これらのプロパティはすべて、BindableProperty オブジェクトによってサポートされています。 Value プロパティの既定のバインディング モードは BindingMode.TwoWay です。これは、Model-View-ViewModel (MVVM) パターンを使用するアプリケーションのバインディング ソースとして適していることを意味します。

Stepper は、Value プロパティを MinimumMaximum の間になるように強制します。 Minimum プロパティが Value プロパティより大きい値に設定されている場合、StepperValue プロパティを Minimum に設定します。 同様に、MaximumValue より小さい値に設定されている場合、StepperValue プロパティを Maximum に設定します。 内部的には、Stepper により、MinimumMaximum 未満であることが保証されます。 もし MinimumMaximum より小さくならないように MinimumMaximum が設定された場合、例外が発生します。 Minimum および Maximum プロパティの設定の詳細については、「注意事項」を参照してください。

Stepper は、Stepper のユーザー操作によって、またはアプリケーションが Value プロパティを直接設定することによって、Value が変更されたときに発生する ValueChanged イベントを定義します。 ValueChanged イベントは、前述のように Value プロパティが強制された場合にも発生します。 ValueChanged イベントに付随する ValueChangedEventArgs オブジェクトには、double 型の OldValueNewValue があります。 イベントが発生した時点では、NewValue の値は Stepper オブジェクトの Value プロパティと同じです。

ステッパーの作成

2 つの Label オブジェクトで Stepper を作成する方法の例を次に示します。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="StepperDemo.BasicStepperXAMLPage"
             Title="Basic Stepper XAML">
    <StackLayout Margin="20">
        <Label x:Name="_rotatingLabel"
               Text="ROTATING TEXT"
               FontSize="18"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
        <Stepper Maximum="360"
                 Increment="30"
                 HorizontalOptions="Center"
                 ValueChanged="OnStepperValueChanged" />
        <Label x:Name="_displayLabel"
               Text="(uninitialized)"
               HorizontalOptions="Center"
               VerticalOptions="Center" />        
    </StackLayout>
</ContentPage>

この例では、Stepper は、Maximum プロパティ 360、Increment プロパティ 30 を持つように初期化されています。 Stepper を操作すると、Increment プロパティの値に基づいて、選択した値が Minimum から Maximum まで段階的に変更されます。 2 番目の Label は、Stepper が操作されるまでテキスト「(初期化されていない)」を表示します。これにより、最初の ValueChanged イベントが発生します。

分離コード ファイルには、ValueChanged イベントのハンドラーが含まれています。

public partial class BasicStepperXAMLPage : ContentPage
{
    public BasicStepperXAMLPage()
    {
        InitializeComponent();
    }

    void OnStepperValueChanged(object sender, ValueChangedEventArgs e)
    {
        double value = e.NewValue;
        _rotatingLabel.Rotation = value;
        _displayLabel.Text = string.Format("The Stepper value is {0}", value);
    }
}

StepperValueChanged ハンドラーは、stepper オブジェクトの Value プロパティを使用して、最初の LabelRotation プロパティを設定し、string.Format メソッドを使用します。 イベント引数の NewValue プロパティを使用して、2番目の LabelText プロパティを設定します。

.NET MAUI Stepper screenshot.

イベント ハンドラーは、sender 引数を介してイベントを発生させる Stepper を取得することもできます。 Value プロパティは現在値を含みます。

double value = ((Stepper)sender).Value;

XAML ファイル内で Stepper オブジェクトに x:Name 属性を持つ名前が指定されている場合 (「stepper」など)、イベント ハンドラーはそのオブジェクトを直接参照できます。

double value = stepper.Value;

Stepper を作成するための同等の C# コードは次のとおりです。

Stepper stepper = new Stepper
{
    Maximum = 360,
    Increment = 30,
    HorizontalOptions = LayoutOptions.Center
};
stepper.ValueChanged += (sender, e) =>
{
    rotationLabel.Rotation = stepper.Value;
    displayLabel.Text = string.Format("The Stepper value is {0}", e.NewValue);
};

ステッパーをバインドするデータ

ValueChanged イベント ハンドラーは、データ バインディングを使用して Stepper 値の変更に応答することで削除できます。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="StepperDemo.BasicStepperBindingsPage"
             Title="Basic Stepper Bindings">
    <StackLayout Margin="20">
        <Label Text="ROTATING TEXT"
               Rotation="{Binding Source={x:Reference _stepper}, Path=Value}"
               FontSize="18"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
        <Stepper x:Name="_stepper"
                 Maximum="360"
                 Increment="30"
                 HorizontalOptions="Center" />
        <Label Text="{Binding Source={x:Reference _stepper}, Path=Value, StringFormat='The Stepper value is {0:F0}'}"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

この例では、最初の LabelRotation プロパティは、StepperValue プロパティにバインドされており、2 番目の LabelText プロパティも StringFormat 仕様でバインドされています。 ページが最初に表示されると、2 番目の Label には値を含むテキスト文字列が表示されます。 データ バインディングなしでテキストを表示するには、LabelText プロパティを具体的に初期化するか、クラス コンストラクターからイベント ハンドラーを呼び出して ValueChanged イベントの発生をシミュレートする必要があります。

注意事項

Minimum プロパティの値は常に、Maximum プロパティの値より小さくする必要があります。 次のコード例では、Stepper に例外が発生します。

// Throws an exception!
Stepper stepper = new Stepper
{
    Minimum = 180,
    Maximum = 360
};

C# コンパイラは、これら 2 つのプロパティを順番に設定するコードを生成します。Minimum プロパティが 180 に設定されている場合、この値は規定値の Maximum である 100 よりも大きくなります。 この場合、最初に Maximum プロパティを設定することで例外を回避できます。

Stepper stepper = new Stepper
{
    Maximum = 360,
    Minimum = 180
};

この例では、Maximum を 360 に設定しても問題はありません。これは、既定値の Minimum 値である 0 よりも大きいためです。 Minimum が設定されている場合、値は Maximum の値 360 より小さくなります。

XAML でも同じ問題が存在します。 Maximum が常に Minimum より大きくなる順序でプロパティを設定します。

<Stepper Maximum="360"
         Minimum="180" ... />

MinimumMaximum の値は負の数に設定できますが、Minimum が常に Maximum より小さくなる順序でのみ設定できます。

<Stepper Minimum="-360"
         Maximum="-180" ... />

Value プロパティは常に Minimum 値以上、Maximum 値以下になります。 Value がその範囲外の値に設定されている場合、値は強制的に範囲内に設定されますが、例外は発生しません。 たとえば、次のコードでは例外は発生しません。

Stepper stepper = new Stepper
{
    Value = 180
};

その代わりに、Value プロパティは Maximum の値が 100 に強制的に設定されます。

前の例では Maximum を 360 に、Minimum を 180 に設定しました。

Stepper stepper = new Stepper
{
    Maximum = 360,
    Minimum = 180
};

Minimum を 180 に設定すると、Value も 180 に設定されます。

Value プロパティが既定値の 0 以外の値に強制された時点で ValueChanged イベント ハンドラーがアタッチされている場合、ValueChanged イベントが発生します。

<Stepper ValueChanged="OnStepperValueChanged"
         Maximum="360"
         Minimum="180" />

Minimum を 180 に設定すると、Value も 180 に設定され、ValueChanged イベントが発生します。 これは、ページの残りの部分が構築される前に発生する可能性があり、ハンドラーは、まだ作成されていないページ上の他の要素を参照しようとする可能性があります。 ページ上の他の要素の null 値をチェックするコードを、ValueChanged ハンドラーに追加できます。 または、Stepper 値が初期化された後に ValueChanged イベント ハンドラーを設定することもできます。