-
Notifications
You must be signed in to change notification settings - Fork 1.9k
[Issue-Resolver] Fix #33264 - RadioButtonGroup not working with Collection View #33268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| <?xml version="1.0" encoding="utf-8" ?> | ||
| <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" | ||
| xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | ||
| x:Class="Maui.Controls.Sample.Issues.Issue33264" | ||
| Title="Issue 33264"> | ||
|
|
||
| <StackLayout Padding="20" Spacing="10" RadioButtonGroup.GroupName="choices" RadioButtonGroup.SelectedValue="{Binding SelectedValue}"> | ||
| <Label Text="RadioButtonGroup not working with CollectionView" FontSize="18" FontAttributes="Bold"/> | ||
|
|
||
| <Label Text="Select an option below:" FontSize="14"/> | ||
|
|
||
| <CollectionView ItemsSource="{Binding Choices}" AutomationId="ChoicesCollectionView"> | ||
| <CollectionView.ItemTemplate> | ||
| <DataTemplate> | ||
| <RadioButton Content="{Binding}" Value="{Binding}" GroupName="choices" AutomationId="{Binding}"/> | ||
| </DataTemplate> | ||
| </CollectionView.ItemTemplate> | ||
| </CollectionView> | ||
|
|
||
| <Label Text="Selected value:" FontSize="14" FontAttributes="Bold"/> | ||
| <Label Text="{Binding SelectedValueDisplay}" FontSize="16" AutomationId="SelectedValueLabel"/> | ||
| </StackLayout> | ||
| </ContentPage> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| using System.Collections.ObjectModel; | ||
| using System.ComponentModel; | ||
| using System.Runtime.CompilerServices; | ||
|
|
||
| namespace Maui.Controls.Sample.Issues; | ||
|
|
||
| [Issue(IssueTracker.Github, 33264, "RadioButtonGroup not working with CollectionView", PlatformAffected.All)] | ||
| public partial class Issue33264 : ContentPage | ||
| { | ||
| public Issue33264() | ||
| { | ||
| InitializeComponent(); | ||
| BindingContext = new Issue33264ViewModel(); | ||
| } | ||
|
|
||
| protected override void OnAppearing() | ||
| { | ||
| base.OnAppearing(); | ||
| Dispatcher.DispatchDelayed(TimeSpan.FromMilliseconds(500), () => | ||
| { | ||
| CaptureState("OnAppearing"); | ||
| }); | ||
| } | ||
|
|
||
| private void CaptureState(string context) | ||
| { | ||
| var vm = BindingContext as Issue33264ViewModel; | ||
| Console.WriteLine($"=== STATE CAPTURE: {context} ==="); | ||
| Console.WriteLine($"SelectedValue: {vm?.SelectedValue ?? "null"}"); | ||
| Console.WriteLine("=== END STATE CAPTURE ==="); | ||
| } | ||
| } | ||
|
|
||
| public class Issue33264ViewModel : INotifyPropertyChanged | ||
| { | ||
| private string _selectedValue; | ||
|
|
||
| public ObservableCollection<string> Choices { get; } = new ObservableCollection<string> | ||
| { | ||
| "Choice 1", | ||
| "Choice 2", | ||
| "Choice 3" | ||
| }; | ||
|
|
||
| public string SelectedValue | ||
| { | ||
| get => _selectedValue; | ||
| set | ||
| { | ||
| if (_selectedValue != value) | ||
| { | ||
| Console.WriteLine($"=== BINDING UPDATE: SelectedValue changing from '{_selectedValue}' to '{value}' ==="); | ||
| _selectedValue = value; | ||
| OnPropertyChanged(); | ||
| OnPropertyChanged(nameof(SelectedValueDisplay)); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public string SelectedValueDisplay => string.IsNullOrEmpty(SelectedValue) ? "None" : SelectedValue; | ||
|
|
||
| public event PropertyChangedEventHandler PropertyChanged; | ||
|
|
||
| protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) | ||
| { | ||
| PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| using NUnit.Framework; | ||
| using UITest.Appium; | ||
| using UITest.Core; | ||
|
|
||
| namespace Microsoft.Maui.TestCases.Tests.Issues; | ||
|
|
||
| public class Issue33264 : _IssuesUITest | ||
| { | ||
| public override string Issue => "RadioButtonGroup not working with CollectionView"; | ||
|
|
||
| public Issue33264(TestDevice device) : base(device) { } | ||
|
|
||
| [Test] | ||
| [Category(UITestCategories.RadioButton)] | ||
| public void RadioButtonGroupBindingWorksInsideCollectionView() | ||
| { | ||
| // Wait for page to load | ||
| App.WaitForElement("ChoicesCollectionView"); | ||
| App.WaitForElement("SelectedValueLabel"); | ||
|
|
||
| // Give it a moment to render | ||
| Task.Delay(500).Wait(); | ||
|
|
||
| // Initially, SelectedValue should show "None" | ||
| var initialValue = App.FindElement("SelectedValueLabel").GetText(); | ||
| Console.WriteLine($"Initial SelectedValue: '{initialValue}'"); | ||
| Assert.That(initialValue, Is.EqualTo("None"), "Initial value should be 'None'"); | ||
|
|
||
| // Tap "Choice 2" radio button | ||
| App.WaitForElement("Choice 2"); | ||
| App.Tap("Choice 2"); | ||
|
|
||
| // Wait for binding update | ||
| Task.Delay(1000).Wait(); | ||
|
||
|
|
||
| // Verify SelectedValue is updated | ||
| var selectedValue = App.FindElement("SelectedValueLabel").GetText(); | ||
| Console.WriteLine($"After tapping 'Choice 2', SelectedValue: '{selectedValue}'"); | ||
| Assert.That(selectedValue, Is.EqualTo("Choice 2"), "SelectedValue should be updated via binding when RadioButton is checked"); | ||
|
|
||
| // Tap "Choice 3" radio button | ||
| App.Tap("Choice 3"); | ||
|
|
||
| // Wait for binding update | ||
| Task.Delay(1000).Wait(); | ||
|
||
|
|
||
| // Verify SelectedValue is updated again | ||
| selectedValue = App.FindElement("SelectedValueLabel").GetText(); | ||
| Console.WriteLine($"After tapping 'Choice 3', SelectedValue: '{selectedValue}'"); | ||
| Assert.That(selectedValue, Is.EqualTo("Choice 3"), "SelectedValue should be updated when different RadioButton is checked"); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using Task.Delay().Wait() with a hardcoded delay is not a reliable approach for UI testing. This pattern is discouraged in the MAUI test infrastructure. Instead, rely on App.WaitForElement() which has built-in retry logic. If you need additional time for rendering, App.WaitForElement() already handles this with its timeout mechanism.