microsoft-ui-xaml icon indicating copy to clipboard operation
microsoft-ui-xaml copied to clipboard

ListView reorder sets ListView.Items with TwoWay xBind to null values after initial reorder

Open wadeamaral opened this issue 3 years ago • 0 comments

Describe the bug

When a ListView item is being reordered with a ListView.ItemTemplate defined with a twoway binding, the value of the twoway binding is being set to null.

The reorder works correctly when reordering the first ListView Item. Once you reorder the 2nd item the value of the twoway binding is being set to null.

Steps to reproduce the bug

Consider the following xaml with the ViewModel defined in the .CS class:

<Window
    x:Class="ListViewReorderTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ListViewReorderTest"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <ListView ItemsSource="{x:Bind ViewModel.ItemCollection}"
                  CanReorderItems="True"
                  AllowDrop="True">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:ListViewItemViewModel">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="Drag Me"/>
                        <ComboBox Grid.Column="1"
                                  ItemsSource="{x:Bind StringCollection, Mode=OneWay}"
                                  SelectedItem="{x:Bind String, Mode=TwoWay}"
                                  Width="150"/>
                    </Grid>
                    
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackPanel>
</Window>

The MainWindowViewModel:

public class MainWindowViewModel : ObservableObject
   {
       private ObservableCollection<ListViewItemViewModel> _itemCollection;

       public ObservableCollection<ListViewItemViewModel> ItemCollection
       {
           get { return _itemCollection; }
           set { _itemCollection = value; RaisePropertyChanged(); }
       }

       public MainWindowViewModel()
       {
           ItemCollection = new ObservableCollection<ListViewItemViewModel>();
           ItemCollection.Add(new ListViewItemViewModel());
           ItemCollection.Add(new ListViewItemViewModel());
           ItemCollection.Add(new ListViewItemViewModel());
       }
   }

The ListViewItemViewModel:

public class ListViewItemViewModel : ObservableObject
   {
       private ObservableCollection<string> _stringCollection;

       public ObservableCollection<string> StringCollection
       {
           get { return _stringCollection; }
           set { _stringCollection = value; RaisePropertyChanged(); }
       }

       private string _string;

       public string String
       {
           get { return _string; }
           set 
           {
              SetProperty(ref _string, value);
           }
       }

       public ListViewItemViewModel()
       {
           StringCollection = new ObservableCollection<string> { "Option 1", "Option 2", "Option 3" };

           String = StringCollection.First();
       }

   }

When you run the application and reorder the ListView the first time, the application works as expected. If you then reorder the ListView again, the setter of the ListViewItemViewModel.String is being set to null.

In my testing, I always reordered the last item in the list to the first item in the list.

Expected behavior

The expectation is the reorder behavior would work the same as the first time the ListView is being reordered.

On the first reorder, the setter of the ListViewItemViewModel.String is not being hit which is correct as there is no change to the value of the property.

Screenshots

No response

NuGet package version

No response

Windows app type

  • [ ] UWP
  • [X] Win32

Device form factor

Desktop

Windows version

Windows 11 (22H2): Build 22621

Additional context

No response

wadeamaral avatar Jul 31 '22 08:07 wadeamaral