Поведение VisualStateGroup в CarouselView ломается при помещении в Horizontal Layout
Хотел сделать прокрутку времени похожую как на IOS:
Используя несколько 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>
Ответы (1 шт):
Автор решения: ClioBro
→ Ссылка
Решил создать отдельный, собственный 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>


