AvaloniaUI / Avalonia.Xaml.Behaviors

Port of Windows UWP Xaml Behaviors for Avalonia Xaml.
MIT License
395 stars 47 forks source link

ListBox control firing SelectionChanged event before updating SelectedItem property #127

Closed 3aIno closed 1 year ago

3aIno commented 1 year ago

Describe the bug

When using the ListBox control in an Avalonia MVVM application, it appears that the control is firing the SelectionChanged event before updating the SelectedItem property. This results in the SelectedItem property referencing the old value instead of the newly selected item. This is only happening when using EventTriggerBehavior, and the issue does not occur when handling the event in code-behind.

504DBD82-1AA3-4115-898C-FCE0D351D171

To Reproduce

  1. Add a ListBox control.
  2. Bind the Items property of the ListBox to a collection in the ViewModel.
  3. Bind the SelectedItem property of the ListBox to an Observable Property in the ViewModel using a TwoWay binding.
  4. Use the Interaction.Behaviors library to bind a RelayCommand to the SelectionChanged event of the ListBox control.
  5. In the RelayCommand, log the value of the SelectedItem property.
  6. Select an item from the ListBox control.
`<ListBox x:Name="ExampleListBox" 
                         Items="{Binding ExampleItems, Mode=OneWay}"
                         SelectionMode="Single" 
                         SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
                    <Interaction.Behaviors>
                        <EventTriggerBehavior SourceObject="ExampleListBox" 
                                              EventName="SelectionChanged">
                            <InvokeCommandAction Command="{Binding SelectedItemChangedCommand}" />
                        </EventTriggerBehavior>
                    </Interaction.Behaviors>
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>`
` public ObservableCollection<string> ExampleItems { get; set; } = new()
    {
        "Test 1",
        "Test 2",
        "Test 3"
    };

    [ObservableProperty] private string _selectedExampleItem;

    [RelayCommand]
    private void SelectedExampleItemChanged()
    {
        Console.WriteLine(SelectedExampleItem);
    }

Expected behavior The the SelectedItem property should be the item in the ListBox control which has just been selected, rather than the item it was prior to the selection change.

Desktop

Additional context This may be a similar issue to that being reported here.

workgroupengineering commented 1 year ago

I have same Issue this is sample repo AListboxIssue.zip

@3aIno Have you found a workaround?

workgroupengineering commented 1 year ago

Workaround

    [RelayCommand]
    private void SelectedExampleItemChanged()
    {
        Avalonia.Threading.Dispatcher.UIThread.Post( ()=>
                        Console.WriteLine(SelectedExampleItem));
    }
wieslawsoltes commented 1 year ago

It's Avalonia issue

lnxon commented 11 months ago

I just created a pull request that fixes this issue. As wieslawsoltes suggested it was Avalonia control's issue. Please see AvaloniaUI/Avalonia pull request https://github.com/AvaloniaUI/Avalonia/pull/13503