Windows icon indicating copy to clipboard operation
Windows copied to clipboard

SelectedIndex is set to internalIndex when parent element becomes visible

Open Joost-Jens-Luminis opened this issue 1 year ago • 0 comments

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): image

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.

Joost-Jens-Luminis avatar May 17 '24 08:05 Joost-Jens-Luminis