Xamarin.Forms スライダー
連続する値の範囲から選択する場合は、スライダーを使用します。
これは Xamarin.FormsSlider
、ユーザーが連続範囲から値を選択 double
するために操作できる水平バーです。
型の Slider
3 つのプロパティを double
定義します。
Minimum
は範囲の最小値で、既定値は 0 です。Maximum
は範囲の最大値で、既定値は 1 です。Value
はスライダーの値で、範囲を指定Minimum
Maximum
でき、既定値は 0 です。
3 つのプロパティはすべてオブジェクトによって BindableProperty
サポートされます。 このValue
プロパティの既定のBindingMode.TwoWay
バインド モードは、Model-View-ViewModel (MVVM) アーキテクチャを使用するアプリケーションのバインディング ソースとして適していることを意味します。
警告
内部的には、Slider
は Minimum
が Maximum
より小さくなるようにします。 Minimum
が Maximum
より小さくならないように Minimum
や Maximum
が設定された場合、例外が発生します。 設定とプロパティの詳細については、以下の「予防措置」セクションをMinimum
Maximum
参照してください。
Slider
は、Value
プロパティを Minimum
と Maximum
の間になるように強制します(両端の値を含む)。 Minimum
プロパティが Value
プロパティより大きい値に設定されている場合、Slider
は Value
プロパティを Minimum
に設定します。 同様に、Maximum
が Value
より小さい値に設定されている場合は、Slider
は Value
プロパティを Maximum
に設定します。
Slider
は、ValueChanged
ユーザーによる操作Slider
によって、またはプログラムがプロパティをValue
直接設定したときに、変更時に発生するイベントをValue
定義します。 前の ValueChanged
段落で説明したようにプロパティが Value
強制されると、イベントも発生します。
イベントに付随するオブジェクトにはValueChangedEventArgs
、次の 2 つのプロパティがあります。型double
OldValue
は次のとおりですNewValue
。ValueChanged
イベントが発生した時点では、値はNewValue
オブジェクトのSlider
プロパティとValue
同じです。
Slider
では、ドラッグ アクションの DragStarted
先頭と末尾に発生するイベントも定義されます DragCompleted
。 ValueChanged
イベントとは異なり、イベントDragStarted
はDragCompleted
ユーザー操作によってのみ発生しますSlider
。 DragStarted
イベントが発生すると、ICommand
型の DragStartedCommand
を実行します。 同様に、DragCompleted
イベントが発生すると、ICommand
型の DragCompletedCommand
をが実行します。
警告
Slider
で、Center
、Start
、End
の制約のない水平レイアウト オプションを使用しないでください。 Android と UWP の両方で、 Slider
長さが 0 のバーに折りたたまれます。iOS では、バーは非常に短くなります。 Fill
の既定の HorizontalOptions
設定をそのまま使用し、Grid
レイアウトに Slider
を配置する場合は、Auto
の幅を使用しないでください。
また、 Slider
外観に影響を与えるいくつかのプロパティも定義します。
MinimumTrackColor
は、親指の左側のバーの色です。MaximumTrackColor
は、親指の右側のバーの色です。ThumbColor
は親指の色です。ThumbImageSource
は、種類ImageSource
のサムに使用する画像です。
Note
ThumbColor
と ThumbImageSource
のプロパティは相互に排他的です。 両方が設定されている場合、ThumbImageSource
プロパティが優先されます。
基本的なスライダーのコードとマークアップ
SliderDemos サンプルは、機能的には同じ 3 つのページから始まりますが、さまざまな方法で実装されています。 最初のページでは C# コードのみを使用し、2 番目のページではコード内のイベント ハンドラーと共に XAML を使用し、3 番目のページでは XAML ファイル内のデータ バインディングを使用してイベント ハンドラーを回避できます。
コードでのスライダーの作成
SliderDemos サンプルの [基本的なスライダー コード] ページには、コード内に 1 つのオブジェクトと 2 つのLabel
オブジェクトをSlider
作成する方法が示されています。
public class BasicSliderCodePage : ContentPage
{
public BasicSliderCodePage()
{
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
};
Slider slider = new Slider
{
Maximum = 360
};
slider.ValueChanged += (sender, args) =>
{
rotationLabel.Rotation = slider.Value;
displayLabel.Text = String.Format("The Slider value is {0}", args.NewValue);
};
Title = "Basic Slider Code";
Padding = new Thickness(10, 0);
Content = new StackLayout
{
Children =
{
rotationLabel,
slider,
displayLabel
}
};
}
}
Slider
360 のプロパティをMaximum
持つ初期化されます。 ハンドラーは、オブジェクトのプロパティをValue
使用して最初Label
のslider
プロパティをRotation
設定し、イベント引数のプロパティを持つNewValue
メソッドを使用String.Format
して、2 番目のプロパティをText
設定しますLabel
。ValueChanged
Slider
の現在の Slider
値を取得するためのこれら2つのアプローチは交換可能である。
iOS および Android デバイスで実行されているプログラムを次に示します。
2 つ目 Label
は、操作されるまで Slider
"(初期化されていない)" というテキストを表示します。これにより、最初 ValueChanged
のイベントが発生します。 表示される小数点以下の桁数はプラットフォームごとに異なっています。 これらの違いは、プラットフォームの Slider
実装に関連しており、この記事の「プラットフォーム実装の違い」セクション で後述します。
XAML でのスライダーの作成
基本的なスライダー XAML ページは、基本的なスライダー コードと機能的には同じですが、主に XAML で実装されます。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SliderDemos.BasicSliderXamlPage"
Title="Basic Slider XAML"
Padding="10, 0">
<StackLayout>
<Label x:Name="rotatingLabel"
Text="ROTATING TEXT"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Slider Maximum="360"
ValueChanged="OnSliderValueChanged" />
<Label x:Name="displayLabel"
Text="(uninitialized)"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>
分離コード ファイルには、ValueChanged
イベントのハンドラーが含まれます。
public partial class BasicSliderXamlPage : ContentPage
{
public BasicSliderXamlPage()
{
InitializeComponent();
}
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
double value = args.NewValue;
rotatingLabel.Rotation = value;
displayLabel.Text = String.Format("The Slider value is {0}", value);
}
}
イベント ハンドラーは、sender
引数でイベントを発生させる Slider
を取得することもできます。 Value
プロパティは現在値を含みます。
double value = ((Slider)sender).Value;
XAML ファイルで x:Name
属性 ("slider" など) を持つ名前が Slider
オブジェクトに指定されている場合、イベント ハンドラーはそのオブジェクトを直接参照できます。
double value = slider.Value;
スライダーのデータ バインディング
[基本的なスライダー バインド] ページには、データ バインディングを使用してイベント ハンドラーを排除する、ほぼ同等のプログラムをValue
記述する方法が示されています。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SliderDemos.BasicSliderBindingsPage"
Title="Basic Slider Bindings"
Padding="10, 0">
<StackLayout>
<Label Text="ROTATING TEXT"
Rotation="{Binding Source={x:Reference slider},
Path=Value}"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Slider x:Name="slider"
Maximum="360" />
<Label x:Name="displayLabel"
Text="{Binding Source={x:Reference slider},
Path=Value,
StringFormat='The Slider value is {0:F0}'}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>
最初Label
のプロパティはRotation
、2 番目Label
のSlider
プロパティと同様Text
に、仕様を持つプロパティにStringFormat
バインドValue
されます。 [基本スライダー バインド] ページの機能は、前の 2 つのページとは少し異なります。ページが最初に表示されると、2 番目Label
のページに値を含むテキスト文字列が表示されます。 これは、データ バインディングを使用する利点です。 データ バインディングなしでテキストを表示するには、Label
の Text
プロパティを具体的に初期化するか、クラス コンストラクターからイベント ハンドラーを呼び出して ValueChanged
イベントの発生をシミュレートする必要があります。
注意事項
Minimum
プロパティの値は常に、Maximum
プロパティの値より小さくする必要があります。 次のコード スニペットを使用すると、例外が Slider
発生します。
// Throws an exception!
Slider slider = new Slider
{
Minimum = 10,
Maximum = 20
};
C# コンパイラは、これら 2 つのプロパティを順番に設定するコードを生成します。Minimum
プロパティを 10 に設定すると、Maximum
の既定値 1 より大きくなります。 この場合、最初に Maximum
プロパティを設定することで例外を回避できます。
Slider slider = new Slider
{
Maximum = 20,
Minimum = 10
};
既定値の 0 より大きいため、20 にMinimum
設定Maximum
しても問題ありません。 Minimum
を設定すると、この値は Maximum
の値 20 より小さくなります。
XAML でも同じ問題が存在します。 Maximum
が常に Minimum
より大きくなる順序でプロパティを設定します。
<Slider Maximum="20"
Minimum="10" ... />
Minimum
と Maximum
の値を負の数に設定できますが、Minimum
が常に Maximum
より小さくなるような順序でのみ設定できます。
<Slider Minimum="-20"
Maximum="-10" ... />
Value
プロパティは常に Minimum
値以上、Maximum
値以下です。 Value
がその範囲外の値に設定された場合、値は強制的に範囲内に設定されますが、例外は発生しません。 たとえば、次のコードでは例外は 発生しません 。
Slider slider = new Slider
{
Value = 10
};
代わりに、Value
プロパティは、Maximum
値の 1 に強制的に設定されます。
上記のコード スニペットを次に示します。
Slider slider = new Slider
{
Maximum = 20,
Minimum = 10
};
Minimum
を 10 に設定した場合、Value
も 10 に設定されます。
ValueChanged
プロパティが既定値の 0 以外の値に強制された時点Value
でイベント ハンドラーがアタッチされている場合ValueChanged
は、イベントが発生します。 XAML のスニペットを次に示します。
<Slider ValueChanged="OnSliderValueChanged"
Maximum="20"
Minimum="10" />
10 に設定すると Minimum
、 Value
10 にも設定され、イベントが発生します ValueChanged
。 これは、ページの残りの部分が作成される前に発生する可能性があり、ハンドラーは、まだ作成されていないページ上の他の要素を参照しようとする可能性があります。 ページ上の他の要素の null
値をチェックするコードを、ValueChanged
ハンドラーに追加できます。 または、Slider
の値が初期化された後に ValueChanged
イベント ハンドラーを設定することもできます。
プラットフォーム実装の違い
前に示したスクリーンショットでは、小数点の数が Slider
異なる値が表示されます。 これは、Android および UWP プラットフォームでの実装方法 Slider
に関連します。
Android の実装
Android の Slider
実装は Android SeekBar
に基づいており、常にプロパティを Max
1000 に設定します。 これは、Android 上の Slider
個別の値が 1,001 個だけであることを意味します。 a Minimum
を 0 に設定し、a Maximum
を 5000 に設定Slider
したSlider
場合、操作時Value
にプロパティの値は 0、5、10、15 などになります。
UWP の実装
UWP の Slider
実装は、UWP Slider
コントロールに基づいています。 UWP Slider
のプロパティはStepFrequency
、プロパティとMinimum
プロパティのMaximum
差を 10 で除算したものの、1 より大きく設定されていません。
たとえば、既定の範囲の 0 から 1 の場合、 StepFrequency
プロパティは 0.1 に設定されます。 Slider
操作されると、Value
プロパティは 0、0.1、0.2、0.3、0.4、0.5、0.6、0.7、0.8、0.9、1.0 に制限されます。 (これは、次のページの最後のページで明らかです。SliderDemos サンプル)。)プロパティとプロパティのMaximum
差が 10 以上の場合は StepFrequency
1 に設定されValue
、プロパティには整数値が設定Minimum
されます。
StepSlider ソリューション
より汎用性の高い方法StepSlider
については、第 27 章で説明します。モバイル アプリXamarin.Formsの作成に関する書籍のカスタム レンダラー 以下StepSlider
にSlider
似ていますが、次の値Minimum
の数を指定するプロパティを追加Steps
しますMaximum
。
色を選択するためのスライダー
SliderDemos サンプルの最後の 2 ページでは、どちらも 3 つのSlider
インスタンスを使用して色を選択します。 最初のページは分離コード ファイル内のすべての操作を処理し、2 番目のページでは ViewModel でデータ バインディングを使用する方法を示します。
分離コード ファイルでのスライダーの処理
[RGB カラー スライダー] ページでは、色を表示する aBoxView
、色の赤、緑、青のコンポーネントを選択する 3 つのSlider
インスタンス、およびこれらの色値を表示するための 3 つのLabel
要素がインスタンス化されます。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SliderDemos.RgbColorSlidersPage"
Title="RGB Color Sliders">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Slider">
<Setter Property="Maximum" Value="255" />
</Style>
<Style TargetType="Label">
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout Margin="10">
<BoxView x:Name="boxView"
Color="Black"
VerticalOptions="FillAndExpand" />
<Slider x:Name="redSlider"
ValueChanged="OnSliderValueChanged" />
<Label x:Name="redLabel" />
<Slider x:Name="greenSlider"
ValueChanged="OnSliderValueChanged" />
<Label x:Name="greenLabel" />
<Slider x:Name="blueSlider"
ValueChanged="OnSliderValueChanged" />
<Label x:Name="blueLabel" />
</StackLayout>
</ContentPage>
A Style
は、3 つの Slider
要素すべてに 0 から 255 の範囲を与えます。 要素は Slider
、分離コード ファイルに実装されている同じ ValueChanged
ハンドラーを共有します。
public partial class RgbColorSlidersPage : ContentPage
{
public RgbColorSlidersPage()
{
InitializeComponent();
}
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
if (sender == redSlider)
{
redLabel.Text = String.Format("Red = {0:X2}", (int)args.NewValue);
}
else if (sender == greenSlider)
{
greenLabel.Text = String.Format("Green = {0:X2}", (int)args.NewValue);
}
else if (sender == blueSlider)
{
blueLabel.Text = String.Format("Blue = {0:X2}", (int)args.NewValue);
}
boxView.Color = Color.FromRgb((int)redSlider.Value,
(int)greenSlider.Value,
(int)blueSlider.Value);
}
}
最初のセクションでは、 Text
インスタンスの 1 つのプロパティを Label
、16 進数の値を示す短いテキスト文字列に Slider
設定します。 次に、3 つの Slider
インスタンスすべてにアクセスして、RGB コンポーネントから値を作成 Color
します。
スライダーを ViewModel にバインドする
HSL カラー スライダー ページでは、ViewModel を使用して、色相、彩度、および明度の値から値をColor
作成するために使用される計算を実行する方法を示します。 すべての ViewModel と同様に、クラスは HSLColorViewModel
インターフェイスを INotifyPropertyChanged
実装し、プロパティのいずれかが変更されるたびにイベントを発生 PropertyChanged
させます。
public class HslColorViewModel : INotifyPropertyChanged
{
Color color;
public event PropertyChangedEventHandler PropertyChanged;
public double Hue
{
set
{
if (color.Hue != value)
{
Color = Color.FromHsla(value, color.Saturation, color.Luminosity);
}
}
get
{
return color.Hue;
}
}
public double Saturation
{
set
{
if (color.Saturation != value)
{
Color = Color.FromHsla(color.Hue, value, color.Luminosity);
}
}
get
{
return color.Saturation;
}
}
public double Luminosity
{
set
{
if (color.Luminosity != value)
{
Color = Color.FromHsla(color.Hue, color.Saturation, value);
}
}
get
{
return color.Luminosity;
}
}
public Color Color
{
set
{
if (color != value)
{
color = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Hue"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Saturation"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Luminosity"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Color"));
}
}
get
{
return color;
}
}
}
ViewModel とINotifyPropertyChanged
インターフェイスについては、データ バインディングに関する記事で説明します。
HslColorSlidersPage.xaml ファイルは、ページをHslColorViewModel
インスタンス化し、ページのBindingContext
プロパティに設定します。 これにより、XAML ファイル内のすべての要素を ViewModel のプロパティにバインドできます。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SliderDemos"
x:Class="SliderDemos.HslColorSlidersPage"
Title="HSL Color Sliders">
<ContentPage.BindingContext>
<local:HslColorViewModel Color="Chocolate" />
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Label">
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout Margin="10">
<BoxView Color="{Binding Color}"
VerticalOptions="FillAndExpand" />
<Slider Value="{Binding Hue}" />
<Label Text="{Binding Hue, StringFormat='Hue = {0:F2}'}" />
<Slider Value="{Binding Saturation}" />
<Label Text="{Binding Saturation, StringFormat='Saturation = {0:F2}'}" />
<Slider Value="{Binding Luminosity}" />
<Label Text="{Binding Luminosity, StringFormat='Luminosity = {0:F2}'}" />
</StackLayout>
</ContentPage>
要素が Slider
操作されると、 BoxView
ViewModel から要素と Label
要素が更新されます。
マークアップ拡張のBinding
コンポーネントはStringFormat
、小数点以下 2 桁を表示する "F2" の形式に設定されます。 (データ バインディングでの文字列の書式設定については、この記事 で説明します。文字列の書式設定。)ただし、プログラムの UWP バージョンは、0、0.1、0.2、..の値に制限されています。0.9、1.0。 これは、「プラットフォーム実装の違い」セクションで前述したように、UWP Slider
の実装の直接的な結果です。