Xamarin.Forms 滑桿
使用滑桿從連續值範圍選取。
Xamarin.FormsSlider
是水平橫條,可由使用者操作,從連續範圍中選取double
值。
定義 Slider
類型的三個 double
屬性:
這三個屬性都是由 BindableProperty
物件所支援。 屬性Value
的預設系結模式BindingMode.TwoWay
為 ,這表示它適合做為使用Model-View-ViewModel (MVVM) 架構之應用程式中的系結來源。
警告
在內部, Slider
可確保 Minimum
小於 Maximum
。 如果 Minimum
已設定 或 Maximum
,使其 Minimum
不小於 Maximum
,則會引發例外狀況。 如需設定 Minimum
和 Maximum
屬性的詳細資訊,請參閱下面的預防措施一節。
Value
強制Slider
屬性,使其介於和 Maximum
之間Minimum
,並包含 。 如果 屬性 Minimum
設定為大於 Value
屬性的值,會將 Slider
Value
屬性設定為 Minimum
。 同樣地,如果 Maximum
設定為小於 Value
的值,則將 Slider
屬性設定 Value
為 Maximum
。
Slider
定義 ValueChanged
在變更時 Value
引發的事件,無論是透過使用者操作 Slider
,還是程式直接設定 Value
屬性時引發。 ValueChanged
當 屬性強制執行時Value
,也會引發事件,如上一段所述。
事件 ValueChangedEventArgs
隨附 ValueChanged
的物件有兩個 double
屬性,類型為 : OldValue
和 NewValue
。 在引發事件時, NewValue
的值會與 Value
對象的屬性 Slider
相同。
Slider
也會定義 DragStarted
和 DragCompleted
事件,這些事件會在拖曳動作的開頭和結尾引發。 ValueChanged
與事件不同,DragStarted
和 DragCompleted
事件只會透過使用者操作 Slider
引發。 DragStarted
當事件引發時,DragStartedCommand
會執行 類型 ICommand
為的 。 同樣地,當事件引發時 DragCompleted
, DragCompletedCommand
會執行 類型 ICommand
為 的 。
警告
請勿使用、 Start
或 End
的Slider
不受限制的水準版面配置選項Center
。 在 Android 和 UWP 上,折 Slider
疊成長度為零的條形圖,而 iOS 上,條形圖非常短。 保留的預設HorizontalOptions
設定,且不要在配置中時Slider
Grid
使用的寬度Auto
Fill
。
Slider
也會定義影響其外觀的數個屬性:
MinimumTrackColor
是拇指左側的橫條色彩。MaximumTrackColor
是拇指右側的橫條色彩。ThumbColor
是拇指色彩。ThumbImageSource
是用於拇指的影像,類型為ImageSource
。
注意
ThumbColor
和 ThumbImageSource
屬性互斥。 如果同時設定這兩個屬性,屬性 ThumbImageSource
會優先使用。
基本滑桿程式代碼和標記
此範例的開頭為三個功能完全相同的頁面,但會以不同的方式實作。 第一頁只使用 C# 程式代碼,第二個使用 XAML 搭配程式碼中的事件處理程式,第三個頁面可以使用 XAML 檔案中的數據系結來避免事件處理程式。
在程式代碼中建立滑桿
[基本滑桿代碼] 頁面會顯示在程式碼中建立 和 兩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
初始化 為具有 Maximum
360 的 屬性。 的ValueChanged
Slider
處理程式會使用 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
的 屬性會系結至 Value
的 Slider
屬性,如同 Text
第二 Label
個 StringFormat
具有規格的 屬性。 [ 基本滑桿系結 ] 頁面的運作方式與前兩頁稍有不同:第一頁出現時,第二個 Label
頁面會顯示具有 值的文字字串。 這是使用數據系結的優點。 若要顯示沒有數據系結的文字,您必須從類別建構函式呼叫事件處理程式,特別初始化 Text
的 Label
屬性,或模擬 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 的 ,則當操作 時 Slider
, Value
屬性的值為 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
。 然後,會存取這三 Slider
個 Color
實例,以從 RGB 元件建立值:
將滑桿系結至 ViewModel
[ HSL 色彩滑桿 ] 頁面示範如何使用 ViewModel 來執行用來從色調、飽和度和亮度值建立 Color
值的計算。 如同所有 ViewModels,類別會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
元素:
標記 StringFormat
延伸的 Binding
元件會設定為 「F2」 格式,以顯示兩個小數字數。 (數據系結中的字串格式設定會在文章 中討論字串格式。)不過,程式的 UWP 版本限制為 0、0.1、0.2、 ...0.9 和 1.0。 這是UWP Slider
實作的直接結果,如平台實作差異一節中所述。