Added Converter to simplify the use of Layouts in the CarouselView (#8665)
authorJavier Suárez Ruiz <javiersuarezruiz@hotmail.com>
Mon, 9 Dec 2019 19:57:38 +0000 (20:57 +0100)
committerSamantha Houts <samhouts@users.noreply.github.com>
Mon, 9 Dec 2019 19:57:38 +0000 (11:57 -0800)
fixes #7813

Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7813.xaml [new file with mode: 0644]
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7813.xaml.cs [new file with mode: 0644]
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
Xamarin.Forms.Core/Items/CarouselLayoutTypeConverter.cs [new file with mode: 0644]
Xamarin.Forms.Core/Items/CarouselView.cs
Xamarin.Forms.Core/Items/LinearItemsLayout.cs

diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7813.xaml b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7813.xaml
new file mode 100644 (file)
index 0000000..f92876f
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<ContentPage
+    x:Class="Xamarin.Forms.Controls.Issues.Issue7813"
+    xmlns="http://xamarin.com/schemas/2014/forms"
+    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+    Title="Issue 7813">
+    <ContentPage.Resources>
+        <ResourceDictionary>
+
+            <DataTemplate x:Key="CarouselTemplate">
+                <Grid
+                    BackgroundColor="{Binding Color}">
+                    <Label
+                        HorizontalOptions="Center"
+                        VerticalOptions="Center"
+                        Text="{Binding Name}"/>
+                </Grid>
+            </DataTemplate>
+
+        </ResourceDictionary>
+    </ContentPage.Resources>
+    <Grid
+        RowSpacing="0">
+        <Grid.RowDefinitions>
+            <RowDefinition Height="Auto" />
+            <RowDefinition />
+            <RowDefinition />
+        </Grid.RowDefinitions>
+        <Label
+            Grid.Row="0"
+            Text="If the first CarouselView uses horizontal orientation and the second one vertical orientation (using a Converter), the test has passed."
+            BackgroundColor="Black"
+            TextColor="White"/>
+        <CarouselView
+            Grid.Row="1"
+            ItemsSource="{Binding Items}"
+            ItemsLayout="HorizontalList"
+            ItemTemplate="{StaticResource CarouselTemplate}"/>
+        <CarouselView
+            Grid.Row="2"
+            ItemsSource="{Binding Items}"
+            ItemsLayout="VerticalList"
+            ItemTemplate="{StaticResource CarouselTemplate}"/>
+    </Grid>
+</ContentPage>
\ No newline at end of file
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7813.xaml.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7813.xaml.cs
new file mode 100644 (file)
index 0000000..883f683
--- /dev/null
@@ -0,0 +1,83 @@
+using Xamarin.Forms.Internals;
+using Xamarin.Forms.Xaml;
+using System;
+using System.Collections.ObjectModel;
+using System.Collections.Generic;
+using Xamarin.Forms.CustomAttributes;
+
+#if UITEST
+using NUnit.Framework;
+using Xamarin.UITest;
+using Xamarin.Forms.Core.UITests;
+#endif
+
+namespace Xamarin.Forms.Controls.Issues
+{
+#if UITEST
+       [NUnit.Framework.Category(UITestCategories.CarouselView)]
+#endif
+#if APP
+       [XamlCompilation(XamlCompilationOptions.Compile)]
+#endif
+       [Preserve(AllMembers = true)]
+       [Issue(IssueTracker.Github, 7813, "CarouselView vertical layout could use a converter", PlatformAffected.All)]
+       public partial class Issue7813 : ContentPage
+       {
+               public Issue7813()
+               {
+#if APP
+                       InitializeComponent();
+#endif
+                       BindingContext = new Issue7813ViewModel();
+               }
+       }
+
+       [Preserve(AllMembers = true)]
+       public class Issue7813Model
+       {
+               public Color Color { get; set; }
+               public string Name { get; set; }
+       }
+
+       [Preserve(AllMembers = true)]
+       public class Issue7813ViewModel : BindableObject
+       {
+               ObservableCollection<Issue7813Model> _items;
+
+               public Issue7813ViewModel()
+               {
+                       LoadItems();
+               }
+
+               public ObservableCollection<Issue7813Model> Items
+               {
+                       get { return _items; }
+                       set
+                       {
+                               _items = value;
+                               OnPropertyChanged();
+                       }
+               }
+
+               void LoadItems()
+               {
+                       Items = new ObservableCollection<Issue7813Model>();
+
+                       var random = new Random();
+                       var items = new List<Issue7813Model>();
+
+                       for (int n = 0; n < 5; n++)
+                       {
+                               items.Add(new Issue7813Model
+                               {
+                                       Color = Color.FromRgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255)),
+                                       Name = $"{n + 1}"
+                               });
+                       }
+
+                       _items = new ObservableCollection<Issue7813Model>(items);
+                       OnPropertyChanged(nameof(Items));
+
+               }
+       }
+}
\ No newline at end of file
index 4618f92..6f53be4 100644 (file)
     <Compile Include="$(MSBuildThisFileDirectory)Issue8417.xaml.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue8647.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue7510.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Issue7813.xaml.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue8638.xaml.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue8672.cs" />
   </ItemGroup>
       <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
     </EmbeddedResource>
     <EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue8417.xaml" />
+    <EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue7813.xaml" />
     <EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue8638.xaml" />
   </ItemGroup>
   <ItemGroup>
diff --git a/Xamarin.Forms.Core/Items/CarouselLayoutTypeConverter.cs b/Xamarin.Forms.Core/Items/CarouselLayoutTypeConverter.cs
new file mode 100644 (file)
index 0000000..3a7a447
--- /dev/null
@@ -0,0 +1,23 @@
+using System;
+
+namespace Xamarin.Forms
+{
+       [Xaml.TypeConversion(typeof(LinearItemsLayout))]
+       public class CarouselLayoutTypeConverter : TypeConverter
+       {
+               public override object ConvertFromInvariantString(string value)
+               {
+                       if (value == "HorizontalList")
+                       {
+                               return LinearItemsLayout.CarouselDefault;
+                       }
+
+                       if (value == "VerticalList")
+                       {
+                               return LinearItemsLayout.CarouselVertical;
+                       }
+
+                       throw new InvalidOperationException($"Cannot convert \"{value}\" into {typeof(IItemsLayout)}");
+               }
+       }
+}
\ No newline at end of file
index be4c892..770cbcf 100644 (file)
@@ -151,6 +151,7 @@ namespace Xamarin.Forms
                        BindableProperty.Create(nameof(ItemsLayout), typeof(LinearItemsLayout), typeof(ItemsView),
                                LinearItemsLayout.CarouselDefault);
 
+               [TypeConverter(typeof(CarouselLayoutTypeConverter))]
                public LinearItemsLayout ItemsLayout
                {
                        get => (LinearItemsLayout)GetValue(ItemsLayoutProperty);
index 7d46056..2a33028 100644 (file)
@@ -11,6 +11,12 @@ namespace Xamarin.Forms
                public static readonly IItemsLayout Vertical = new LinearItemsLayout(ItemsLayoutOrientation.Vertical); 
                public static readonly IItemsLayout Horizontal = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal);
 
+               public static readonly IItemsLayout CarouselVertical = new LinearItemsLayout(ItemsLayoutOrientation.Vertical)
+               {
+                       SnapPointsType = SnapPointsType.MandatorySingle,
+                       SnapPointsAlignment = SnapPointsAlignment.Center
+               };
+
                internal static readonly LinearItemsLayout CarouselDefault = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal)
                {
                        SnapPointsType = SnapPointsType.MandatorySingle,