Xamarin.Forms スライダー

Download Sampleサンプルのダウンロード

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

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

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

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

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

警告

内部的には、SliderMinimumMaximum より小さくなるようにします。 MinimumMaximum より小さくならないように MinimumMaximum が設定された場合、例外が発生します。 設定とプロパティの詳細については、以下の「予防措置」セクションをMinimumMaximum参照してください。

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

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

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

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

警告

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

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

Note

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持つ初期化されます。 ハンドラーは、オブジェクトのプロパティをValue使用して最初LabelsliderプロパティをRotation設定し、イベント引数のプロパティを持つNewValueメソッドを使用String.Formatして、2 番目のプロパティをText設定しますLabelValueChangedSlider の現在の 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;

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 番目LabelSliderプロパティと同様Textに、仕様を持つプロパティにStringFormatバインドValueされます。 [基本スライダー バインド] ページの機能は、前の 2 つのページとは少し異なります。ページが最初に表示されると、2 番目Labelのページに値を含むテキスト文字列が表示されます。 これは、データ バインディングを使用する利点です。 データ バインディングなしでテキストを表示するには、LabelText プロパティを具体的に初期化するか、クラス コンストラクターからイベント ハンドラーを呼び出して 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" ... />

MinimumMaximum の値を負の数に設定できますが、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 に設定すると MinimumValue 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作成に関する書籍のカスタム レンダラー 以下StepSliderSlider似ていますが、次の値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 します。

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 の実装の直接的な結果です