共用方式為


Xamarin.Forms 滑桿

使用滑桿從連續值範圍選取。

Xamarin.FormsSlider是水平橫條,可由使用者操作,從連續範圍中選取double值。

定義 Slider 類型的三個 double屬性:

  • Minimum 是範圍的最小值,預設值為0。
  • Maximum 是範圍上限,預設值為1。
  • Value是滑桿的值,可介於 和 Maximum 之間Minimum,且預設值為 0。

這三個屬性都是由 BindableProperty 物件所支援。 屬性Value的預設系結模式BindingMode.TwoWay為 ,這表示它適合做為使用Model-View-ViewModel (MVVM) 架構之應用程式中的系結來源。

警告

在內部, Slider 可確保 Minimum 小於 Maximum。 如果 Minimum 已設定 或 Maximum ,使其 Minimum 不小於 Maximum,則會引發例外狀況。 如需設定 MinimumMaximum 屬性的詳細資訊,請參閱下面的預防措施一節。

Value強制Slider屬性,使其介於和 Maximum之間Minimum,並包含 。 如果 屬性 Minimum 設定為大於 Value 屬性的值,會將 Slider Value 屬性設定為 Minimum。 同樣地,如果 Maximum 設定為小於 Value的值,則將 Slider 屬性設定 ValueMaximum

Slider 定義 ValueChanged 在變更時 Value 引發的事件,無論是透過使用者操作 Slider ,還是程式直接設定 Value 屬性時引發。 ValueChanged當 屬性強制執行時Value,也會引發事件,如上一段所述。

事件 ValueChangedEventArgs 隨附 ValueChanged 的物件有兩個 double屬性,類型為 : OldValueNewValue。 在引發事件時, NewValue 的值會與 Value 對象的屬性 Slider 相同。

Slider 也會定義 DragStartedDragCompleted 事件,這些事件會在拖曳動作的開頭和結尾引發。 ValueChanged與事件不同,DragStartedDragCompleted 事件只會透過使用者操作 Slider引發。 DragStarted當事件引發時,DragStartedCommand會執行 類型 ICommand為的 。 同樣地,當事件引發時 DragCompletedDragCompletedCommand會執行 類型 ICommand為 的 。

警告

請勿使用、 StartEndSlider不受限制的水準版面配置選項Center。 在 Android 和 UWP 上,折 Slider 疊成長度為零的條形圖,而 iOS 上,條形圖非常短。 保留的預設HorizontalOptions設定,且不要在配置中時SliderGrid使用的寬度AutoFill

Slider也會定義影響其外觀的數個屬性:

注意

ThumbColorThumbImageSource 屬性互斥。 如果同時設定這兩個屬性,屬性 ThumbImageSource 會優先使用。

基本滑桿程式代碼和標記

此範例的開頭為三個功能完全相同的頁面,但會以不同的方式實作。 第一頁只使用 C# 程式代碼,第二個使用 XAML 搭配程式碼中的事件處理程式,第三個頁面可以使用 XAML 檔案中的數據系結來避免事件處理程式。

在程式代碼中建立滑桿

[基本滑桿代碼] 頁面會顯示在程式碼中建立 和 兩LabelSlider 對象的顯示:

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初始化 為具有 Maximum 360 的 屬性。 的ValueChangedSlider處理程式會使用 Value 對象的 屬性slider來設定Rotation第一Label個 的屬性,並使用 String.Format 方法搭配NewValue事件自變數的 屬性來設定Text第二Label個 的屬性。 這兩種方法可交換取得 的目前值 Slider

以下是在 iOS 和 Android 裝置上執行的程式:

基本滑桿程序代碼

