From 2aba33296f26921810a1204baeb7d19d2ccd18be Mon Sep 17 00:00:00 2001 From: "E.Z. Hart" Date: Wed, 4 Nov 2020 17:22:16 -0700 Subject: [PATCH 1/2] Bind RadioButton default template root properties to RadioButton's properties Fixes #12345 --- .Xamarin.Forms.iOS.slnf | 12 +-- .../RadioButtonTemplateTests.cs | 81 +++++++++++++++++++ .../Xamarin.Forms.Core.UnitTests.csproj | 1 + Xamarin.Forms.Core/RadioButton.cs | 19 +++-- ...amarin.Forms.Platform.iOS.UnitTests.csproj | 2 +- 5 files changed, 98 insertions(+), 17 deletions(-) create mode 100644 Xamarin.Forms.Core.UnitTests/RadioButtonTemplateTests.cs diff --git a/.Xamarin.Forms.iOS.slnf b/.Xamarin.Forms.iOS.slnf index 4b5c920461a..54282649aa2 100644 --- a/.Xamarin.Forms.iOS.slnf +++ b/.Xamarin.Forms.iOS.slnf @@ -2,13 +2,7 @@ "solution": { "path": "Xamarin.Forms.sln", "projects": [ - "EmbeddingTestBeds\\Embedding.XF\\Embedding.XF.csproj", - "EmbeddingTestBeds\\Embedding.iOS\\Embedding.iOS.csproj", - "PagesGallery\\PagesGallery.iOS\\PagesGallery.iOS.csproj", - "PagesGallery\\PagesGallery\\PagesGallery.csproj", "Stubs\\Xamarin.Forms.Platform.iOS\\Xamarin.Forms.Platform.iOS (Forwarders).csproj", - "XFCorePostProcessor.Tasks\\XFCorePostProcessor.Tasks.csproj", - "Xamarin.Flex\\Xamarin.Flex.shproj", "Xamarin.Forms.Build.Tasks\\Xamarin.Forms.Build.Tasks.csproj", "Xamarin.Forms.ControlGallery.iOS\\Xamarin.Forms.ControlGallery.iOS.csproj", "Xamarin.Forms.Controls.Issues\\Xamarin.Forms.Controls.Issues.Shared\\Xamarin.Forms.Controls.Issues.Shared.shproj", @@ -22,13 +16,9 @@ "Xamarin.Forms.Maps.iOS\\Xamarin.Forms.Maps.iOS.csproj", "Xamarin.Forms.Maps\\Xamarin.Forms.Maps.csproj", "Xamarin.Forms.Material.iOS\\Xamarin.Forms.Material.iOS.csproj", - "Xamarin.Forms.Pages.Azure\\Xamarin.Forms.Pages.Azure.csproj", - "Xamarin.Forms.Pages.UnitTests\\Xamarin.Forms.Pages.UnitTests.csproj", - "Xamarin.Forms.Pages\\Xamarin.Forms.Pages.csproj", + "Xamarin.Forms.Platform.iOS.UnitTests\\Xamarin.Forms.Platform.iOS.UnitTests.csproj", "Xamarin.Forms.Platform.iOS\\Xamarin.Forms.Platform.iOS.csproj", "Xamarin.Forms.Platform\\Xamarin.Forms.Platform.csproj", - "Xamarin.Forms.Sandbox.iOS\\Xamarin.Forms.Sandbox.iOS.csproj", - "Xamarin.Forms.Sandbox\\Xamarin.Forms.Sandbox.csproj", "Xamarin.Forms.Xaml.Design\\Xamarin.Forms.Xaml.Design.csproj", "Xamarin.Forms.Xaml.UnitTests\\Xamarin.Forms.Xaml.UnitTests.csproj", "Xamarin.Forms.Xaml\\Xamarin.Forms.Xaml.csproj" diff --git a/Xamarin.Forms.Core.UnitTests/RadioButtonTemplateTests.cs b/Xamarin.Forms.Core.UnitTests/RadioButtonTemplateTests.cs new file mode 100644 index 00000000000..0f6dcca2711 --- /dev/null +++ b/Xamarin.Forms.Core.UnitTests/RadioButtonTemplateTests.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections; +using NUnit.Framework; + +namespace Xamarin.Forms.Core.UnitTests +{ + [TestFixture(Category = "RadioButton")] + public class RadioButtonTemplateTests : BaseTestFixture + { + class FrameStyleCases : IEnumerable + { + public IEnumerator GetEnumerator() + { + yield return new object[] { Frame.VerticalOptionsProperty, LayoutOptions.End }; + yield return new object[] { Frame.HorizontalOptionsProperty, LayoutOptions.End }; + yield return new object[] { Frame.BackgroundColorProperty, Color.Red }; + yield return new object[] { Frame.BorderColorProperty, Color.Magenta }; + yield return new object[] { Frame.MarginProperty, new Thickness(1, 2, 3, 4) }; + yield return new object[] { Frame.OpacityProperty, 0.67 }; + yield return new object[] { Frame.RotationProperty, 0.3 }; + yield return new object[] { Frame.ScaleProperty, 0.8 }; + yield return new object[] { Frame.ScaleXProperty, 0.9 }; + yield return new object[] { Frame.ScaleYProperty, 0.95 }; + yield return new object[] { Frame.TranslationXProperty, 123 }; + yield return new object[] { Frame.TranslationYProperty, 321 }; + } + } + + [TestCaseSource(typeof(FrameStyleCases))] + [Description("Frame Style properties should not affect RadioButton")] + public void RadioButtonIgnoresFrameStyleProperties(BindableProperty property, object value) + { + var implicitFrameStyle = new Style(typeof(Frame)); + implicitFrameStyle.Setters.Add(new Setter() { Property = property, Value = value }); + + var page = new ContentPage(); + page.Resources.Add(implicitFrameStyle); + + var radioButton = new RadioButton() { ControlTemplate = RadioButton.DefaultTemplate }; + page.Content = radioButton; + + var root = (radioButton as IControlTemplated)?.TemplateRoot as Frame; + + Assert.IsNotNull(root); + Assert.That(root.GetValue(property), Is.Not.EqualTo(value), $"{property.PropertyName} should be ignored."); + } + + class RadioButtonStyleCases : IEnumerable + { + public IEnumerator GetEnumerator() + { + yield return new object[] { RadioButton.VerticalOptionsProperty, LayoutOptions.End }; + yield return new object[] { RadioButton.HorizontalOptionsProperty, LayoutOptions.End }; + yield return new object[] { RadioButton.BackgroundColorProperty, Color.Red }; + yield return new object[] { RadioButton.MarginProperty, new Thickness(1, 2, 3, 4) }; + yield return new object[] { RadioButton.OpacityProperty, 0.67 }; + yield return new object[] { RadioButton.RotationProperty, 0.3 }; + yield return new object[] { RadioButton.ScaleProperty, 0.8}; + yield return new object[] { RadioButton.ScaleXProperty, 0.9 }; + yield return new object[] { RadioButton.ScaleYProperty, 0.95 }; + yield return new object[] { RadioButton.TranslationXProperty, 123 }; + yield return new object[] { RadioButton.TranslationYProperty, 321 }; + } + } + + [TestCaseSource(typeof(RadioButtonStyleCases))] + [Description("RadioButton Style properties should affect RadioButton")] + public void RadioButtonStyleSetsPropertyOnTemplateRoot(BindableProperty property, object value) + { + var radioButtonStyle = new Style(typeof(RadioButton)); + radioButtonStyle.Setters.Add(new Setter() { Property = property, Value = value }); + + var radioButton = new RadioButton() { ControlTemplate = RadioButton.DefaultTemplate, Style = radioButtonStyle }; + + var root = (radioButton as IControlTemplated)?.TemplateRoot as Frame; + + Assert.IsNotNull(root); + Assert.That(root.GetValue(property), Is.EqualTo(value), $"{property.PropertyName} should match."); + } + } +} diff --git a/Xamarin.Forms.Core.UnitTests/Xamarin.Forms.Core.UnitTests.csproj b/Xamarin.Forms.Core.UnitTests/Xamarin.Forms.Core.UnitTests.csproj index b1523c6ccb4..0875f12b296 100644 --- a/Xamarin.Forms.Core.UnitTests/Xamarin.Forms.Core.UnitTests.csproj +++ b/Xamarin.Forms.Core.UnitTests/Xamarin.Forms.Core.UnitTests.csproj @@ -84,6 +84,7 @@ + diff --git a/Xamarin.Forms.Core/RadioButton.cs b/Xamarin.Forms.Core/RadioButton.cs index 6fbe9d84dd5..bd5a17cc5c0 100644 --- a/Xamarin.Forms.Core/RadioButton.cs +++ b/Xamarin.Forms.Core/RadioButton.cs @@ -417,18 +417,27 @@ void HandleRadioButtonGroupValueChanged(Layout layout, RadioButtonGroupVal IsChecked = true; } + static void BindToTemplatedParent(BindableObject bindableObject, params BindableProperty[] properties) + { + foreach (var property in properties) + { + bindableObject.SetBinding(property, new Binding(property.PropertyName, + source: RelativeBindingSource.TemplatedParent)); + } + } + static View BuildDefaultTemplate() { var frame = new Frame { HasShadow = false, - BackgroundColor = Color.Transparent, - VerticalOptions = LayoutOptions.Start, - HorizontalOptions = LayoutOptions.Start, - Margin = new Thickness(6), - Padding = new Thickness(0) + Padding = 6 }; + BindToTemplatedParent(frame, BackgroundColorProperty, Frame.BorderColorProperty, HorizontalOptionsProperty, + MarginProperty, OpacityProperty, RotationProperty, ScaleProperty, ScaleXProperty, ScaleYProperty, + TranslationYProperty, TranslationXProperty, VerticalOptionsProperty); + var grid = new Grid { RowSpacing = 0, diff --git a/Xamarin.Forms.Platform.iOS.UnitTests/Xamarin.Forms.Platform.iOS.UnitTests.csproj b/Xamarin.Forms.Platform.iOS.UnitTests/Xamarin.Forms.Platform.iOS.UnitTests.csproj index 833596a53b3..90d41f0b883 100644 --- a/Xamarin.Forms.Platform.iOS.UnitTests/Xamarin.Forms.Platform.iOS.UnitTests.csproj +++ b/Xamarin.Forms.Platform.iOS.UnitTests/Xamarin.Forms.Platform.iOS.UnitTests.csproj @@ -84,4 +84,4 @@ - + \ No newline at end of file From 21555d1fc482383717088e8e387efda15b713ae9 Mon Sep 17 00:00:00 2001 From: "E.Z. Hart" Date: Fri, 6 Nov 2020 08:28:18 -0700 Subject: [PATCH 2/2] Revert project file changes --- .Xamarin.Forms.iOS.slnf | 12 +++++++++++- .../Xamarin.Forms.Core.UnitTests.csproj | 3 +-- .../Xamarin.Forms.Platform.iOS.UnitTests.csproj | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.Xamarin.Forms.iOS.slnf b/.Xamarin.Forms.iOS.slnf index 54282649aa2..4b5c920461a 100644 --- a/.Xamarin.Forms.iOS.slnf +++ b/.Xamarin.Forms.iOS.slnf @@ -2,7 +2,13 @@ "solution": { "path": "Xamarin.Forms.sln", "projects": [ + "EmbeddingTestBeds\\Embedding.XF\\Embedding.XF.csproj", + "EmbeddingTestBeds\\Embedding.iOS\\Embedding.iOS.csproj", + "PagesGallery\\PagesGallery.iOS\\PagesGallery.iOS.csproj", + "PagesGallery\\PagesGallery\\PagesGallery.csproj", "Stubs\\Xamarin.Forms.Platform.iOS\\Xamarin.Forms.Platform.iOS (Forwarders).csproj", + "XFCorePostProcessor.Tasks\\XFCorePostProcessor.Tasks.csproj", + "Xamarin.Flex\\Xamarin.Flex.shproj", "Xamarin.Forms.Build.Tasks\\Xamarin.Forms.Build.Tasks.csproj", "Xamarin.Forms.ControlGallery.iOS\\Xamarin.Forms.ControlGallery.iOS.csproj", "Xamarin.Forms.Controls.Issues\\Xamarin.Forms.Controls.Issues.Shared\\Xamarin.Forms.Controls.Issues.Shared.shproj", @@ -16,9 +22,13 @@ "Xamarin.Forms.Maps.iOS\\Xamarin.Forms.Maps.iOS.csproj", "Xamarin.Forms.Maps\\Xamarin.Forms.Maps.csproj", "Xamarin.Forms.Material.iOS\\Xamarin.Forms.Material.iOS.csproj", - "Xamarin.Forms.Platform.iOS.UnitTests\\Xamarin.Forms.Platform.iOS.UnitTests.csproj", + "Xamarin.Forms.Pages.Azure\\Xamarin.Forms.Pages.Azure.csproj", + "Xamarin.Forms.Pages.UnitTests\\Xamarin.Forms.Pages.UnitTests.csproj", + "Xamarin.Forms.Pages\\Xamarin.Forms.Pages.csproj", "Xamarin.Forms.Platform.iOS\\Xamarin.Forms.Platform.iOS.csproj", "Xamarin.Forms.Platform\\Xamarin.Forms.Platform.csproj", + "Xamarin.Forms.Sandbox.iOS\\Xamarin.Forms.Sandbox.iOS.csproj", + "Xamarin.Forms.Sandbox\\Xamarin.Forms.Sandbox.csproj", "Xamarin.Forms.Xaml.Design\\Xamarin.Forms.Xaml.Design.csproj", "Xamarin.Forms.Xaml.UnitTests\\Xamarin.Forms.Xaml.UnitTests.csproj", "Xamarin.Forms.Xaml\\Xamarin.Forms.Xaml.csproj" diff --git a/Xamarin.Forms.Core.UnitTests/Xamarin.Forms.Core.UnitTests.csproj b/Xamarin.Forms.Core.UnitTests/Xamarin.Forms.Core.UnitTests.csproj index 0875f12b296..6dd884c8a68 100644 --- a/Xamarin.Forms.Core.UnitTests/Xamarin.Forms.Core.UnitTests.csproj +++ b/Xamarin.Forms.Core.UnitTests/Xamarin.Forms.Core.UnitTests.csproj @@ -84,7 +84,6 @@ - @@ -290,4 +289,4 @@ - \ No newline at end of file + diff --git a/Xamarin.Forms.Platform.iOS.UnitTests/Xamarin.Forms.Platform.iOS.UnitTests.csproj b/Xamarin.Forms.Platform.iOS.UnitTests/Xamarin.Forms.Platform.iOS.UnitTests.csproj index 90d41f0b883..833596a53b3 100644 --- a/Xamarin.Forms.Platform.iOS.UnitTests/Xamarin.Forms.Platform.iOS.UnitTests.csproj +++ b/Xamarin.Forms.Platform.iOS.UnitTests/Xamarin.Forms.Platform.iOS.UnitTests.csproj @@ -84,4 +84,4 @@ - \ No newline at end of file +