Поведение VisualStateGroup в CarouselView ломается при помещении в Horizontal Layout

Рейтинг: 0Ответов: 1Опубликовано: 04.05.2023

Хотел сделать прокрутку времени похожую как на IOS:

IOS TimePicker

Используя несколько CarouselView в горизонтальных макетах таких как StackLayout или же Grid получается что в первом работает корректно. А в последующих отображается криво. Притом что во FlexLayout отображаются корректно первые две:

введите сюда описание изображения

В чём может быть причина данной проблемы?

XAML Код

<ContentView.Resources>
    <ResourceDictionary>
        <Style x:Key="stackLayoutStyle" TargetType="StackLayout">
            <Setter Property="VisualStateManager.VisualStateGroups">
                <VisualStateGroupList>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="PreviousItem">
                            <VisualState.Setters>
                                <Setter Property="Opacity"
                                        Value="0.30" />
                            </VisualState.Setters>
                        </VisualState>
                        <VisualState x:Name="CurrentItem">
                            <VisualState.Setters>
                                <Setter Property="Scale"
                                        Value="1.1" />
                            </VisualState.Setters>
                        </VisualState>
                        <VisualState x:Name="NextItem">
                            <VisualState.Setters>
                                <Setter Property="Opacity"
                                        Value="0.30" />
                            </VisualState.Setters>
                        </VisualState>
                        <VisualState x:Name="DefaultItem">
                            <VisualState.Setters>
                                <Setter Property="Opacity"
                                        Value="0.30" />
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateGroupList>
            </Setter>
        </Style>
        <Style x:Key="carouselViewStyle" TargetType="CarouselView">
            <Setter Property="HeightRequest" Value="100"/>
            <Setter Property="BackgroundColor" Value="Yellow"/>
            <Setter Property="PeekAreaInsets" Value="40"/>
        </Style>
    </ResourceDictionary>
</ContentView.Resources>
<ContentView.Content>
    <StackLayout>
        <Label 
            FontSize="50"
            TextColor="Black"
            Text="{Binding CurrentTime}" 
            HorizontalOptions="CenterAndExpand"/>
        <FlexLayout
            Direction="Row">
            <CarouselView
                ItemsSource="{Binding HoursTimes}"
                CurrentItem="{Binding CurrentHour}"
                Style="{StaticResource carouselViewStyle}">
                <CarouselView.ItemsLayout>
                    <LinearItemsLayout SnapPointsAlignment="Center" SnapPointsType="Mandatory" Orientation="Vertical" />
                </CarouselView.ItemsLayout>
                <CarouselView.ItemTemplate>
                    <DataTemplate x:DataType="viewModels:TimeModel">
                        <StackLayout Style="{StaticResource stackLayoutStyle}">
                            <Label
                                Text="{Binding Num}" 
                                TextColor="Black" 
                                HorizontalOptions="Center"/>
                        </StackLayout>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
            <CarouselView        
                ItemsSource="{Binding LeftMinTimes}"
                CurrentItem="{Binding CurrentLeftMinute}"
                Style="{StaticResource carouselViewStyle}">
                <CarouselView.ItemsLayout>
                    <LinearItemsLayout SnapPointsAlignment="Center" SnapPointsType="Mandatory" Orientation="Vertical" />
                </CarouselView.ItemsLayout>
                <CarouselView.ItemTemplate>
                    <DataTemplate x:DataType="viewModels:TimeModel">
                        <StackLayout 
                            CompressedLayout.IsHeadless="True"
                            Style="{StaticResource stackLayoutStyle}">
                            <Label
                                Text="{Binding Num}" 
                                TextColor="Black" 
                                HorizontalOptions="Center"/>
                        </StackLayout>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
            <CarouselView        
                ItemsSource="{Binding RightMinTimes}"
                CurrentItem="{Binding CurrentRightMinute}"
                Style="{StaticResource carouselViewStyle}">
                <CarouselView.ItemsLayout>
                    <LinearItemsLayout SnapPointsAlignment="Center" SnapPointsType="Mandatory" Orientation="Vertical" />
                </CarouselView.ItemsLayout>
                <CarouselView.ItemTemplate>
                    <DataTemplate x:DataType="viewModels:TimeModel">
                        <StackLayout 
                            CompressedLayout.IsHeadless="True"
                            Style="{StaticResource stackLayoutStyle}">
                            <Label
                                Text="{Binding Num}" 
                                TextColor="Black" 
                                HorizontalOptions="Center"/>
                        </StackLayout>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
            <CarouselView        
                ItemsSource="{Binding LeftSecondsTimes}"
                CurrentItem="{Binding CurrentLeftSecound}"
                Style="{StaticResource carouselViewStyle}">
                <CarouselView.ItemsLayout>
                    <LinearItemsLayout SnapPointsAlignment="Center" SnapPointsType="Mandatory" Orientation="Vertical" />
                </CarouselView.ItemsLayout>
                <CarouselView.ItemTemplate>
                    <DataTemplate x:DataType="viewModels:TimeModel">
                        <StackLayout 
                            CompressedLayout.IsHeadless="True"
                            Style="{StaticResource stackLayoutStyle}">
                            <Label
                                Text="{Binding Num}" 
                                TextColor="Black" 
                                HorizontalOptions="Center"/>
                        </StackLayout>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
            <CarouselView        
                ItemsSource="{Binding RightSecondsTimes}"
                CurrentItem="{Binding CurrentRightSecound}"
                Style="{StaticResource carouselViewStyle}">
                <CarouselView.ItemsLayout>
                    <LinearItemsLayout SnapPointsAlignment="Center" SnapPointsType="Mandatory" Orientation="Vertical" />
                </CarouselView.ItemsLayout>
                <CarouselView.ItemTemplate>
                    <DataTemplate x:DataType="viewModels:TimeModel">
                        <StackLayout 
                            CompressedLayout.IsHeadless="True"
                            Style="{StaticResource stackLayoutStyle}">
                            <Label
                                Text="{Binding Num}" 
                                TextColor="Black" 
                                HorizontalOptions="Center"/>
                        </StackLayout>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
        </FlexLayout>
    </StackLayout>
