| File: BindingExpressionHelper.cs | Web Access |
| Project: src\src\Controls\src\Core\Controls.Core.csproj (Microsoft.Maui.Controls) |
using System; using System.Globalization; using System.Linq; using System.Reflection; namespace Microsoft.Maui.Controls { internal static class BindingExpressionHelper { static readonly Type[] DecimalTypes = { typeof(float), typeof(decimal), typeof(double) }; internal static bool TryConvert(ref object value, BindableProperty targetProperty, Type convertTo, bool toTarget) { if (value == null) return !convertTo.GetTypeInfo().IsValueType || Nullable.GetUnderlyingType(convertTo) != null; try { if ((toTarget && targetProperty.TryConvert(ref value)) || (!toTarget && convertTo.IsInstanceOfType(value))) return true; } catch (InvalidOperationException) { //that's what TypeConverters ususally throw return false; } object original = value; try { convertTo = Nullable.GetUnderlyingType(convertTo) ?? convertTo; var stringValue = value as string ?? string.Empty; // see: https://bugzilla.xamarin.com/show_bug.cgi?id=32871 // do not canonicalize "*.[.]"; "1." should not update bound BindableProperty if (stringValue.EndsWith(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, StringComparison.Ordinal) && DecimalTypes.Contains(convertTo)) { value = original; return false; } // do not canonicalize "-0"; user will likely enter a period after "-0" if (stringValue == "-0" && DecimalTypes.Contains(convertTo)) { value = original; return false; } value = Convert.ChangeType(value, convertTo, CultureInfo.CurrentCulture); return true; } catch (Exception ex) when (ex is InvalidCastException || ex is FormatException || ex is InvalidOperationException || ex is OverflowException) { value = original; return false; } } } }