From 5bb10d4bd6fc48a9b5eb69b4af6c882434fdd9b4 Mon Sep 17 00:00:00 2001 From: Durgesh Khandal Date: Tue, 29 Oct 2019 16:05:04 +0530 Subject: [PATCH] Fixed 5680 - Added method to force value coercion (#8097) --- .../Issue5680.xaml | 16 ++++++ .../Issue5680.xaml.cs | 59 ++++++++++++++++++++++ Xamarin.Forms.Core/BindableObject.cs | 30 +++++++++++ 3 files changed, 105 insertions(+) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5680.xaml create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5680.xaml.cs diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5680.xaml b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5680.xaml new file mode 100644 index 0000000..c7e01f6 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5680.xaml @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5680.xaml.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5680.xaml.cs new file mode 100644 index 0000000..5ab1152 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5680.xaml.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using Xamarin.Forms; +using System.Threading.Tasks; +using System.Collections.ObjectModel; +using System.ComponentModel; +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; + +namespace Xamarin.Forms.Controls.Issues +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Github, 5680, "[Enhancement] Add method to force value coercion")] + public partial class Issue5680 : TestContentPage + { + + public Issue5680() + { + InitializeComponent(); + } + + protected override void Init() + { + + } + + public static readonly BindableProperty AngleProperty = BindableProperty.Create("Angle", typeof(double), typeof(Issue5680), 0.0, coerceValue: CoerceAngle); + public static readonly BindableProperty MaximumAngleProperty = BindableProperty.Create("MaximumAngle", typeof(double), typeof(Issue5680), 360.0, propertyChanged: ForceCoerceValue); + + public double Angle + { + get { return (double)GetValue(AngleProperty); } + set { SetValue(AngleProperty, value); } + } + + public double MaximumAngle + { + get { return (double)GetValue(MaximumAngleProperty); } + set { SetValue(MaximumAngleProperty, value); } + } + + static object CoerceAngle(BindableObject bindable, object value) + { + var homePage = bindable as Issue5680; + double input = (double)value; + + if (input > homePage.MaximumAngle) + { + input = homePage.MaximumAngle; + } + return input; + } + + static void ForceCoerceValue(BindableObject bindable, object oldValue, object newValue) + { + bindable.CoerceValue(AngleProperty); + } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Core/BindableObject.cs b/Xamarin.Forms.Core/BindableObject.cs index 7adcfff..edb1309 100644 --- a/Xamarin.Forms.Core/BindableObject.cs +++ b/Xamarin.Forms.Core/BindableObject.cs @@ -530,6 +530,36 @@ namespace Xamarin.Forms context.Binding = null; } + public void CoerceValue(BindableProperty property) => CoerceValue(property, checkAccess: true); + + public void CoerceValue(BindablePropertyKey propertyKey) + { + if (propertyKey == null) + throw new ArgumentNullException(nameof(propertyKey)); + + CoerceValue(propertyKey.BindableProperty, checkAccess: false); + } + + void CoerceValue(BindableProperty property, bool checkAccess) + { + if (property == null) + throw new ArgumentNullException(nameof(property)); + + if (checkAccess && property.IsReadOnly) + throw new InvalidOperationException($"The BindableProperty \"{property.PropertyName}\" is readonly."); + + BindablePropertyContext bpcontext = GetContext(property); + if (bpcontext == null) + return; + + object currentValue = bpcontext.Value; + + if (property.ValidateValue != null && !property.ValidateValue(this, currentValue)) + throw new ArgumentException($"Value is an invalid value for {property.PropertyName}", nameof(currentValue)); + + property.CoerceValue?.Invoke(this, currentValue); + } + [Flags] enum BindableContextAttributes { -- 2.7.4