Xamarin.Forms CarouselView 交互

Download Sample下载示例

CarouselView 定义以下控制用户交互的属性:

  • CurrentItem,类型为 object,是当前显示的项。 此属性具有默认绑定模式 TwoWay,且当不存在任何要显示的数据时值为 null
  • CurrentItemChangedCommand,类型为 ICommand,在当前项更改时执行。
  • CurrentItemChangedCommandParameter 属于 object 类型,是传递给 CurrentItemChangedCommand 的参数。
  • IsBounceEnabled,类型为 bool,指定 CarouselView 是否将在内容边界处退回。 默认值为 true
  • IsSwipeEnabled,类型为 bool,用于确定轻扫手势是否会更改显示的项。 默认值为 true
  • Loop,类型为 bool,用于确定 CarouselView 是否提供对其项集合的循环访问。 默认值为 true
  • Position,类型为 int,是基础集合中当前项的索引。 此属性具有默认绑定模式 TwoWay,且当不存在任何要显示的数据时值为 0。
  • PositionChangedCommand,类型为 ICommand,在位置更改时执行。
  • PositionChangedCommandParameter 属于 object 类型,是传递给 PositionChangedCommand 的参数。
  • VisibleViews,类型为 ObservableCollection<View>,这是一个只读属性,其中包含当前可见项的对象。

所有这些属性都由 BindableProperty 对象提供支持,这意味着这些属性可以作为数据绑定的目标。

CarouselView 定义 CurrentItem 属性更改时触发的 CurrentItemChanged 事件,其中更改原因为用户滚动或某应用程序对此属性进行了设置。 CurrentItemChanged 事件随附的 CurrentItemChangedEventArgs 对象具有两个属性,且类型均为 object

  • PreviousItem - 属性更改后的前一项。
  • CurrentItem - 属性更改后的当前项。

CarouselView 还定义了在 Position 属性更改时触发的 PositionChanged 事件,其中更改原因为用户滚动或某应用程序对此属性进行了设置。 PositionChanged 事件随附的 PositionChangedEventArgs 对象具有两个属性,且类型均为 int

  • PreviousPosition - 属性更改后的前一项。
  • CurrentPosition - 属性更改后的当前位置。

响应当前项的更改

当前显示的项发生更改时,CurrentItem 属性将设置为该项的值。 此属性更改时,将执行 CurrentItemChangedCommand,并会将 CurrentItemChangedCommandParameter 的值传递给 ICommand。 然后 Position 属性将更新,并触发 CurrentItemChanged 事件。

重要说明

CurrentItem 属性更改时,Position 属性会随之更改。 这将导致执行 PositionChangedCommand,并触发 PositionChanged 事件。

活动

以下 XAML 示例显示了使用事件处理程序响应当前项更改的一个 CarouselView

<CarouselView ItemsSource="{Binding Monkeys}"
              CurrentItemChanged="OnCurrentItemChanged">
    ...
</CarouselView>

等效 C# 代码如下:

CarouselView carouselView = new CarouselView();
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
carouselView.CurrentItemChanged += OnCurrentItemChanged;

在此示例中,当 OnCurrentItemChanged 事件触发时,将执行 CurrentItemChanged 事件处理程序:

void OnCurrentItemChanged(object sender, CurrentItemChangedEventArgs e)
{
    Monkey previousItem = e.PreviousItem as Monkey;
    Monkey currentItem = e.CurrentItem as Monkey;
}

在此示例中,OnCurrentItemChanged 事件处理程序公开了前一项和当前项:

Screenshot of a CarouselView with previous and current items, on iOS and Android

命令

以下 XAML 示例显示了使用命令响应当前项更改的一个 CarouselView

<CarouselView ItemsSource="{Binding Monkeys}"
              CurrentItemChangedCommand="{Binding ItemChangedCommand}"
              CurrentItemChangedCommandParameter="{Binding Source={RelativeSource Self}, Path=CurrentItem}">
    ...
</CarouselView>

等效 C# 代码如下:

CarouselView carouselView = new CarouselView();
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
carouselView.SetBinding(CarouselView.CurrentItemChangedCommandProperty, "ItemChangedCommand");
carouselView.SetBinding(CarouselView.CurrentItemChangedCommandParameterProperty, new Binding("CurrentItem", source: RelativeBindingSource.Self));

