maui-linux/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issu.../Bugzilla32871.cs

184 строки
4.4 KiB
C#

using System;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
using System.ComponentModel;
#if UITEST
using NUnit.Framework;
using Xamarin.Forms.Core.UITests;
#endif
namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Bugzilla, 32871, "Numeric Keyboard does not work when text has a binding to a value", PlatformAffected.Default)]
public class Bugzilla32871 : TestContentPage
{
public static class Ids
{
public const string ValueEntry = nameof(ValueEntry);
public const string ValueLabel = nameof(ValueLabel);
public const string TypeEntry = nameof(TypeEntry);
public const string AddHorizontal = nameof(AddHorizontal);
public const string TypeLabel = nameof(TypeLabel);
public const string BindButton = nameof(BindButton);
}
[Preserve(AllMembers = true)]
public class ViewModel<T> : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public ViewModel() { }
public T _value;
public T Value
{
get { return _value; }
set
{
_value = value;
s_labelValue.Text = $"value: {value}";
OnPropertyChanged(nameof(Value));
}
}
}
public static Label s_labelValue;
protected override void Init()
{
var stack = new StackLayout();
// text to be coerced
var entryValue = new Entry() { AutomationId = Ids.ValueEntry };
stack.Children.Add(entryValue);
// feedback of the value coerced from text
s_labelValue = new Label() { Text = "value: [none]", AutomationId = Ids.ValueLabel };
stack.Children.Add(s_labelValue);
// the type being coerced from text
var entryType = new Entry() { AutomationId = Ids.TypeEntry };
stack.Children.Add(entryType);
// feedback of the type being coerced from text
var labelType = new Label() { Text = "type: [none]", AutomationId = Ids.TypeLabel };
stack.Children.Add(labelType);
// create view model of the type being coerced; clear text
var bindButton = new Button() { Text = "Bind", AutomationId = Ids.BindButton };
stack.Children.Add(bindButton);
bindButton.Clicked += (o, e) =>
{
try
{
var type = Type.GetType(entryType.Text);
BindingContext = Activator.CreateInstance(
typeof(ViewModel<>).MakeGenericType(type)
);
entryValue.Text = string.Empty;
labelType.Text = $"type: {type.FullName}";
}
catch (Exception ex)
{
labelType.Text = $"type: {ex.Message}";
}
entryValue.SetBinding(Entry.TextProperty, "Value");
};
this.Content = stack;
}
#if UITEST
[Test]
public void Issue32871Test()
{
RunningApp.WaitForElement(q => q.Marked(Ids.BindButton));
var types = new Type[] {
typeof(double),
typeof(int),
typeof(float),
typeof(decimal),
};
var values = new string[] {
"0.1",
"0",
"-0.1",
"-1.1",
"-.1",
".1",
"00",
"01",
};
foreach (var type in types)
Theory(type, values);
}
public bool TryParse(Type type, string value, ref string result)
{
if (value.EndsWith("."))
return false;
if (value == "-0")
return false;
try
{
result = $"{Convert.ChangeType(value, type)}";
return true;
}
catch
{
return false;
}
}
public void Theory(Type type, string[] values)
{
RunningApp.ClearText(Ids.TypeEntry);
RunningApp.EnterText(Ids.TypeEntry, type.FullName);
RunningApp.Tap(Ids.BindButton);
RunningApp.WaitForElement(q => q.Marked($"type: {type.FullName}"));
foreach (var value in values)
Theory(type, value);
}
public void Theory(Type type, string value)
{
try { Convert.ChangeType(value, type); } catch { return; }
Console.WriteLine($"TEST CASE: type={type.FullName}, value={value}");
RunningApp.ClearText(Ids.ValueEntry);
var input = string.Empty;
var output = string.Empty;
foreach (var c in value)
{
input += c;
RunningApp.EnterText(Ids.ValueEntry, $"{c}");
if (TryParse(type, input, ref output))
input = output;
if (string.IsNullOrEmpty(output))
continue;
RunningApp.WaitForElement(q => q.Marked($"value: {output}"));
}
if (!Equals(Convert.ChangeType(value, type), Convert.ChangeType(output, type)))
throw new Exception($"Value '{value}' entered as '{output}'.");
}
#endif
}
}