diff --git a/src/Controls/src/Core/RadioButton/RadioButton.cs b/src/Controls/src/Core/RadioButton/RadioButton.cs index 39ef9b6291e1..95778dbcea86 100644 --- a/src/Controls/src/Core/RadioButton/RadioButton.cs +++ b/src/Controls/src/Core/RadioButton/RadioButton.cs @@ -425,7 +425,7 @@ bool MatchesScope(RadioButtonScopeMessage message) void HandleRadioButtonGroupSelectionChanged(RadioButton selected, RadioButtonGroupSelectionChanged args) { - if (!IsChecked || selected == this || string.IsNullOrEmpty(GroupName) || GroupName != selected.GroupName || object.Equals(Value, args.Value) || !MatchesScope(args)) + if (!IsChecked || selected == this || string.IsNullOrEmpty(GroupName) || GroupName != selected.GroupName || (Value is not null && object.Equals(Value, args.Value)) || !MatchesScope(args)) { return; } diff --git a/src/Controls/tests/Core.UnitTests/RadioButtonTests.cs b/src/Controls/tests/Core.UnitTests/RadioButtonTests.cs index 1bdab98ed4aa..e838bc6e7413 100644 --- a/src/Controls/tests/Core.UnitTests/RadioButtonTests.cs +++ b/src/Controls/tests/Core.UnitTests/RadioButtonTests.cs @@ -5,7 +5,6 @@ namespace Microsoft.Maui.Controls.Core.UnitTests using Grid = Microsoft.Maui.Controls.Compatibility.Grid; using StackLayout = Microsoft.Maui.Controls.Compatibility.StackLayout; - public class RadioButtonTests : BaseTestFixture { [Fact] @@ -13,7 +12,7 @@ public void RadioButtonAddedToGroupGetsGroupName() { var layout = new StackLayout(); var groupName = "foo"; - var radioButton = new RadioButton() { Value = 1 }; + var radioButton = new RadioButton(); layout.SetValue(RadioButtonGroup.GroupNameProperty, groupName); layout.Children.Add(radioButton); @@ -26,7 +25,7 @@ public void NestedRadioButtonAddedToGroupGetsGroupName() { var layout = new StackLayout(); var groupName = "foo"; - var radioButton = new RadioButton() { Value = 1 }; + var radioButton = new RadioButton(); layout.SetValue(RadioButtonGroup.GroupNameProperty, groupName); @@ -57,7 +56,7 @@ public void LayoutGroupNameAppliesToExistingRadioButtons() { var layout = new StackLayout(); var groupName = "foo"; - var radioButton = new RadioButton() { Value = 1 }; + var radioButton = new RadioButton(); layout.Children.Add(radioButton); layout.SetValue(RadioButtonGroup.GroupNameProperty, groupName); @@ -72,8 +71,8 @@ public void UpdatedGroupNameAppliesToRadioButtonsWithOldGroupName() var groupName = "foo"; var updatedGroupName = "bar"; var otherGroupName = "other"; - var radioButton1 = new RadioButton() { Value = 1 }; - var radioButton2 = new RadioButton() { GroupName = otherGroupName, Value = 2 }; + var radioButton1 = new RadioButton(); + var radioButton2 = new RadioButton() { GroupName = otherGroupName }; layout.Children.Add(radioButton1); layout.Children.Add(radioButton2); @@ -90,10 +89,10 @@ public void ThereCanBeOnlyOne() { var groupName = "foo"; - var radioButton1 = new RadioButton() { GroupName = groupName, Value = 1 }; - var radioButton2 = new RadioButton() { GroupName = groupName, Value = 2 }; - var radioButton3 = new RadioButton() { GroupName = groupName, Value = 3 }; - var radioButton4 = new RadioButton() { GroupName = groupName, Value = 4 }; + var radioButton1 = new RadioButton() { GroupName = groupName }; + var radioButton2 = new RadioButton() { GroupName = groupName }; + var radioButton3 = new RadioButton() { GroupName = groupName }; + var radioButton4 = new RadioButton() { GroupName = groupName }; var layout = new Grid(); @@ -120,9 +119,9 @@ public void ThereCanBeOnlyOne() [Fact] public void ImpliedGroup() { - var radioButton1 = new RadioButton() { Value = 1 }; - var radioButton2 = new RadioButton() { Value = 2 }; - var radioButton3 = new RadioButton() { Value = 3 }; + var radioButton1 = new RadioButton(); + var radioButton2 = new RadioButton(); + var radioButton3 = new RadioButton(); var layout = new Grid(); @@ -146,9 +145,9 @@ public void ImpliedGroup() [Fact] public void ImpliedGroupDoesNotIncludeExplicitGroups() { - var radioButton1 = new RadioButton() { Value = 1 }; - var radioButton2 = new RadioButton() { Value = 2 }; - var radioButton3 = new RadioButton() { GroupName = "foo", Value = 3 }; + var radioButton1 = new RadioButton(); + var radioButton2 = new RadioButton(); + var radioButton3 = new RadioButton() { GroupName = "foo" }; var layout = new Grid(); @@ -167,9 +166,9 @@ public void ImpliedGroupDoesNotIncludeExplicitGroups() [Fact] public void RemovingSelectedButtonFromGroupClearsSelection() { - var radioButton1 = new RadioButton() { GroupName = "foo", Value = 1 }; - var radioButton2 = new RadioButton() { GroupName = "foo", Value = 2 }; - var radioButton3 = new RadioButton() { GroupName = "foo", Value = 3 }; + var radioButton1 = new RadioButton() { GroupName = "foo" }; + var radioButton2 = new RadioButton() { GroupName = "foo" }; + var radioButton3 = new RadioButton() { GroupName = "foo" }; radioButton1.IsChecked = true; radioButton2.IsChecked = true; diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/RadioButtonUpdateValueInsideBorderNo.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/RadioButtonUpdateValueInsideBorderNo.png new file mode 100644 index 000000000000..0fd41c78733c Binary files /dev/null and b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/RadioButtonUpdateValueInsideBorderNo.png differ diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/RadioButtonUpdateValueInsideBorderYes.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/RadioButtonUpdateValueInsideBorderYes.png new file mode 100644 index 000000000000..51cb1ae70a60 Binary files /dev/null and b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/RadioButtonUpdateValueInsideBorderYes.png differ diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22183.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22183.cs new file mode 100644 index 000000000000..6fb98461bea5 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22183.cs @@ -0,0 +1,31 @@ +#if IOS +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues +{ + public class Issue22183: _IssuesUITest + { + public Issue22183(TestDevice device) : base(device) + { + } + + public override string Issue => "RadioButton with value cannot display selected state correctly"; + + [Test] + public void RadioButtonWithValueChangeSelected() + { + App.WaitForElement("TestCollectionView"); + + App.Tap("True_0"); + App.Tap("False_0"); + + VerifyScreenshot(); + + App.Tap("True_1"); + App.Tap("False_1"); + } + } +} +#endif diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22750.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22750.cs new file mode 100644 index 000000000000..a82509d29b20 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22750.cs @@ -0,0 +1,31 @@ +#if ANDROID +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues +{ + public class Issue22750 : _IssuesUITest + { + public Issue22750(TestDevice device) : base(device) + { + } + + public override string Issue => "Using radiobuttons in a group, pressing one button works fine, but pressing the second does not reset the first hence"; + + [Test] + public void RadioButtonUpdateValueInsideBorder() + { + App.WaitForElement("WaitForStubControl"); + + App.Tap("Yes"); + + App.Tap("No"); + VerifyScreenshot("RadioButtonUpdateValueInsideBorderNo"); + + App.Tap("Yes"); + VerifyScreenshot("RadioButtonUpdateValueInsideBorderYes"); + } + } +} +#endif \ No newline at end of file diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/RadioButtonWithValueChangeSelected.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/RadioButtonWithValueChangeSelected.png new file mode 100644 index 000000000000..13272afe3e44 Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/RadioButtonWithValueChangeSelected.png differ diff --git a/src/Controls/tests/TestCases/Issues/Issue22183.xaml b/src/Controls/tests/TestCases/Issues/Issue22183.xaml new file mode 100644 index 000000000000..e71ad9291ccc --- /dev/null +++ b/src/Controls/tests/TestCases/Issues/Issue22183.xaml @@ -0,0 +1,60 @@ + + + + + + + + + + + + False + + + + + True + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Controls/tests/TestCases/Issues/Issue22183.xaml.cs b/src/Controls/tests/TestCases/Issues/Issue22183.xaml.cs new file mode 100644 index 000000000000..d840f8c44699 --- /dev/null +++ b/src/Controls/tests/TestCases/Issues/Issue22183.xaml.cs @@ -0,0 +1,71 @@ +using System.Collections.ObjectModel; +using Microsoft.Maui.Controls; +using Microsoft.Maui.Controls.Xaml; + +namespace Maui.Controls.Sample.Issues +{ + [XamlCompilation(XamlCompilationOptions.Compile)] + [Issue(IssueTracker.Github, 22183, "RadioButton with value cannot display selected state correctly", PlatformAffected.iOS)] + public partial class Issue22183 : ContentPage + { + public Issue22183() + { + InitializeComponent(); + + BindingContext = new Issue22183ViewModel(); + } + } + + public class Issue22183ViewModel + { + public ObservableCollection ItemSource { get; } = new ObservableCollection( + [new Issue22183Model() + { + GroupId = 0, + }, + new Issue22183Model() + { + GroupId = 1, + }]); + } + + public class Issue22183Model : BindableObject + { + public int GroupId { get; set; } + + public string False => $"False_{GroupId}"; + + public string True => $"True_{GroupId}"; + + public static readonly BindableProperty ShowOptionsProperty = + BindableProperty.Create(nameof(ShowOptions), typeof(bool), typeof(Issue22183Model)); + + public bool ShowOptions + { + set => SetValue(ShowOptionsProperty, value); + get => (bool)GetValue(ShowOptionsProperty); + } + + public ObservableCollection Options { get; } + + public Issue22183Model() + { + ShowOptions = false; + + Options = new ObservableCollection(); + + for (int i = 0; i < 10; i++) + { + Options.Add(new Options + { + Name = $"Options_{i}", + }); + } + } + } + + public class Options + { + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/src/Controls/tests/TestCases/Issues/Issue22750.xaml b/src/Controls/tests/TestCases/Issues/Issue22750.xaml new file mode 100644 index 000000000000..2f34c231fdb1 --- /dev/null +++ b/src/Controls/tests/TestCases/Issues/Issue22750.xaml @@ -0,0 +1,40 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/Controls/tests/TestCases/Issues/Issue22750.xaml.cs b/src/Controls/tests/TestCases/Issues/Issue22750.xaml.cs new file mode 100644 index 000000000000..1d6f4e6c3721 --- /dev/null +++ b/src/Controls/tests/TestCases/Issues/Issue22750.xaml.cs @@ -0,0 +1,49 @@ +using Microsoft.Maui.Controls; +using Microsoft.Maui.Controls.Xaml; + +namespace Maui.Controls.Sample.Issues +{ + [XamlCompilation(XamlCompilationOptions.Compile)] + [Issue(IssueTracker.Github, 22750, "Using radiobuttons in a group, pressing one button works fine, but pressing the second does not reset the first hence", PlatformAffected.Android)] + public partial class Issue22750 : ContentPage + { + readonly Issue22750ViewModel _vm; + + public Issue22750() + { + InitializeComponent(); + + BindingContext = _vm = new Issue22750ViewModel(); + } + + void OnRadioButtonCheckedChanged(object sender, CheckedChangedEventArgs e) + { + RadioButton button = sender as RadioButton; + + if (button.Content.ToString() == "Yes") + _vm.Text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; + else + _vm.Text = "Lorem ipsum dolor sit amet 2."; + } + } + + public class Issue22750ViewModel : BindableObject + { + string _stringInQuestion; + + public Issue22750ViewModel() + { + Text = "Lorem ipsum dolor sit amet 1."; + } + + public string Text + { + get { return _stringInQuestion; } + set + { + _stringInQuestion = value; + OnPropertyChanged(); + } + } + } +} \ No newline at end of file