ListView should convert item to string when ItemTemplate is not specified (#4016)

* Convert item to string, when ListView has no ItemTemplate

* ToStringValueConverter tests

* Format value using parameter in ToStringValueConverter
- fixes #3715
This commit is contained in:
Rasto 2018-11-02 00:04:47 +08:00 коммит произвёл Shane Neuville
Родитель dbfa47c978
Коммит 791fb0461e
5 изменённых файлов: 308 добавлений и 9 удалений

Просмотреть файл

@ -45,6 +45,17 @@ namespace Xamarin.Forms.Core.UnitTests
{
public string Name { get; set; }
public string Description { get; set; }
public override string ToString() => Name ?? base.ToString();
}
static ListItem[] CreateListItemCollection()
{
return new[]
{
new ListItem { Name = "Foo", Description = "Bar" },
new ListItem { Name = "Baz", Description = "Raz" }
};
}
[Test]
@ -55,10 +66,7 @@ namespace Xamarin.Forms.Core.UnitTests
cellTemplate.SetBinding (TextCell.DetailProperty, new Binding ("Description"));
var listView = new ListView {
ItemsSource = new[] {
new ListItem {Name = "Foo", Description = "Bar"},
new ListItem {Name = "Baz", Description = "Raz"}
},
ItemsSource = CreateListItemCollection(),
ItemTemplate = cellTemplate
};
@ -87,6 +95,27 @@ namespace Xamarin.Forms.Core.UnitTests
Assert.That (((TextCell) cell).Text, Is.Null);
}
[Test]
public void ItemTemplateIsNullObjectExecutesToString()
{
var listView = new ListView
{
ItemsSource = CreateListItemCollection()
};
Assert.AreEqual(2, listView.TemplatedItems.Count);
Cell cell = listView.TemplatedItems[0];
Assert.That(cell, Is.Not.Null);
Assert.That(cell, Is.InstanceOf<TextCell>());
Assert.That(((TextCell)cell).Text, Is.EqualTo("Foo"));
cell = listView.TemplatedItems[1];
Assert.That(cell, Is.Not.Null);
Assert.That(cell, Is.InstanceOf<TextCell>());
Assert.That(((TextCell)cell).Text, Is.EqualTo("Baz"));
}
[Test]
[Description("Setting BindingContext should trickle down to Header and Footer.")]
public void SettingBindingContextPassesToHeaderAndFooter()

Просмотреть файл