在此示例中,CurrentItemChangedCommand 属性绑定到 ItemChangedCommand 属性,并将 CurrentItem 属性值作为参数传递给该属性。 然后,ItemChangedCommand 可以根据需要响应当前项更改:

public ICommand ItemChangedCommand => new Command<Monkey>((item) =>
{
    PreviousMonkey = CurrentMonkey;
    CurrentMonkey = item;
});

在此示例中,ItemChangedCommand 更新了存储前一项和当前项的对象。

响应位置更改

当前显示的项发生更改时,Position 属性将设置为基础集合中当前项的索引。 此属性更改时,将执行 PositionChangedCommand,并会将 PositionChangedCommandParameter 的值传递给 ICommand。 然后触发 PositionChanged 事件。 如果 Position 属性已经以编程方式更改,则 CarouselView 将滚动到与 Position 值相对应的项。

注意

Position 属性设置为 0 将会导致显示基础集合中的第一项。

事件

下面的 XAML 示例显示了使用事件处理程序响应 Position 属性更改的 CarouselView

<CarouselView ItemsSource="{Binding Monkeys}"              
              PositionChanged="OnPositionChanged">
    ...
</CarouselView>

等效 C# 代码如下:

CarouselView carouselView = new CarouselView();
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
carouselView.PositionChanged += OnPositionChanged;

在此示例中,当 PositionChanged 事件触发时,将执行 OnPositionChanged 事件处理程序:

void OnPositionChanged(object sender, PositionChangedEventArgs e)
{
    int previousItemPosition = e.PreviousPosition;
    int currentItemPosition = e.CurrentPosition;
}

在此示例中,OnCurrentItemChanged 事件处理程序公开之前和当前位置:

Screenshot of a CarouselView with previous and current positions, on iOS and Android

命令

以下 XAML 示例显示了使用命令响应 Position 更改属性的 CarouselView

<CarouselView ItemsSource="{Binding Monkeys}"
              PositionChangedCommand="{Binding PositionChangedCommand}"
              PositionChangedCommandParameter="{Binding Source={RelativeSource Self}, Path=Position}">
    ...
</CarouselView>

等效 C# 代码如下:

CarouselView carouselView = new CarouselView();
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
carouselView.SetBinding(CarouselView.PositionChangedCommandProperty, "PositionChangedCommand");
carouselView.SetBinding(CarouselView.PositionChangedCommandParameterProperty, new Binding("Position", source: RelativeBindingSource.Self));

在此示例中,PositionChangedCommand 属性绑定到 PositionChangedCommand 属性,并将 Position 属性值作为参数传递给该属性。 然后,PositionChangedCommand 可以根据需要响应位置变化:

public ICommand PositionChangedCommand => new Command<int>((position) =>
{
    PreviousPosition = CurrentPosition;
    CurrentPosition = position;
});

在此示例中,PositionChangedCommand 更新存储之前与当前位置的对象。

预设当前项

通过将 CurrentItem 属性设置为当前项,可以编程方式设置 CarouselView 中的当前项。 以下 XAML 示例显示预先选择当前项的 CarouselView

<CarouselView ItemsSource="{Binding Monkeys}"
              CurrentItem="{Binding CurrentItem}">
    ...
</CarouselView>

等效 C# 代码如下:

CarouselView carouselView = new CarouselView();
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
carouselView.SetBinding(CarouselView.CurrentItemProperty, "CurrentItem");

注意

CurrentItem 属性的默认绑定模式为 TwoWay

CarouselView.CurrentItem 属性数据绑定到已连接视图模型的 CurrentItem 属性,该属性的类型 Monkey。 默认情况下,使用 TwoWay 绑定,以便当用户更改当前项时,CurrentItem 属性的值将设置为当前 Monkey 对象。 CurrentItem 属性在 MonkeysViewModel 类中定义:

public class MonkeysViewModel : INotifyPropertyChanged
{
    // ...
    public ObservableCollection<Monkey> Monkeys { get; private set; }

    public Monkey CurrentItem { get; set; }

    public MonkeysViewModel()
    {
        // ...
        CurrentItem = Monkeys.Skip(3).FirstOrDefault();
        OnPropertyChanged("CurrentItem");
    }
}

在此示例中,CurrentItem 属性设置为 Monkeys 集合中的第四项:

Screenshot of a CarouselView with preset item, on iOS and Android

预设位置

