使用滑桿從連續值範圍選取。
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設定,且不要在配置中時SliderGrid使用的寬度AutoFill。
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 的 屬性。 的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 的 屬性會系結至 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,類別會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>
當操作專案時 Slider , BoxView 會從 ViewModel 更新 和 Label 元素:
標記 StringFormat 延伸的 Binding 元件會設定為 「F2」 格式,以顯示兩個小數字數。 (數據系結中的字串格式設定會在文章 中討論字串格式。)不過,程式的 UWP 版本限制為 0、0.1、0.2、 ...0.9 和 1.0。 這是UWP Slider 實作的直接結果,如平台實作差異一節中所述。


