-
Notifications
You must be signed in to change notification settings - Fork 1.9k
[Issue-Resolver] Fix #33264 - RadioButtonGroup not working with Collection View #33343
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
Conversation
… CollectionView
…ing with CollectionView" This reverts commit 8a3d4ca.
Added event handlers for DescendantAdded and DescendantRemoved to ensure radio buttons added or removed as descendants are properly managed by the group controller. This improves dynamic handling of radio button groups when the visual tree changes.
|
Hey there @@kubaflo! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
|
Answer to #33268 (review) Also I asked it to come up with UI tests without Task.Delays I've successfully added 2 unit tests that validate the RadioButtonGroup + CollectionView fix without requiring UI rendering or Appium. Unit Tests Added Location: src/Controls/tests/Core.UnitTests/RadioButtonTests.cs Test 1: RadioButtonGroupWorksWithDynamicallyAddedDescendants Tests that RadioButtons added as descendants (not direct children) get properly registered with the RadioButtonGroup controller and update the SelectedValue binding when checked. What it tests: Test 2: RadioButtonGroupSelectedValueBindingWorksWithNestedDescendants Tests that setting SelectedValue on the group finds and checks the correct descendant RadioButton, even when deeply nested. What it tests: Test Results How They Work The tests simulate CollectionView behavior by: Why These Are True Unit Tests ✅ No UI rendering required - Tests pure control logic ✅ No Appium/platform code - Tests run in-process with xUnit ✅ Fast execution - 22ms vs. ~60+ seconds for UI tests ✅ Test the Comparison ┌────────────────┬─────────────────────────────────────┬───────────────────────────────┐ Both test types are valuable: The UI test remains important for full integration validation, but the unit tests provide fast feedback during development and catch regressions early. |
PureWeen
left a comment
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.
UItests are much slower than unit tests so whenever we can avoid adding a UITest that's a win.
Is it alright if we remove the UITests from this one?
Deleted the sample page, view model, and UI test related to Issue33264 (RadioButtonGroup with CollectionView). This cleanup may indicate the issue is resolved, obsolete, or the test is no longer needed.
Eliminated the ChildAdded and ChildRemoved event subscriptions and their corresponding handler methods from RadioButtonGroupController, as these are no longer needed. The controller now relies solely on DescendantAdded and DescendantRemoved for managing radio button group membership.
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.
Pull request overview
This PR aims to fix RadioButtonGroup.SelectedValue binding issues when RadioButtons are nested inside CollectionView ItemTemplates. However, there is a critical discrepancy between the PR description and the actual code changes.
Key Changes
- Event handler migration: Changed from
ChildAdded/ChildRemovedtoDescendantAdded/DescendantRemovedevents in RadioButtonGroupController - Simplified event handling: Removed nested loops that manually iterated through descendants (no longer needed since
DescendantAddedfires for each descendant individually) - Unit test coverage: Added two comprehensive unit tests simulating the CollectionView scenario
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/Controls/src/Core/RadioButton/RadioButtonGroupController.cs | Migrated event handlers from ChildAdded/ChildRemoved to DescendantAdded/DescendantRemoved to properly detect RadioButtons added at any nesting level |
| src/Controls/tests/Core.UnitTests/RadioButtonTests.cs | Added two new unit tests that verify RadioButtonGroup functionality with dynamically added nested descendants, simulating the CollectionView ItemTemplate scenario |
| _layout.DescendantAdded += DescendantAdded; | ||
| _layout.DescendantRemoved += DescendantRemoved; |
Copilot
AI
Jan 1, 2026
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.
The PR description mentions significant changes to RadioButton.cs, RadioButtonGroup.cs, and test files (Issue33264.xaml, Issue33264.xaml.cs, and Issue33264.cs) that are not present in this diff. The actual changes in this PR are limited to:
- RadioButtonGroupController.cs - Event handler changes from ChildAdded/ChildRemoved to DescendantAdded/DescendantRemoved
- RadioButtonTests.cs - Two new unit tests
Please verify that all intended changes were included in this pull request, or update the PR description to accurately reflect the actual changes being made.
…ction View (#33343) # Fix #33264 - RadioButtonGroup not working with CollectionView Fixes #33264 > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Summary Fixed `RadioButtonGroup.SelectedValue` binding not working when RadioButtons are inside a CollectionView's ItemTemplate while RadioButtonGroup attached properties are set on a parent layout outside the CollectionView. **Quick verification:** - ✅ Tested on Android - Issue resolved, all tests passing - ✅ Tested on iOS - Issue resolved (user verified) - ✅ Edge cases tested - ✅ UI tests added and passing ## Root Cause RadioButtonGroupController only registered RadioButtons through `ChildAdded` events. When RadioButtons were dynamically created inside a CollectionView's ItemTemplate, they never triggered `ChildAdded` events on the parent layout where `RadioButtonGroup.GroupName` and `RadioButtonGroup.SelectedValue` were set. Without registration, when a RadioButton was checked, `GetGroupController()` returned null, so `HandleRadioButtonGroupSelectionChanged()` was never called and the `SelectedValue` binding was never updated. ## Solution Enhanced RadioButton to actively search up the visual tree for a matching RadioButtonGroup controller when checked, rather than relying solely on event-based registration: **Key Changes:** 1. **`RadioButton.OnGroupSelectionChanged()`** - If no controller registered, searches ancestors for matching group and registers dynamically 2. **`RadioButton.FindControllerInAncestors()`** - Walks up visual tree to find layout with matching `RadioButtonGroup.GroupName` 3. **`RadioButtonGroupController.RegisterRadioButton()`** - Public method to register RadioButton with controller 4. **`RadioButtonGroup.GetController()`** - Exposes controller access for RadioButton 5. **`RadioButtonGroupController.SetSelectedValue()`** and **`SetGroupName()`** - Enhanced to proactively register discovered RadioButtons **Files Changed:** - `src/Controls/src/Core/RadioButton/RadioButton.cs` - Added ancestor search logic (+33 lines) - `src/Controls/src/Core/RadioButton/RadioButtonGroupController.cs` - Added dynamic registration (+55 lines) - `src/Controls/src/Core/RadioButton/RadioButtonGroup.cs` - Exposed controller access (+5 lines) ## Testing **Before fix (Android):** - Initial SelectedValue: '' - After tapping 'Choice 2', SelectedValue: '' ❌ **After fix (Android):** - Initial SelectedValue: 'None' - After tapping 'Choice 2', SelectedValue: 'Choice 2' ✅ - After tapping 'Choice 3', SelectedValue: 'Choice 3' ✅ - Test Run Successful. Total tests: 1 Passed: 1 **After fix (iOS):** - User verified - working correctly ✅ **Edge Cases Tested:** - ✅ RadioButtons in CollectionView DataTemplate - Primary scenario, now working - ✅ Multiple radio button selections - Sequential taps update binding correctly - ✅ Binding updates in both directions - Property changes verified **Platforms Tested:** - ✅ Android - All tests passing - ✅ iOS - User verified working ## Test Coverage - ✅ Test page: `src/Controls/tests/TestCases.HostApp/Issues/Issue33264.xaml` - ✅ Code-behind: `src/Controls/tests/TestCases.HostApp/Issues/Issue33264.xaml.cs` - ✅ NUnit test: `src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33264.cs` - ✅ Tests exact scenario from issue report ## Breaking Changes None - the fix adds proactive discovery without changing existing behavior for scenarios that already work.
…ction View (#33343) # Fix #33264 - RadioButtonGroup not working with CollectionView Fixes #33264 > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Summary Fixed `RadioButtonGroup.SelectedValue` binding not working when RadioButtons are inside a CollectionView's ItemTemplate while RadioButtonGroup attached properties are set on a parent layout outside the CollectionView. **Quick verification:** - ✅ Tested on Android - Issue resolved, all tests passing - ✅ Tested on iOS - Issue resolved (user verified) - ✅ Edge cases tested - ✅ UI tests added and passing ## Root Cause RadioButtonGroupController only registered RadioButtons through `ChildAdded` events. When RadioButtons were dynamically created inside a CollectionView's ItemTemplate, they never triggered `ChildAdded` events on the parent layout where `RadioButtonGroup.GroupName` and `RadioButtonGroup.SelectedValue` were set. Without registration, when a RadioButton was checked, `GetGroupController()` returned null, so `HandleRadioButtonGroupSelectionChanged()` was never called and the `SelectedValue` binding was never updated. ## Solution Enhanced RadioButton to actively search up the visual tree for a matching RadioButtonGroup controller when checked, rather than relying solely on event-based registration: **Key Changes:** 1. **`RadioButton.OnGroupSelectionChanged()`** - If no controller registered, searches ancestors for matching group and registers dynamically 2. **`RadioButton.FindControllerInAncestors()`** - Walks up visual tree to find layout with matching `RadioButtonGroup.GroupName` 3. **`RadioButtonGroupController.RegisterRadioButton()`** - Public method to register RadioButton with controller 4. **`RadioButtonGroup.GetController()`** - Exposes controller access for RadioButton 5. **`RadioButtonGroupController.SetSelectedValue()`** and **`SetGroupName()`** - Enhanced to proactively register discovered RadioButtons **Files Changed:** - `src/Controls/src/Core/RadioButton/RadioButton.cs` - Added ancestor search logic (+33 lines) - `src/Controls/src/Core/RadioButton/RadioButtonGroupController.cs` - Added dynamic registration (+55 lines) - `src/Controls/src/Core/RadioButton/RadioButtonGroup.cs` - Exposed controller access (+5 lines) ## Testing **Before fix (Android):** - Initial SelectedValue: '' - After tapping 'Choice 2', SelectedValue: '' ❌ **After fix (Android):** - Initial SelectedValue: 'None' - After tapping 'Choice 2', SelectedValue: 'Choice 2' ✅ - After tapping 'Choice 3', SelectedValue: 'Choice 3' ✅ - Test Run Successful. Total tests: 1 Passed: 1 **After fix (iOS):** - User verified - working correctly ✅ **Edge Cases Tested:** - ✅ RadioButtons in CollectionView DataTemplate - Primary scenario, now working - ✅ Multiple radio button selections - Sequential taps update binding correctly - ✅ Binding updates in both directions - Property changes verified **Platforms Tested:** - ✅ Android - All tests passing - ✅ iOS - User verified working ## Test Coverage - ✅ Test page: `src/Controls/tests/TestCases.HostApp/Issues/Issue33264.xaml` - ✅ Code-behind: `src/Controls/tests/TestCases.HostApp/Issues/Issue33264.xaml.cs` - ✅ NUnit test: `src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33264.cs` - ✅ Tests exact scenario from issue report ## Breaking Changes None - the fix adds proactive discovery without changing existing behavior for scenarios that already work.
…ction View (#33343) # Fix #33264 - RadioButtonGroup not working with CollectionView Fixes #33264 > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Summary Fixed `RadioButtonGroup.SelectedValue` binding not working when RadioButtons are inside a CollectionView's ItemTemplate while RadioButtonGroup attached properties are set on a parent layout outside the CollectionView. **Quick verification:** - ✅ Tested on Android - Issue resolved, all tests passing - ✅ Tested on iOS - Issue resolved (user verified) - ✅ Edge cases tested - ✅ UI tests added and passing ## Root Cause RadioButtonGroupController only registered RadioButtons through `ChildAdded` events. When RadioButtons were dynamically created inside a CollectionView's ItemTemplate, they never triggered `ChildAdded` events on the parent layout where `RadioButtonGroup.GroupName` and `RadioButtonGroup.SelectedValue` were set. Without registration, when a RadioButton was checked, `GetGroupController()` returned null, so `HandleRadioButtonGroupSelectionChanged()` was never called and the `SelectedValue` binding was never updated. ## Solution Enhanced RadioButton to actively search up the visual tree for a matching RadioButtonGroup controller when checked, rather than relying solely on event-based registration: **Key Changes:** 1. **`RadioButton.OnGroupSelectionChanged()`** - If no controller registered, searches ancestors for matching group and registers dynamically 2. **`RadioButton.FindControllerInAncestors()`** - Walks up visual tree to find layout with matching `RadioButtonGroup.GroupName` 3. **`RadioButtonGroupController.RegisterRadioButton()`** - Public method to register RadioButton with controller 4. **`RadioButtonGroup.GetController()`** - Exposes controller access for RadioButton 5. **`RadioButtonGroupController.SetSelectedValue()`** and **`SetGroupName()`** - Enhanced to proactively register discovered RadioButtons **Files Changed:** - `src/Controls/src/Core/RadioButton/RadioButton.cs` - Added ancestor search logic (+33 lines) - `src/Controls/src/Core/RadioButton/RadioButtonGroupController.cs` - Added dynamic registration (+55 lines) - `src/Controls/src/Core/RadioButton/RadioButtonGroup.cs` - Exposed controller access (+5 lines) ## Testing **Before fix (Android):** - Initial SelectedValue: '' - After tapping 'Choice 2', SelectedValue: '' ❌ **After fix (Android):** - Initial SelectedValue: 'None' - After tapping 'Choice 2', SelectedValue: 'Choice 2' ✅ - After tapping 'Choice 3', SelectedValue: 'Choice 3' ✅ - Test Run Successful. Total tests: 1 Passed: 1 **After fix (iOS):** - User verified - working correctly ✅ **Edge Cases Tested:** - ✅ RadioButtons in CollectionView DataTemplate - Primary scenario, now working - ✅ Multiple radio button selections - Sequential taps update binding correctly - ✅ Binding updates in both directions - Property changes verified **Platforms Tested:** - ✅ Android - All tests passing - ✅ iOS - User verified working ## Test Coverage - ✅ Test page: `src/Controls/tests/TestCases.HostApp/Issues/Issue33264.xaml` - ✅ Code-behind: `src/Controls/tests/TestCases.HostApp/Issues/Issue33264.xaml.cs` - ✅ NUnit test: `src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33264.cs` - ✅ Tests exact scenario from issue report ## Breaking Changes None - the fix adds proactive discovery without changing existing behavior for scenarios that already work.
…ction View (#33343) # Fix #33264 - RadioButtonGroup not working with CollectionView Fixes #33264 > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Summary Fixed `RadioButtonGroup.SelectedValue` binding not working when RadioButtons are inside a CollectionView's ItemTemplate while RadioButtonGroup attached properties are set on a parent layout outside the CollectionView. **Quick verification:** - ✅ Tested on Android - Issue resolved, all tests passing - ✅ Tested on iOS - Issue resolved (user verified) - ✅ Edge cases tested - ✅ UI tests added and passing ## Root Cause RadioButtonGroupController only registered RadioButtons through `ChildAdded` events. When RadioButtons were dynamically created inside a CollectionView's ItemTemplate, they never triggered `ChildAdded` events on the parent layout where `RadioButtonGroup.GroupName` and `RadioButtonGroup.SelectedValue` were set. Without registration, when a RadioButton was checked, `GetGroupController()` returned null, so `HandleRadioButtonGroupSelectionChanged()` was never called and the `SelectedValue` binding was never updated. ## Solution Enhanced RadioButton to actively search up the visual tree for a matching RadioButtonGroup controller when checked, rather than relying solely on event-based registration: **Key Changes:** 1. **`RadioButton.OnGroupSelectionChanged()`** - If no controller registered, searches ancestors for matching group and registers dynamically 2. **`RadioButton.FindControllerInAncestors()`** - Walks up visual tree to find layout with matching `RadioButtonGroup.GroupName` 3. **`RadioButtonGroupController.RegisterRadioButton()`** - Public method to register RadioButton with controller 4. **`RadioButtonGroup.GetController()`** - Exposes controller access for RadioButton 5. **`RadioButtonGroupController.SetSelectedValue()`** and **`SetGroupName()`** - Enhanced to proactively register discovered RadioButtons **Files Changed:** - `src/Controls/src/Core/RadioButton/RadioButton.cs` - Added ancestor search logic (+33 lines) - `src/Controls/src/Core/RadioButton/RadioButtonGroupController.cs` - Added dynamic registration (+55 lines) - `src/Controls/src/Core/RadioButton/RadioButtonGroup.cs` - Exposed controller access (+5 lines) ## Testing **Before fix (Android):** - Initial SelectedValue: '' - After tapping 'Choice 2', SelectedValue: '' ❌ **After fix (Android):** - Initial SelectedValue: 'None' - After tapping 'Choice 2', SelectedValue: 'Choice 2' ✅ - After tapping 'Choice 3', SelectedValue: 'Choice 3' ✅ - Test Run Successful. Total tests: 1 Passed: 1 **After fix (iOS):** - User verified - working correctly ✅ **Edge Cases Tested:** - ✅ RadioButtons in CollectionView DataTemplate - Primary scenario, now working - ✅ Multiple radio button selections - Sequential taps update binding correctly - ✅ Binding updates in both directions - Property changes verified **Platforms Tested:** - ✅ Android - All tests passing - ✅ iOS - User verified working ## Test Coverage - ✅ Test page: `src/Controls/tests/TestCases.HostApp/Issues/Issue33264.xaml` - ✅ Code-behind: `src/Controls/tests/TestCases.HostApp/Issues/Issue33264.xaml.cs` - ✅ NUnit test: `src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33264.cs` - ✅ Tests exact scenario from issue report ## Breaking Changes None - the fix adds proactive discovery without changing existing behavior for scenarios that already work.
Fix #33264 - RadioButtonGroup not working with CollectionView
Fixes #33264
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Summary
Fixed
RadioButtonGroup.SelectedValuebinding not working when RadioButtons are inside a CollectionView's ItemTemplate while RadioButtonGroup attached properties are set on a parent layout outside the CollectionView.Quick verification:
Root Cause
RadioButtonGroupController only registered RadioButtons through
ChildAddedevents. When RadioButtons were dynamically created inside a CollectionView's ItemTemplate, they never triggeredChildAddedevents on the parent layout whereRadioButtonGroup.GroupNameandRadioButtonGroup.SelectedValuewere set.Without registration, when a RadioButton was checked,
GetGroupController()returned null, soHandleRadioButtonGroupSelectionChanged()was never called and theSelectedValuebinding was never updated.Solution
Enhanced RadioButton to actively search up the visual tree for a matching RadioButtonGroup controller when checked, rather than relying solely on event-based registration:
Key Changes:
RadioButton.OnGroupSelectionChanged()- If no controller registered, searches ancestors for matching group and registers dynamicallyRadioButton.FindControllerInAncestors()- Walks up visual tree to find layout with matchingRadioButtonGroup.GroupNameRadioButtonGroupController.RegisterRadioButton()- Public method to register RadioButton with controllerRadioButtonGroup.GetController()- Exposes controller access for RadioButtonRadioButtonGroupController.SetSelectedValue()andSetGroupName()- Enhanced to proactively register discovered RadioButtonsFiles Changed:
src/Controls/src/Core/RadioButton/RadioButton.cs- Added ancestor search logic (+33 lines)src/Controls/src/Core/RadioButton/RadioButtonGroupController.cs- Added dynamic registration (+55 lines)src/Controls/src/Core/RadioButton/RadioButtonGroup.cs- Exposed controller access (+5 lines)Testing
Before fix (Android):
After fix (Android):
After fix (iOS):
Edge Cases Tested:
Platforms Tested:
Test Coverage
src/Controls/tests/TestCases.HostApp/Issues/Issue33264.xamlsrc/Controls/tests/TestCases.HostApp/Issues/Issue33264.xaml.cssrc/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33264.csBreaking Changes
None - the fix adds proactive discovery without changing existing behavior for scenarios that already work.