Xamarin.Forms ステッパー
"値の範囲から数値を選ぶには、ステッパーを使います。"
Xamarin.FormsStepper
は、マイナス記号とプラス記号の付いた 2 つのボタンで構成されます。 ユーザーはこれらのボタンを操作して、値の範囲から double
値を段階的に選択できます。
Stepper
では、double
型の 4 つのプロパティが定義されています。
Increment
は選択した値を変更する量で、既定値は 1 です。Minimum
は範囲の最小値で、既定値は 0 です。Maximum
は範囲の最大値で、既定値は 100 です。Value
はステッパーの値です。この値はMinimum
からMaximum
までの範囲で指定でき、既定値は 0 です。
これらのプロパティはすべて、BindableProperty
オブジェクトによってサポートされます。 Value
プロパティの既定のバインド モードは BindingMode.TwoWay
で、Model-View-ViewModel (MVVM) アーキテクチャを使うアプリケーションのバインディング ソースとして適していることを意味します。
警告
内部的には、Stepper
は Minimum
が Maximum
より小さくなるようにします。 Minimum
が Maximum
より小さくならないように Minimum
や Maximum
が設定された場合、例外が発生します。 Minimum
および Maximum
プロパティの設定の詳細については、「注意事項」セクションを参照してください。
Stepper
は、Value
プロパティを Minimum
と Maximum
の間になるように強制します(両端の値を含む)。 Minimum
プロパティが Value
プロパティより大きい値に設定されている場合、Stepper
は Value
プロパティを Minimum
に設定します。 同様に、Maximum
が Value
より小さい値に設定されている場合は、Stepper
は Value
プロパティを Maximum
に設定します。
Stepper
は、Stepper
がユーザーによって操作されるか、アプリケーションで Value
プロパティが直接設定されることで、Value
が変化したときに発生する ValueChanged
イベントを定義します。 前の段落で説明したように、Value
プロパティが強制された場合にも ValueChanged
イベントが発生します。
ValueChanged
イベントに付随する ValueChangedEventArgs
オブジェクトには、double
型の 2 つのプロパティ (OldValue
と NewValue
) があります。 イベントが発生した時点では、NewValue
の値は Stepper
オブジェクトの Value
プロパティと同じです。
基本的なステッパー コードとマークアップ
サンプルは、機能的には同じですが、異なる方法で実装された 3 つのページが含まれます。 最初のページでは C# コードのみを使い、2 番目のページではコード内のイベント ハンドラーで XAML を使い、3 番目のページでは XAML ファイル内のデータ バインディングを使ってイベント ハンドラーを回避できます。
コードでのステッパーの作成
サンプルの [基本的なステッパー コード] ページには、コード内に Stepper
と 2 つの Label
オブジェクトを作成する方法が示されています。
public class BasicStepperCodePage : ContentPage
{
public BasicStepperCodePage()
{
Label rotationLabel = new Label
{
Text = "ROTATING TEXT",
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.CenterAndExpand
};
Label displayLabel = new Label
{
Text = "(uninitialized)",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.CenterAndExpand
};
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);
};
Title = "Basic Stepper Code";
Content = new StackLayout
{
Margin = new Thickness(20),
Children = { rotationLabel, stepper, displayLabel }
};
}
}
Stepper
は、Maximum
プロパティが 360、Increment
プロパティが 30 になるように初期化されます。 Stepper
を操作すると、Increment
プロパティの値に基づいて、選択した値が Minimum
から Maximum
まで段階的に変更されます。 Stepper
の ValueChanged
ハンドラーは、stepper
オブジェクトの Value
プロパティを使って最初の Label
の Rotation
プロパティを設定し、string.Format
メソッドをイベント引数の NewValue
プロパティと共に使って 2 番目の Label
の Text
プロパティを設定します。 Stepper
の現在の値を取得するこれらの 2 つの方法は、相互に置き換え可能です。
次のスクリーンショットは、[基本的なステッパー コード] ページを示しています。
2 番目の Label
には、Stepper
が操作されるまで "(初期化されていません)" というテキストが表示されます。これにより、最初の ValueChanged
イベントが発生します。
XAML でのステッパーの作成
[基本的なステッパー XAML] ページは、基本的なステッパー コードと機能的には同じですが、主に XAML で実装されています。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
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="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Stepper Maximum="360"
Increment="30"
HorizontalOptions="Center"
ValueChanged="OnStepperValueChanged" />
<Label x:Name="_displayLabel"
Text="(uninitialized)"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>
分離コード ファイルには、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);
}
}
イベント ハンドラーは、sender
引数でイベントを発生させる Stepper
を取得することもできます。 Value
プロパティは現在値を含みます。
double value = ((Stepper)sender).Value;
XAML ファイル内で Stepper
オブジェクトに x:Name
属性 ("stepper" など) を持つ名前が指定されている場合、イベント ハンドラーはそのオブジェクトを直接参照できます。
double value = stepper.Value;
ステッパーのデータ バインディング
[基本的なステッパー バインディング] ページでは、データ バインディングを使って Value
イベント ハンドラーを除去する、ほぼ同等のアプリケーションを作成する方法を示します。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
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="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<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="CenterAndExpand" />
</StackLayout>
</ContentPage>
最初の Label
の Rotation
プロパティは Stepper
の Value
プロパティにバインドされ、2 番目の Label
の Text
プロパティは StringFormat
の仕様でバインドされています。 [基本的なステッパー バインディング] ページは、前の 2 つのページとは少し異なる形で機能します。ページが最初に表示されると、2 番目の Label
に値を含むテキスト文字列が表示されます。 これは、データ バインディングを使う利点です。 データ バインディングなしでテキストを表示するには、Label
の Text
プロパティを具体的に初期化するか、クラス コンストラクターからイベント ハンドラーを呼び出して 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" ... />
Minimum
と Maximum
の値を負の数に設定できますが、Minimum
が常に Maximum
より小さくなるような順序でのみ設定できます。
<Stepper Minimum="-360"
Maximum="-180" ... />
Value
プロパティは常に Minimum
値以上、Maximum
値以下です。 Value
がその範囲外の値に設定された場合、値は強制的に範囲内に設定されますが、例外は発生しません。 たとえば、次のコードを使っても、例外は発生 "しません"。
Stepper stepper = new Stepper
{
Value = 180
};
その代わりに、Value
プロパティは Maximum
の値が 100 に強制的に設定されます。
上記のコード スニペットを次に示します。
Stepper stepper = new Stepper
{
Maximum = 360,
Minimum = 180
};
Minimum
を 180 に設定すると、Value
も 180 に設定されます。
ValueChanged
イベント ハンドラーが、Value
プロパティが既定値 0 以外の値に強制された時点ですでにアタッチされていた場合、ValueChanged
イベントが発生します。 XAML のスニペットを次に示します。
<Stepper ValueChanged="OnStepperValueChanged"
Maximum="360"
Minimum="180" />
Minimum
を 180 に設定すると、Value
も 180 に設定され、ValueChanged
イベントが発生します。 これは、ページの残りの部分が作成される前に発生する可能性があり、ハンドラーは、まだ作成されていないページ上の他の要素を参照しようとする可能性があります。 ページ上の他の要素の null
値をチェックするコードを、ValueChanged
ハンドラーに追加できます。 または、Stepper
の値が初期化された後に ValueChanged
イベント ハンドラーを設定することもできます。