ListView reorder sets ListView.Items with TwoWay xBind to null values after initial reorder
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