Xamarin.Forms CarouselView:降低未选中项目的不透明度

Xamarin.Forms CarouselView: lower opacity of unselected items

我有一个 Xamarin.Forms Vertical CarouselView,其中 PeakAreaInsets 设置得非常高,因此我可以一次看到列表中的多个项目。我想要一种能够直观地显示列表中当前 "focused" 或已选中的项目的方法。有没有一种方法可以在滚动视图时动态更改轮播视图中项目的不透明度,以显示当前选中的项目?

如果有帮助的话,这是我的代码片段:

<CarouselView ItemsSource="{Binding Days}"
                  CurrentItem="{Binding SelectedDay}"
                  VerticalOptions="Center"
                  HorizontalOptions="Center"
                  PeekAreaInsets="300"
                  x:Name="DayCarousel">
        <CarouselView.ItemsLayout>
            <LinearItemsLayout SnapPointsAlignment="Center"
                               SnapPointsType="Mandatory"
                               Orientation="Vertical"/>
        </CarouselView.ItemsLayout>
        <CarouselView.ItemTemplate>
            <DataTemplate>
                <StackLayout Spacing="0"
                             Orientation="Vertical"
                             HorizontalOptions="Center"
                             VerticalOptions="Center"
                             Margin="30,10">
                    <Label Text="{Binding FormattedDate}"
                           HorizontalOptions="Center"
                           VerticalOptions="Center"
                           Style="{StaticResource LabelStyle}"/>
                    <Label Text="{Binding TitleText}"
                           HorizontalOptions="Center"
                           VerticalOptions="Center"
                           Style="{StaticResource LabelHeader1Style}"/>
                    <StackLayout.GestureRecognizers>
                        <TapGestureRecognizer Command="{Binding BindingContext.SelectDay, Source={x:Reference this}}"
                                              CommandParameter="{Binding .}"/>
                    </StackLayout.GestureRecognizers>
                </StackLayout>
            </DataTemplate>
        </CarouselView.ItemTemplate>
    </CarouselView>

这是我正在寻找的示例:

感谢@MouseOnMars

这是使这项工作成功的xaml。

        <CarouselView ItemsSource="{Binding Days}"
                  CurrentItem="{Binding SelectedDay}"
                  VerticalOptions="Center"
                  HorizontalOptions="Center"
                  PeekAreaInsets="300"
                  x:Name="DayCarousel">
        <CarouselView.ItemsLayout>
            <LinearItemsLayout SnapPointsAlignment="Center"
                               SnapPointsType="Mandatory"
                               Orientation="Vertical"/>
        </CarouselView.ItemsLayout>
        <CarouselView.ItemTemplate>
            <DataTemplate>
                <StackLayout Spacing="0"
                             Orientation="Vertical"
                             HorizontalOptions="Center"
                             VerticalOptions="Center"
                             Margin="30,10"
                             Opacity=".25">
                    <StackLayout.Triggers>
                        <DataTrigger TargetType="StackLayout"
                                     Binding="{Binding IsSelected}"
                                     Value="True">
                            <Setter Property="Opacity"
                                    Value="1"/>
                        </DataTrigger>
                    </StackLayout.Triggers>
                    <Label Text="{Binding FormattedDate}"
                           HorizontalOptions="Center"
                           VerticalOptions="Center"
                           Style="{StaticResource LabelStyle}"/>
                    <Label Text="{Binding TitleText}"
                           HorizontalOptions="Center"
                           VerticalOptions="Center"
                           Style="{StaticResource LabelHeader1Style}"/>
                    <StackLayout.GestureRecognizers>
                        <TapGestureRecognizer Command="{Binding BindingContext.SelectDay, Source={x:Reference this}}"
                                              CommandParameter="{Binding .}"/>
                    </StackLayout.GestureRecognizers>
                </StackLayout>
            </DataTemplate>
        </CarouselView.ItemTemplate>
    </CarouselView>

我必须向 ItemTemplate 绑定到的模型添加一个新的 bool 属性 "IsSelected"。然后,我必须在我的 Page ViewModel 的 "SelectedDay" 属性 中添加一些逻辑来打开和关闭 IsSelected 布尔值。此外,由于我将 CarouselView 直接绑定到一个模型,因此我不得不在模型打开或关闭时提高 属性 Changed on the model for IsSelected。

@Jonathan Cook:我想出了一个更通用的解决方案,它不依赖于 ViewModel 绑定。工作起来就像一个魅力,你不必在你的 ViewModel 中弄乱它。

<CarouselView>
    <CarouselView.ItemTemplate>
        <DataTemplate>
            <StackLayout Opacity=".3">
                <View.Triggers>
                    <DataTrigger TargetType="StackLayout" Value="True">

                        <!-- Using MultiBinding as we are going to compare two bound objects -->
                        <DataTrigger.Binding>

                            <!-- Simple IMultiValueConverter that checks for equality of the two values in the array -->
                            <MultiBinding Converter="{x:Static s:CommonConverters.MultiEquals}">
                                <MultiBinding.Bindings>
                                    <Binding />
                                    <Binding Path="CurrentItem" 
                                             Source="{RelativeSource AncestorType={x:Type CarouselView}}"/>
                                </MultiBinding.Bindings>
                            </MultiBinding>
                        </DataTrigger.Binding>

                        <Setter Property="Opacity" Value="1" />
                    </DataTrigger>
                </View.Triggers>

                <!-- Template content --> 
            </StackLayout>
        </DataTemplate>
    </CarouselView.ItemTemplate>
</CarouselView>