步进器
.NET Multi-platform App UI (.NET MAUI) Stepper 允许从一系列值中选择数值。 它由两个带有减号和加号的按钮组成。 用户可以操作这些按钮,以增量方式从一系列值中选择一个 double
值。
Stepper 定义了类型为 double
的四个属性。
Increment
是所选值的变化量,默认值为 1。Minimum
是最小范围,默认值为 0。Maximum
是最大范围,默认值为 100。Value
是步进器的值,其范围介于Minimum
和Maximum
之间,默认值为 0。
所有这些属性都由 BindableProperty 对象支持。 Value
属性具有 BindingMode.TwoWay
的默认绑定模式,这意味着它适合用作使用模型-视图-视图模型 (MVVM) 模式的应用程序中的绑定源。
Stepper 会强制转换 Value
属性,使其介于 Minimum
和 Maximum
之间(含)。 如果 Minimum
属性被设置为大于 Value
属性的值,则 Stepper 会将 Value
属性设置为 Minimum
。 同样,如果 Maximum
被设置为小于 Value
的值,则 Stepper 会将 Value
属性设置为 Maximum
。 在内部,Stepper 可确保 Minimum
小于 Maximum
。 如果曾经设置过 Minimum
或 Maximum
,则 Minimum
不小于 Maximum
,将会引发异常。 有关设置 Minimum
和 Maximum
属性的详细信息,请参阅预防措施。
Stepper 定义在 Value
发生更改时引发的 ValueChanged
事件,该事件是通过 Stepper 的用户操作或在应用程序直接设置 Value
属性时引发的。 如前所述,当强制转换 Value
属性时,也会引发 ValueChanged
事件。 随附 ValueChanged
事件的 ValueChangedEventArgs
对象有类型为 double
的 OldValue
和 NewValue
。 在引发事件时,NewValue
的值与 Stepper 对象的 Value
属性相同。
创建 Stepper
下面的示例展示了如何用 Label 对象创建 Stepper:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="StepperDemo.BasicStepperXAMLPage"
Title="Basic Stepper XAML">
<StackLayout Margin="20">
<Label x:Name="_rotatingLabel"
Text="ROTATING TEXT"
FontSize="18"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Stepper Maximum="360"
Increment="30"
HorizontalOptions="Center"
ValueChanged="OnStepperValueChanged" />
<Label x:Name="_displayLabel"
Text="(uninitialized)"
HorizontalOptions="Center"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
在此示例中,对 Stepper 进行了初始化,使其具有一个值为 360 的 Maximum
属性,和一个值为 30 的 Increment
属性。 根据 Increment
属性的值,对 Stepper 进行操作会以增量方式在 Minimum
和 Maximum
之间更改所选值。 第二个 Label 显示文本“(uninitialized)”,直到操作了 Stepper,这将导致引发第一个 ValueChanged
事件。
代码隐藏文件包含 ValueChanged
事件的处理程序:
public partial class BasicStepperXAMLPage : ContentPage
{
public BasicStepperXAMLPage()
{
InitializeComponent();
}
void OnStepperValueChanged(object sender, ValueChangedEventArgs e)
{
double value = e.NewValue;
_rotatingLabel.Rotation = value;
_displayLabel.Text = string.Format("The Stepper value is {0}", value);
}
}
Stepper 的 ValueChanged
处理程序使用 stepper
对象的 Value
属性来设置第一个 Label 的 Rotation
属性,并将 string.Format
方法与事件参数的 NewValue
属性一起使用来设置第二个 Label 的 Text
属性:
事件处理程序还可能通过 sender
参数获取触发事件的 Stepper。 Value
属性包含当前值:
double value = ((Stepper)sender).Value;
如果 Stepper 对象在 XAML 文件中指定了带 x:Name
属性(例如“stepper”)的名称,则事件处理程序可以直接引用该对象:
double value = stepper.Value;
用于创建 Stepper 的等效 C# 代码为:
Stepper stepper = new Stepper
{
Maximum = 360,
Increment = 30,
HorizontalOptions = LayoutOptions.Center
};
stepper.ValueChanged += (sender, e) =>
{
rotationLabel.Rotation = stepper.Value;
displayLabel.Text = string.Format("The Stepper value is {0}", e.NewValue);
};
数据绑定 Stepper
可以使用数据绑定来响应 Stepper 值的更改,从而消除 ValueChanged
事件处理程序:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="StepperDemo.BasicStepperBindingsPage"
Title="Basic Stepper Bindings">
<StackLayout Margin="20">
<Label Text="ROTATING TEXT"
Rotation="{Binding x:DataType='Stepper', Source={x:Reference _stepper}, Path=Value}"
FontSize="18"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Stepper x:Name="_stepper"
Maximum="360"
Increment="30"
HorizontalOptions="Center" />
<Label Text="{Binding x:DataType='Stepper', Source={x:Reference _stepper}, Path=Value, StringFormat='The Stepper value is {0:F0}'}"
HorizontalOptions="Center"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
在此示例中,第一个 Label 的 Rotation
属性绑定到 Stepper 的 Value
属性,第二个 Label 的 Text
属性具有 StringFormat
规范。 第一页出现时,第二个 Label 将显示具有该值的文本字符串。 若要显示没有数据绑定的文本,需要通过从类构造函数调用事件处理程序来专门初始化 Label 的 Text
属性或模拟 ValueChanged
事件的触发。
预防措施
Minimum
属性的值必须始终小于 Maximum
属性的值。 下面的代码示例会导致 Stepper 引发异常:
// Throws an exception!
Stepper stepper = new Stepper
{
Minimum = 180,
Maximum = 360
};
C# 编译器生成了按顺序设置这两个属性的代码,当 Minimum
属性被设置为 180 时,它大于默认 Maximum
值 100。 可以通过先设置 Maximum
属性来避免此情况下出现的异常:
Stepper stepper = new Stepper
{
Maximum = 360,
Minimum = 180
};
在此示例中,将 Maximum
设置为 360 不会造成问题,因为它大于默认 Minimum
值 0。 设置 Minimum
时,该值小于 Maximum
值 360。
XAML 中存在相同的问题。 设置属性是为了确保 Maximum
始终大于 Minimum
:
<Stepper Maximum="360"
Minimum="180" ... />
可以将 Minimum
和 Maximum
值设置为负数,但只能按照 Minimum
始终小于 Maximum
的顺序:
<Stepper Minimum="-360"
Maximum="-180" ... />
Value
属性始终大于或等于 Minimum
值且小于或等于 Maximum
。 如果将 Value
设置为该范围之外的值,则会强制使此值位于该范围内,但不会引发异常。 例如,此代码不会引发异常:
Stepper stepper = new Stepper
{
Value = 180
};
而是会将 Value
属性的 Maximum
值强制转换为 100。
前面的示例将 Maximum
设置为 360,将 Minimum
设置为 180:
Stepper stepper = new Stepper
{
Maximum = 360,
Minimum = 180
};
如果 Minimum
被设置为 180,则 Value
也会被设置为 180。
如果在将 Value
属性强制转换为其默认值 0 以外的其他值时附加了 ValueChanged
事件处理程序,则会引发 ValueChanged
事件:
<Stepper ValueChanged="OnStepperValueChanged"
Maximum="360"
Minimum="180" />
如果 Minimum
被设置为 180,则 Value
也会被设置为 180,并引发 ValueChanged
事件。 在构造页面的其余部分之前,可能会发生这种情况,处理程序可能会尝试引用尚未创建的页面上的其他元素。 你需要向 ValueChanged
处理程序添加一些代码,以检查页面上其他元素的 null
值。 或者,可以在初始化 Stepper 值后设置 ValueChanged
事件处理程序。