通过将 Position 属性设置为基础集合中项的索引,可以通过编程方式设置 CarouselView 的显示项。 以下 XAML 示例显示设置显示项的 CarouselView

<CarouselView ItemsSource="{Binding Monkeys}"
              Position="{Binding Position}">
    ...
</CarouselView>

等效 C# 代码如下:

CarouselView carouselView = new CarouselView();
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
carouselView.SetBinding(CarouselView.PositionProperty, "Position");

注意

Position 属性的默认绑定模式为 TwoWay

CarouselView.Position 属性数据绑定到已连接视图模型的 Position 属性,该属性的类型 int。 默认情况下,使用 TwoWay 绑定,以便当用户滚动浏览 CarouselView 时,Position 属性的值将设置为显示项的索引。 Position 属性在 MonkeysViewModel 类中定义:

public class MonkeysViewModel : INotifyPropertyChanged
{
    // ...
    public int Position { get; set; }

    public MonkeysViewModel()
    {
        // ...
        Position = 3;
        OnPropertyChanged("Position");
    }
}

在此示例中,Position 属性设置为 Monkeys 集合中的第四项:

Screenshot of a CarouselView with preset position, on iOS and Android

定义视觉状态

CarouselView 定义了四种视觉状态:

  • CurrentItem 表示当前显示项的视觉状态。
  • PreviousItem 表示之前显示项的视觉状态。
  • NextItem 表示下一项的视觉状态。
  • DefaultItem 表示项的其余部分的视觉状态。

这些视觉状态可用于启动对由 CarouselView 显示项的视觉更改。

以下 XAML 示例显示如何定义 CurrentItemPreviousItemNextItemDefaultItem 视觉状态:

<CarouselView ItemsSource="{Binding Monkeys}"
              PeekAreaInsets="100">
    <CarouselView.ItemTemplate>
        <DataTemplate>
            <StackLayout>
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="CurrentItem">
                            <VisualState.Setters>
                                <Setter Property="Scale"
                                        Value="1.1" />
                            </VisualState.Setters>
                        </VisualState>
                        <VisualState x:Name="PreviousItem">
                            <VisualState.Setters>
                                <Setter Property="Opacity"
                                        Value="0.5" />
                            </VisualState.Setters>
                        </VisualState>
                        <VisualState x:Name="NextItem">
                            <VisualState.Setters>
                                <Setter Property="Opacity"
                                        Value="0.5" />
                            </VisualState.Setters>
                        </VisualState>
                        <VisualState x:Name="DefaultItem">
                            <VisualState.Setters>
                                <Setter Property="Opacity"
                                        Value="0.25" />
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>

                <!-- Item template content -->
                <Frame HasShadow="true">
                    ...
                </Frame>
            </StackLayout>
        </DataTemplate>
    </CarouselView.ItemTemplate>
</CarouselView>

在此示例中,CurrentItem 视觉状态指定由 CarouselView 显示的当前项其 Scale 属性将从默认值 1 更改为 1.1。 PreviousItemNextItem 视觉状态指定当前项周围的项将使用 0.5 的 Opacity 值显示。 DefaultItem 视觉状态指定由 CarouselView 显示的项的其余部分将使用 0.25 的 Opacity 值显示。

注意

或者,可以在具有 TargetType 属性值的 Style 中定义视觉状态,该属性值是 DataTemplate 根元素的类型,该元素设置为 ItemTemplate 属性值。

以下屏幕截图显示了 CurrentItemPreviousItemNextItem 视觉状态:

Screenshot of a CarouselView using visual states, on iOS and Android

若要详细了解可视状态,请参阅 Xamarin.Forms 可视状态管理器

清除当前项

可以通过将 CurrentItem 属性或其绑定的对象设置为 null 来清除该属性。

禁用弹出

默认情况下,CarouselView 在内容边界处弹出项。 通过将 IsBounceEnabled 属性设置为 false,可以禁用此行为。

禁用循环

默认情况下,CarouselView 提供对其项集合的循环访问。 因此,从集合中的第一项向后轻扫将显示集合中的最后一项。 同样,从集合中最后一项向前轻扫将返回到集合中的第一项。 通过将 Loop 属性设置为 false,可以禁用此行为。

禁用轻扫交互

默认情况下,CarouselView 允许用户使用轻扫手势浏览项。 通过将 IsSwipeEnabled 属性设置为 false,可以禁用此轻扫交互。