Xamarin.Forms スライダー

Download Sample サンプルをダウンロードします

連続する値の範囲から選択する場合は、スライダーを使用します。

これは Xamarin.FormsSlider 、ユーザーが連続範囲から値を選択 double するために操作できる水平バーです。

次の Slider 3 つの型のプロパティを定義します double

  • Minimum は範囲の最小値で、既定値は 0 です。
  • Maximum は範囲の最大値で、既定値は 1 です。
  • Valueはスライダーの値で、MinimumMaximum範囲は 0 で、既定値は 0 です。

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

警告

内部的にはSlider、以下であることをMinimumMaximum保証します。 それ以上に設定されている場合、またはMaximumそれ以上Maximumに設定Minimumされている場合Minimumは、例外が発生します。 設定とMaximumプロパティの詳細については、以下の「注意事項」セクションをMinimum参照してください。

プロパティはSlider、その間MinimumMaximum、両端を含む値になるように強制Valueされます。 プロパティが Minimum プロパティより Value 大きい値に設定されている場合、プロパティは SliderValueMinimum. 同様に、より小さい値に設定されている場合Maximumは、SliderプロパティMaximumValue .Value

Sliderは、ValueChangedユーザーによる操作Sliderによって、またはプログラムがプロパティをValue直接設定したときに、変更時に発生するイベントをValue定義します。 前の ValueChanged 段落で説明したようにプロパティが Value 強制されると、イベントも発生します。

イベントに付随ValueChangedするオブジェクトにはValueChangedEventArgs、次の 2 つのプロパティがあります。型doubleは次のとおりですNewValueOldValue イベントが発生した時点では、値NewValueはオブジェクトのSliderプロパティとValue同じです。

Slider では、ドラッグ アクションの DragStarted 先頭と DragCompleted 末尾で発生するイベントも定義および定義されます。 ValueChangedイベントとは異なり、イベントDragStartedDragCompletedユーザーによる操作によってのみ発生しますSlider。 イベントが DragStarted 発生すると、 DragStartedCommandICommandの 、が実行されます。 同様に、イベントが DragCompleted 発生すると、 DragCompletedCommandICommandの 、が実行されます。

警告

の制約のない水平レイアウト オプションCenterStartEndSliderを使用しないでください。 Android と UWP の両方で、 Slider 長さが 0 のバーに折りたたまれます。iOS では、バーは非常に短くなります。 レイアウトを配置する場合は、既定HorizontalOptionsFill設定をそのまま使用し、幅AutoSliderGrid使用しないでください。

また、 Slider 外観に影響を与えるいくつかのプロパティも定義します。

注意

プロパティ ThumbColorThumbImageSource プロパティは相互に排他的です。 両方のプロパティが設定されている場合は、 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 初期化されます。 ハンドラーは、オブジェクトのプロパティをsliderValue使用して最初LabelのプロパティをRotation設定し、イベント引数のプロパティを持つNewValueメソッドを使用String.Formatして 2 番目LabelのプロパティをText設定します。ValueChangedSlider の現在の値 Slider を取得するためのこれら2つのアプローチは交換可能である。

iOS および Android デバイスで実行されているプログラムを次に示します。

Basic Slider Code

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;

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

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、仕様をValue持つ 2 番目のSliderプロパティと同様にText、プロパティLabelのプロパティにStringFormatバインドされます。 [基本スライダー バインド] ページの機能は、前の 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 、値が 20 未満 Maximum になります。

XAML でも同じ問題が存在します。 プロパティは、常に次の値を超MinimumえるMaximum順序で設定します。

<Slider Maximum="20"
        Minimum="10" ... />

値とMaximum値は負のMinimum数値に設定できますが、常に次の値よりMaximum小さい順序Minimumでのみ設定できます。

<Slider Minimum="-20"
        Maximum="-10" ... />

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

Slider slider = new Slider
{
    Value = 10
};

代わりに、プロパティの Value 値は 1 に Maximum 強制されます。

上記のコード スニペットを次に示します。

Slider slider = new Slider
{
    Maximum = 20,
    Minimum = 10
};

10 に設定すると MinimumValue 10 にも設定されます。

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

<Slider ValueChanged="OnSliderValueChanged"
        Maximum="20"
        Minimum="10" />

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

プラットフォーム実装の違い

前に示したスクリーンショットでは、小数点の数が 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 に設定されます。 操作中、SliderValueプロパティは 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.FormsStepSlider似ていますSliderが、プロパティをSteps追加して、値MinimumMaximumの数を指定します。

色を選択するためのスライダー

SliderDemos サンプルの最後の 2 ページでは、どちらも 3 つのSliderインスタンスを使用して色を選択します。 最初のページは分離コード ファイル内のすべての操作を処理します。2 番目のページでは、ViewModel でデータ バインディングを使用する方法を示します。

分離コード ファイルでのスライダーの処理

[RGB カラー スライダー] ページでは、色を表示するインスタンスをBoxViewインスタンス化し、色の赤、緑、青のコンポーネントを選択する 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 します。

RGB Color Sliders

スライダーを 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 要素が更新されます。

HSL Color Sliders

マークアップ拡張機能のBindingコンポーネントはStringFormat、小数点以下 2 桁を表示する "F2" の形式に設定されます。 (データ バインディングの文字列書式については、「 文字列の書式設定」を参照してください)。ただし、プログラムの UWP バージョンは、0、0.1、0.2、..の値に制限されています。0.9、1.0。 これは、「プラットフォームの実装の違い」セクションで説明したように、UWP Slider の実装の直接的な結果です。