Skip to content

Commit

Permalink
Use HorizontalGrid and VerticalGrid string values to specify GridItem…
Browse files Browse the repository at this point in the history
…sLayout in XAML (xamarin#8104)

* Convert HorizontalGrid and VerticalGrid strings to ItemsLayout (xamarin#5577)

* Support GridLayout in ItemsLayoutDesignTypeConverter xamarin#5577

* Add Issue5577 control to test ItemsLayoutConverter

* Optimize ItemsLayoutTypeConverter

* Expect InvalidOperationException, when span is missing in ItemsLayoutTypeConverter

Co-authored-by: E.Z. Hart <[email protected]>
  • Loading branch information
duracellko and hartez authored Jun 5, 2020
1 parent 3cf3286 commit f06cb1f
Show file tree
Hide file tree
Showing 7 changed files with 386 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8" ?>
<controls:TestContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:Xamarin.Forms.Controls"
x:Class="Xamarin.Forms.Controls.Issues.Issue5577">

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

<Label Grid.Row="0" LineBreakMode="WordWrap" Text="Page should display 2 collection view with horizontal and vertical grid layouts"/>

<CollectionView Grid.Row="1" ItemsSource="{Binding Animals}" ItemsLayout="HorizontalGrid, 2" BackgroundColor="Yellow">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding Name}"/>
<Label Text="{Binding Location}"/>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>

<CollectionView Grid.Row="2" ItemsSource="{Binding Animals}" ItemsLayout="VerticalGrid, 4">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding Name}"/>
<Label Text="{Binding Location}"/>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</controls:TestContentPage>
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
using System.Collections.ObjectModel;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
using Xamarin.Forms.Xaml;

#if UITEST
using Xamarin.Forms.Core.UITests;
#endif

namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[NUnit.Framework.Category(UITestCategories.CollectionView)]
#endif
#if APP
[XamlCompilation(XamlCompilationOptions.Compile)]
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 5577, "CollectionView XAML API suggestion", PlatformAffected.All)]
public partial class Issue5577 : TestContentPage
{
#if APP
public Issue5577()
{
InitializeComponent();

BindingContext = new ViewModel5577();
}
#endif

protected override void Init()
{

}
}

[Preserve(AllMembers = true)]
public class ViewModel5577
{
public ViewModel5577()
{
AddAnimals();
}

public ObservableCollection<Model5577> Animals { get; private set; } = new ObservableCollection<Model5577>();

private void AddAnimals()
{
Animals.Add(new Model5577
{
Name = "Afghan Hound",
Location = "Afghanistan",
});
Animals.Add(new Model5577
{
Name = "Alpine Dachsbracke",
Location = "Austria",
});
Animals.Add(new Model5577
{
Name = "American Bulldog",
Location = "United States",
});
Animals.Add(new Model5577
{
Name = "Bearded Collie",
Location = "Scotland",
});
Animals.Add(new Model5577
{
Name = "Boston Terrier",
Location = "United States",
});
Animals.Add(new Model5577
{
Name = "Canadian Eskimo",
Location = "Canada",
});
Animals.Add(new Model5577
{
Name = "Eurohound",
Location = "Scandinavia",
});
Animals.Add(new Model5577
{
Name = "Irish Terrier",
Location = "Ireland",
});
Animals.Add(new Model5577
{
Name = "Kerry Beagle",
Location = "Ireland",
});
Animals.Add(new Model5577
{
Name = "Norwegian Buhund",
Location = "Norway",
});
}
}