@ -0,0 +1,243 @@
using System;
using System.Globalization;
using NUnit.Framework;
namespace Xamarin.Forms.Core.UnitTests
{
[TestFixture]
public class ToStringValueConverterTests : BaseTestFixture
{
static readonly CultureInfo _enUsCulture = CultureInfo.GetCultureInfo("en-US");
static readonly CultureInfo _skSkCulture = CultureInfo.GetCultureInfo("sk-SK");
[SetUp]
public override void Setup()
{
base.Setup();
System.Threading.Thread.CurrentThread.CurrentCulture = _enUsCulture;
}
[Test]
public void NullObjectConvertsToNull()
{
var toStringValueConverter = new ToStringValueConverter();
object result = toStringValueConverter.Convert(null, null, null, null);
Assert.That(result, Is.Null);
}
[Test]
public void NullObjectWithTargetTypeConvertsToNull()
{
var toStringValueConverter = new ToStringValueConverter();
object result = toStringValueConverter.Convert(null, typeof(string), null, null);
Assert.That(result, Is.Null);
}
[Test]
public void ObjectConvertsToStringValue()
{
var toStringValueConverter = new ToStringValueConverter();
object result = toStringValueConverter.Convert(new object(), typeof(string), null, null);
Assert.That(result, Is.EqualTo("System.Object"));
}
[Test]
public void EmptyStringConvertsToEmptyString()
{
var toStringValueConverter = new ToStringValueConverter();
object result = toStringValueConverter.Convert(string.Empty, typeof(string), null, null);
Assert.That(result, Is.EqualTo(string.Empty));
}
[Test]
public void StringConvertsToString()
{
var toStringValueConverter = new ToStringValueConverter();
object result = toStringValueConverter.Convert("Hello, World!", typeof(string), null, null);
Assert.That(result, Is.EqualTo("Hello, World!"));
}
private class ToStringObject
{
public ToStringObject(string value)
{
Value = value;
}
public string Value { get; set; }
public int ToStringCounter { get; private set; }
public override string ToString()
{
ToStringCounter++;
return Value;
}
}
[Test]
public void CustomObjectWithNullValueConvertsToNull()
{
var toStringValueConverter = new ToStringValueConverter();
var value = new ToStringObject(null);
object result = toStringValueConverter.Convert(value, typeof(string), null, null);
Assert.That(result, Is.Null);
Assert.That(value.ToStringCounter, Is.EqualTo(1));
}
[Test]
public void CustomObjectWithEmptyStringConvertsToEmptyString()
{
var toStringValueConverter = new ToStringValueConverter();
var value = new ToStringObject(string.Empty);
object result = toStringValueConverter.Convert(value, typeof(string), null, null);
Assert.That(result, Is.EqualTo(string.Empty));
Assert.That(value.ToStringCounter, Is.EqualTo(1));
}
[Test]
public void CustomObjectWithStringConvertsToStringValue()
{
var toStringValueConverter = new ToStringValueConverter();
var value = new ToStringObject("Test string");
object result = toStringValueConverter.Convert(value, typeof(string), null, null);
Assert.That(result, Is.EqualTo("Test string"));
Assert.That(value.ToStringCounter, Is.EqualTo(1));
}
[Test]
public void ExecutesToStringTwice()
{
var toStringValueConverter = new ToStringValueConverter();
var value = new ToStringObject("Test string");
object result = toStringValueConverter.Convert(value, typeof(string), null, _skSkCulture);
Assert.That(result, Is.EqualTo("Test string"));
value.Value = "Hello, World!";
result = toStringValueConverter.Convert(value, typeof(string), null, _skSkCulture);
Assert.That(result, Is.EqualTo("Hello, World!"));
Assert.That(value.ToStringCounter, Is.EqualTo(2));
}
[Test]
public void DoubleValueConvertsToStringValue()
{
var toStringValueConverter = new ToStringValueConverter();
object result = toStringValueConverter.Convert(99123.567, typeof(string), null, null);
Assert.That(result, Is.EqualTo("99123.567"));
}
[Test]
public void DoubleValueWithSkCultureConvertsToStringValue()
{
var toStringValueConverter = new ToStringValueConverter();
object result = toStringValueConverter.Convert(99123.567, typeof(string), null, _skSkCulture);
Assert.That(result, Is.EqualTo("99123,567"));
}
[Test]
public void DoubleValueWithEmptyParameterConvertsToStringValue()
{
var toStringValueConverter = new ToStringValueConverter();
object result = toStringValueConverter.Convert(99123.567, typeof(string), string.Empty, null);
Assert.That(result, Is.EqualTo("99123.567"));
}
[Test]
public void DoubleValueWithEmptyParameterAndSkCultureConvertsToStringValue()
{
var toStringValueConverter = new ToStringValueConverter();
object result = toStringValueConverter.Convert(99123.567, typeof(string), string.Empty, _skSkCulture);
Assert.That(result, Is.EqualTo("99123,567"));
}
[Test]
public void DoubleValueWithNumberFormatConvertsToStringValue()
{
var toStringValueConverter = new ToStringValueConverter();
object result = toStringValueConverter.Convert(99123.567, typeof(string), "N2", null);
Assert.That(result, Is.EqualTo("99,123.57"));
}
[Test]
public void DoubleValueWithNumberFormatAndSkCultureConvertsToStringValue()
{
var toStringValueConverter = new ToStringValueConverter();
object result = toStringValueConverter.Convert(99123.567, typeof(string), "N2", _skSkCulture);
Assert.That(result, Is.EqualTo("99 123,57"));
}
[Test]
public void DoubleValueWithSpecificFormatConvertsToStringValue()
{
var toStringValueConverter = new ToStringValueConverter();
var format = new ToStringObject("#,##0.000");
object result = toStringValueConverter.Convert(99123.56, typeof(string), format, null);
Assert.That(result, Is.EqualTo("99,123.560"));
}
[Test]
public void DoubleValueWithSpecificFormatAndSkCultureConvertsToStringValue()
{
var toStringValueConverter = new ToStringValueConverter();
var format = new ToStringObject("#,##0.000");
object result = toStringValueConverter.Convert(99123.56, typeof(string), format, _skSkCulture);
Assert.That(result, Is.EqualTo("99 123,560"));
}
[Test]
public void NullObjectConvertsBackThrowsException()
{
var toStringValueConverter = new ToStringValueConverter();
TestDelegate action = () => toStringValueConverter.ConvertBack(null, null, null, null);
Assert.That(action, Throws.InstanceOf<NotSupportedException>());
}
[Test]
public void ObjectConvertsBackThrowsException()
{
var toStringValueConverter = new ToStringValueConverter();
TestDelegate action = () => toStringValueConverter.ConvertBack(new object(), typeof(string), null, null);
Assert.That(action, Throws.InstanceOf<NotSupportedException>());
}
}
}

Просмотреть файл

@ -156,6 +156,7 @@
<Compile Include="TimePickerUnitTest.cs" />
<Compile Include="ToolbarItemTests.cs" />
<Compile Include="ToolbarTrackerTests.cs" />
<Compile Include="ToStringValueConverterTests.cs" />
<Compile Include="TypeUnitTests.cs" />
<Compile Include="ViewCellTests.cs" />
<Compile Include="ViewUnitTests.cs" />

Просмотреть файл

@ -50,6 +50,8 @@ namespace Xamarin.Forms
public static readonly BindableProperty VerticalScrollBarVisibilityProperty = BindableProperty.Create(nameof(VerticalScrollBarVisibility), typeof(ScrollBarVisibility), typeof(ListView), ScrollBarVisibility.Default);
static readonly ToStringValueConverter _toStringValueConverter = new ToStringValueConverter();
readonly Lazy<PlatformConfigurationRegistry<ListView>> _platformConfigurationRegistry;
BindingBase _groupDisplayBinding;
@ -337,12 +339,8 @@ namespace Xamarin.Forms
protected override Cell CreateDefault(object item)
{
string text = null;
if (item != null)
text = item.ToString();
TextCell textCell = new TextCell();
textCell.SetBinding(TextCell.TextProperty, ".");
textCell.SetBinding(TextCell.TextProperty, ".", converter: _toStringValueConverter);
return textCell;
}

Просмотреть файл

@ -0,0 +1,28 @@
using System;
using System.Globalization;
namespace Xamarin.Forms
{
public class ToStringValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
{
return null;
}
if (value is IFormattable formattable)
{
return formattable.ToString(parameter?.ToString(), culture);
}
return value.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}