第二個 Label 會顯示文字 “(uninitialized)”,直到 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如果物件在具有屬性的 XAML 檔案x:Name中指定名稱(例如 “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>

Rotation 一個 Label 的 屬性會系結至 ValueSlider屬性,如同 Text 第二 LabelStringFormat 具有規格的 屬性。 [ 基本滑桿系結 ] 頁面的運作方式與前兩頁稍有不同:第一頁出現時,第二個 Label 頁面會顯示具有 值的文字字串。 這是使用數據系結的優點。 若要顯示沒有數據系結的文字,您必須從類別建構函式呼叫事件處理程式,特別初始化 TextLabel 屬性,或模擬 ValueChanged 引發事件。

預防措施

屬性的值 Minimum 必須永遠小於 屬性的值 Maximum 。 下列代碼段會導致 Slider 引發例外狀況:

// Throws an exception!
Slider slider = new Slider
{
    Minimum = 10,
    Maximum = 20
};

C# 編譯程式會產生程式代碼,依序設定這兩個屬性,當 屬性設定為 10 時 Minimum ,其大於預設值 Maximum 1。 您可以先設定 屬性來 Maximum 避免此案例中的例外狀況:

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

將 設定 Maximum 為 20 不是問題,因為它大於預設值 Minimum 0。 設定時 Minimum ,值小於 Maximum 20 的值。

XAML 中存在相同的問題。 以確保 Maximum 一律大於 Minimum的順序設定屬性:

<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 會強制設為 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" />

Minimum 設定為 10 時, Value 也會設定為 10,並 ValueChanged 引發事件。 這可能會在建構頁面的其餘部分之前發生,而且處理程式可能會嘗試參考尚未建立之頁面上的其他元素。 您可能會想要將某些程式代碼新增至處理程式, ValueChanged 以檢查 null 頁面上其他元素的值。 或者,您可以在初始化值之後Slider設定ValueChanged事件處理程式。

平台實作差異

稍早顯示的螢幕快照會顯示具有不同小數點數目之 Slider 的值。 這與如何在 Slider Android和UWP平臺上實作有關。

Android 實作

Slider Android 實作是以 Android SeekBar 為基礎,且一律會將 Max 屬性設定為 1000。 這表示 Slider 在Android上只有1,001個離散值。 如果您將 設定 Slider 為具有 Minimum 0 和 Maximum 5000 的 ,則當操作 時 SliderValue 屬性的值為 0、5、10、15 等等。

UWP 實作

的UWP實 Slider 作是以UWP Slider 控件為基礎。 StepFrequency UWP Slider 的 屬性會設定為 和 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。 當 和 屬性之間的差異Maximum是 10 或更高時,則會StepFrequency設定為 1,而 Value 屬性具有整數Minimum值。

StepSlider 解決方案

第 27 章將討論更多才多藝StepSlider。使用 建立行動應用程式Xamarin.Forms之書籍的自定義轉譯器StepSlider類似於 Slider ,但會加入 Steps 屬性,以指定 和Maximum之間的Minimum值數目。

色彩選取的滑桿

範例中的最後兩個頁面都使用三 Slider 個實例進行色彩選取。 第一頁會處理程序代碼後置檔案中的所有互動,而第二頁則示範如何搭配 ViewModel 使用數據系結。

處理程式代碼後置檔案中的滑桿

RGB 色彩滑桿頁面會具現化 BoxView 來顯示色彩、三Slider個實例來選取色彩的紅色、綠色和藍色元件,以及顯示這些色彩值的三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>

提供 Style 這三 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 其中一個 Label 實例的 屬性設定為簡短文字字串,指出十六進位中的 值 Slider 。 然後,會存取這三 SliderColor 實例,以從 RGB 元件建立值:

RGB 色彩滑桿

將滑桿系結至 ViewModel

[ HSL 色彩滑桿 ] 頁面示範如何使用 ViewModel 來執行用來從色調、飽和度和亮度值建立 Color 值的計算。 如同所有 ViewModels,類別會HSLColorViewModelINotifyPropertyChanged實作 介面,並在每當其中一個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>

當操作專案時 SliderBoxView 會從 ViewModel 更新 和 Label 元素:

HSL 色彩滑桿

標記 StringFormat 延伸的 Binding 元件會設定為 「F2」 格式,以顯示兩個小數字數。 (數據系結中的字串格式設定會在文章 中討論字串格式。)不過,程式的 UWP 版本限制為 0、0.1、0.2、 ...0.9 和 1.0。 這是UWP Slider 實作的直接結果,如平台實作差異一節中所述。