</ContentView.Content>

Ответы

▲ 0

Решил создать отдельный, собственный View "MyCarouselView" со стилями (Style) и использовал его. Всё работает корректно:

введите сюда описание изображения

MyCarouselView.xaml

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:models="clr-namespace:ChessClock.Models"
             x:Class="ChessClock.Views.MyCarouselView"
             x:Name="this">
    <ContentView.Resources>
        <ResourceDictionary>
            <Style x:Key="stackLayoutStyle" TargetType="StackLayout">
                <Setter Property="VisualStateManager.VisualStateGroups">
                    <VisualStateGroupList>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="PreviousItem">
                                <VisualState.Setters>
                                    <Setter Property="Opacity"
                                            Value="0.30" />
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="CurrentItem">
                                <VisualState.Setters>
                                    <Setter Property="Scale"
                                            Value="1.1" />
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="NextItem">
                                <VisualState.Setters>
                                    <Setter Property="Opacity"
                                            Value="0.30" />
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="DefaultItem">
                                <VisualState.Setters>
                                    <Setter Property="Opacity"
                                            Value="0.30" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateGroupList>
                </Setter>
            </Style>
            <Style x:Key="carouselViewStyle" TargetType="CarouselView">
                <Setter Property="HeightRequest" Value="100"/>
                <Setter Property="BackgroundColor" Value="Yellow"/>
                <Setter Property="PeekAreaInsets" Value="40"/>
            </Style>
        </ResourceDictionary>
    </ContentView.Resources>
    <ContentView.Content>
        <CarouselView
            ItemsSource="{Binding Items, Source={x:Reference this}}"
            CurrentItem="{Binding Item, Source={x:Reference this}}"
            Style="{StaticResource carouselViewStyle}">
            <CarouselView.ItemsLayout>
                <LinearItemsLayout 
                    SnapPointsAlignment="Center" 
                    SnapPointsType="Mandatory" 
                    Orientation="Vertical"/>
            </CarouselView.ItemsLayout>
            <CarouselView.ItemTemplate>
                <DataTemplate x:DataType="models:TimeModel">
                    <StackLayout Style="{StaticResource stackLayoutStyle}">
                        <Label
                            Text="{Binding Num}" 
                            TextColor="Black" 
                            HorizontalOptions="Center"/>
                    </StackLayout>
                </DataTemplate>
            </CarouselView.ItemTemplate>
        </CarouselView>
    </ContentView.Content>
</ContentView>

MyCarouselView.cs

public partial class MyCarouselView : ContentView
{
    public MyCarouselView ()
    {
        InitializeComponent ();
    }

    public static readonly BindableProperty ItemsProperty =
            BindableProperty.Create(nameof(Items), typeof(IEnumerable<TimeModel>), typeof(MyCarouselView), new List<TimeModel>(), BindingMode.TwoWay);
    public static readonly BindableProperty ItemProperty =
            BindableProperty.Create(nameof(Item), typeof(TimeModel), typeof(MyCarouselView), new TimeModel(0), BindingMode.TwoWay);
    
    public IEnumerable<TimeModel> Items 
    {
        get { return (IEnumerable<TimeModel>)GetValue(ItemsProperty); }
        set { SetValue(ItemsProperty, value); }
    }
    public TimeModel Item
    {
        get { return (TimeModel)GetValue(ItemProperty); }
        set { SetValue(ItemProperty, value); }
    }
}

MainView.xaml

<ContentView.Content>
        <StackLayout>
            <Label 
                FontSize="50"
                TextColor="Black"
                Text="{Binding CurrentTime}" 
                HorizontalOptions="CenterAndExpand"/>
            <FlexLayout
                Direction="Row">
                <views:MyCarouselView
                    Items="{Binding HoursTimes}"
                    Item="{Binding CurrentHour}"/>
                <views:MyCarouselView
                    Items="{Binding LeftMinTimes}"
                    Item="{Binding CurrentLeftMinute}"/>
                <views:MyCarouselView
                    Items="{Binding RightMinTimes}"
                    Item="{Binding CurrentRightMinute}"/>
                <views:MyCarouselView
                    Items="{Binding LeftSecondsTimes}"
                    Item="{Binding CurrentLeftSecound}"/>
                <views:MyCarouselView
                    Items="{Binding RightSecondsTimes}"
                    Item="{Binding CurrentRightSecound}"/>
            </FlexLayout>
        </StackLayout>
</ContentView.Content>