SelectedIndex is set to internalIndex when parent element becomes visible
Describe the bug
When a parent element of a segmented control is invisible at the loading of a view, the databinding is not triggered until it becomes visible. This updates the value of the SelectedIndex and sets it to 0.
In the following setup:
<controls:StackPanel
Space="20"
Visibility="{x:Bind NotNullVM. Enabled, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
<communityToolkitControls:Segmented
IsEnabled="{x:Bind NotNullVM.IsLoadingOrPersistingData, Mode=OneWay, Converter={StaticResource ReverseBoolConverter}}"
HorizontalAlignment="Stretch"
SelectedIndex="{x:Bind NotNullVM.UnitTypeFilterButtonSelection, Mode=TwoWay}"
Margin="0,8,0,0"
ItemsSource="{x:Bind NotNullVM.UnitTypeFilterButtons, Mode=OneWay}">
<communityToolkitControls:Segmented.ItemTemplate >
<DataTemplate x:DataType="models:IUnitTypeFilterButton">
<TextBlock Text="{x:Bind ButtonText}" />
</DataTemplate>
</communityToolkitControls:Segmented.ItemTemplate>
</communityToolkitControls:Segmented>
</controls:StackPanel>
The view is loaded:
- Enabled == false so the visibility of the stackpanel is hidden
- ItemsSource is populated (OnPropertyChanged is fired)
- Property bound to SelectedIndex is set to 1 (in this examples case that is "NotNullVM.UnitTypeFilterButtonSelection") (OnPropertyChanged is fired)
- Enabled = true so the stackpanel becomes visible
- Then the segmented control detects the ItemsSource is updated, it reacts by setting the SelectedIndex to "_internalSelectedIndex" (I am not 100% of the property name at this point) which is 0 at this point
- This updates the bound SelectedIndex property (in this examples case that is "NotNullVM.UnitTypeFilterButtonSelection") and sets it to 0.
We have verified, if we start with Enabled==true (so the parent stackpanel is visible), it al works properly.
Steps to reproduce
The view is loaded:
1. Enabled == false so the visibility of the stackpanel is hidden
2. ItemsSource is populated (OnPropertyChanged is fired)
3. Property bound to SelectedIndex is set to 1 (in this examples case that is "NotNullVM.UnitTypeFilterButtonSelection") (OnPropertyChanged is fired)
4. Enabled = true so the stackpanel becomes visible
5. Then the segmented control detects the ItemsSource is updated, it reacts by setting the SelectedIndex to "_internalSelectedIndex" (I am not 100% of the property name at this point) which is 0 at this point
6. This updates the bound SelectedIndex property (in this examples case that is "NotNullVM.UnitTypeFilterButtonSelection") and sets it to 0.
Expected behavior
I expect the SelectedIndex to only update if it falls outside the range of the newly available options.
Screenshots
It appears to come from here according to the stacktrace (this is the Segmented.cs file):
Code Platform
- [ ] UWP
- [X] WinAppSDK / WinUI 3
- [ ] Web Assembly (WASM)
- [ ] Android
- [ ] iOS
- [ ] MacOS
- [ ] Linux / GTK
Windows Build Number
- [ ] Windows 10 1809 (Build 17763)
- [ ] Windows 10 1903 (Build 18362)
- [ ] Windows 10 1909 (Build 18363)
- [X] Windows 10 2004 (Build 19041)
- [X] Windows 10 20H2 (Build 19042)
- [X] Windows 10 21H1 (Build 19043)
- [X] Windows 10 21H2 (Build 19044)
- [X] Windows 10 22H2 (Build 19045)
- [X] Windows 11 21H2 (Build 22000)
- [ ] Other (specify)
Other Windows Build number
No response
App minimum and target SDK version
- [ ] Windows 10, version 1809 (Build 17763)
- [ ] Windows 10, version 1903 (Build 18362)
- [ ] Windows 10, version 1909 (Build 18363)
- [X] Windows 10, version 2004 (Build 19041)
- [ ] Windows 10, version 2104 (Build 20348)
- [ ] Windows 11, version 22H2 (Build 22000)
- [ ] Other (specify)
Other SDK version
No response
Visual Studio Version
2022
Visual Studio Build Number
17.9.2
Device form factor
Desktop
Additional context
We are using MvvmCross framework. As we are using Observables, and this data is loaded as the result of a async get request, it is loaded after ViewAppread() has already triggered. (the observable OnNext is executed on the MainThread thought so that shouldn't be a problem).
Help us help you
Yes, but only if others can assist.