[Preserve(AllMembers = true)]
public class Model5577
{
public string Name { get; set; }
public string Location { get; set; }

public override string ToString()
{
return Name;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@
<DependentUpon>Issue7048.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Issue5577.xaml.cs">
<DependentUpon>Issue5577.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Issue6804.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue7181.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue5367.cs" />
Expand Down Expand Up @@ -1945,6 +1949,12 @@
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue5577.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue8263.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public override StandardValuesCollection GetStandardValues(ITypeDescriptorContex
{
if (Values == null)
{
var names = new List<string>() { "VerticalList", "HorizontalList" };
var names = new List<string>() { "VerticalList", "HorizontalList", "VerticalGrid", "HorizontalGrid" };
Values = new StandardValuesCollection(names);
}

Expand Down
188 changes: 188 additions & 0 deletions Xamarin.Forms.Core.UnitTests/ItemsLayoutTypeConverterTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
using System;
using NUnit.Framework;

namespace Xamarin.Forms.Core.UnitTests
{
[TestFixture]
public class ItemsLayoutTypeConverterTests : BaseTestFixture
{
[Test]
public void HorizontalListShouldReturnLinearItemsLayout()
{
var converter = new ItemsLayoutTypeConverter();
var result = converter.ConvertFromInvariantString("HorizontalList");
Assert.AreSame(LinearItemsLayout.Horizontal, result);
}

[Test]
public void VerticalListShouldReturnLinearItemsLayout()
{
var converter = new ItemsLayoutTypeConverter();
var result = converter.ConvertFromInvariantString("VerticalList");
Assert.AreSame(LinearItemsLayout.Vertical, result);
}

[Test]
public void HorizontalGridShouldReturnGridItemsLayout()
{
var converter = new ItemsLayoutTypeConverter();
var result = converter.ConvertFromInvariantString("HorizontalGrid");

Assert.IsInstanceOf<GridItemsLayout>(result);
var gridItemsLayout = (GridItemsLayout)result;
Assert.AreEqual(ItemsLayoutOrientation.Horizontal, gridItemsLayout.Orientation);
Assert.AreEqual(1, gridItemsLayout.Span);
}

[Test]
public void VerticalGridShouldReturnGridItemsLayout()
{
var converter = new ItemsLayoutTypeConverter();
var result = converter.ConvertFromInvariantString("VerticalGrid");

Assert.IsInstanceOf<GridItemsLayout>(result);
var gridItemsLayout = (GridItemsLayout)result;
Assert.AreEqual(ItemsLayoutOrientation.Vertical, gridItemsLayout.Orientation);
Assert.AreEqual(1, gridItemsLayout.Span);
}

[Test]
public void HorizontalGridWithSpan4ShouldReturnGridItemsLayout()
{
var converter = new ItemsLayoutTypeConverter();
var result = converter.ConvertFromInvariantString("HorizontalGrid, 4");

Assert.IsInstanceOf<GridItemsLayout>(result);
var gridItemsLayout = (GridItemsLayout)result;
Assert.AreEqual(ItemsLayoutOrientation.Horizontal, gridItemsLayout.Orientation);
Assert.AreEqual(4, gridItemsLayout.Span);
}

[Test]
public void VerticalGridWithSpan2ShouldReturnGridItemsLayout()
{
var converter = new ItemsLayoutTypeConverter();
var result = converter.ConvertFromInvariantString("VerticalGrid,\t\t2");

Assert.IsInstanceOf<GridItemsLayout>(result);
var gridItemsLayout = (GridItemsLayout)result;
Assert.AreEqual(ItemsLayoutOrientation.Vertical, gridItemsLayout.Orientation);
Assert.AreEqual(2, gridItemsLayout.Span);
}

[Test]
public void HorizontalGridWithSpan987654ShouldReturnGridItemsLayout()
{
var converter = new ItemsLayoutTypeConverter();
var result = converter.ConvertFromInvariantString("HorizontalGrid,98654");

Assert.IsInstanceOf<GridItemsLayout>(result);
var gridItemsLayout = (GridItemsLayout)result;
Assert.AreEqual(ItemsLayoutOrientation.Horizontal, gridItemsLayout.Orientation);
Assert.AreEqual(98654, gridItemsLayout.Span);
}

[Test]
public void VerticalGridWithSpan1234ShouldReturnGridItemsLayout()
{
var converter = new ItemsLayoutTypeConverter();
var result = converter.ConvertFromInvariantString("VerticalGrid, \t 1234");

Assert.IsInstanceOf<GridItemsLayout>(result);
var gridItemsLayout = (GridItemsLayout)result;
Assert.AreEqual(ItemsLayoutOrientation.Vertical, gridItemsLayout.Orientation);
Assert.AreEqual(1234, gridItemsLayout.Span);
}

[Test]
public void HorizontalGridWithSpan0ShouldShouldThrowArgumentException()
{
var converter = new ItemsLayoutTypeConverter();
Assert.Throws<ArgumentException>(() => converter.ConvertFromInvariantString("HorizontalGrid, 0"));
}

[Test]
public void VerticalGridWithSpan0ShouldShouldThrowArgumentException()
{
var converter = new ItemsLayoutTypeConverter();
Assert.Throws<ArgumentException>(() => converter.ConvertFromInvariantString("VerticalGrid, 0"));
}

[Test]
public void HorizontalGridWithoutSpanShouldShouldThrowFormatException()
{
var converter = new ItemsLayoutTypeConverter();
Assert.Throws<InvalidOperationException>(() => converter.ConvertFromInvariantString("HorizontalGrid,"));
}

[Test]
public void VerticalGridWithoutSpanShouldShouldThrowFormatException()
{
var converter = new ItemsLayoutTypeConverter();
Assert.Throws<InvalidOperationException>(() => converter.ConvertFromInvariantString("VerticalGrid,"));
}

[Test]
public void HorizontalGridWithSpanIsNotStringShouldShouldThrowFormatException()
{
var converter = new ItemsLayoutTypeConverter();
Assert.Throws<FormatException>(() => converter.ConvertFromInvariantString("HorizontalGrid,test"));
}

[Test]
public void VerticalGridWithSpanIs1point5ShouldShouldThrowFormatException()
{
var converter = new ItemsLayoutTypeConverter();
Assert.Throws<FormatException>(() => converter.ConvertFromInvariantString("VerticalGrid, 1.5"));
}

[Test]
public void VerticalGridWith2ArgumentsShouldShouldThrowFormatException()
{
var converter = new ItemsLayoutTypeConverter();
Assert.Throws<FormatException>(() => converter.ConvertFromInvariantString("VerticalGrid, 2, 3"));
}

[Test]
public void HorizontalGridWithSemicolonShouldShouldThrowInvalidOperationException()
{
var converter = new ItemsLayoutTypeConverter();
Assert.Throws<InvalidOperationException>(() => converter.ConvertFromInvariantString("HorizontalGrid; 2"));
}

[Test]
public void LinearItemsLayoutShouldThrowInvalidOperationException()
{
var converter = new ItemsLayoutTypeConverter();
Assert.Throws<InvalidOperationException>(() => converter.ConvertFromInvariantString("LinearItemsLayout"));
}

[Test]
public void HorizontalListWithArgumentShouldShouldThrowInvalidOperationException()
{
var converter = new ItemsLayoutTypeConverter();
Assert.Throws<InvalidOperationException>(() => converter.ConvertFromInvariantString("HorizontalList, 1"));
}

[Test]
public void VerticalGridWithArgumentShouldShouldThrowInvalidOperationException()
{
var converter = new ItemsLayoutTypeConverter();
Assert.Throws<InvalidOperationException>(() => converter.ConvertFromInvariantString("VerticalList, 2"));
}

[Test]
public void EmptyStringShouldThrowInvalidOperationException()
{
var converter = new ItemsLayoutTypeConverter();
Assert.Throws<InvalidOperationException>(() => converter.ConvertFromInvariantString(string.Empty));
}

[Test]
public void NullShouldThrowArgumentNullException()
{
var converter = new ItemsLayoutTypeConverter();
Assert.Throws<ArgumentNullException>(() => converter.ConvertFromInvariantString(null));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
<Compile Include="CommandSourceTests.cs" />
<Compile Include="CommandTests.cs" />
<Compile Include="DependencyResolutionTests.cs" />
<Compile Include="ItemsLayoutTypeConverterTests.cs" />
<Compile Include="MultiBindingTests.cs" />
<Compile Include="Markup\DefaultBindablePropertiesTests.cs" />
<Compile Include="Markup\BindableObjectExtensionsTests.cs" />
Expand Down
Loading

0 comments on commit f06cb1f

Please sign in to comment.