ListView Items can not be recreated after refreshing items
See original GitHub issueDescribe the bug I’m not sure if the title is appropriate or not. Anyway, I’m trying to explain the problem. i have a listview with following codes
<ListView ItemsSource="{x:Bind Subtitles, Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:model">
<local:SubsceneUserControl Title="{x:Bind Title}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
and this is my usercontrol (as itemtemplate)
<Grid>
<SwipeControl x:Name="ListViewSwipeContainer">
<Grid VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock
Margin="10,5,200,5"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="18"
Text="{Binding ElementName=subsceneView, Path=Title}"
TextWrapping="Wrap"/>
<AppBarButton
Name="OpenFolderButton"
Grid.RowSpan="2"
MinWidth="75"
Margin="10,0,10,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Click="OpenFolderButton_Click"
Icon="OpenLocal"
IsTabStop="False"
Label="Open Folder"
Visibility="Collapsed"/>
<AppBarButton
Name="DownloadHoverButton"
Grid.RowSpan="2"
Margin="10,0,10,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Click="DownloadHoverButton_Click"
Icon="Download"
IsTabStop="False"
Label="Download"
Visibility="Collapsed"/>
</Grid>
</SwipeControl>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="HoveringStates">
<VisualState x:Name="HoverButtonsHidden"/>
<VisualState x:Name="HoverButtonsShown">
<VisualState.Setters>
<Setter Target="DownloadHoverButton.Visibility" Value="Visible"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
now I will add some items to it
private ObservableCollection<model> _subtitles = new ObservableCollection<model>();
public ObservableCollection<model> Subtitles
{
get { return _subtitles; }
set { _subtitles = value; }
}
private void AddItems()
{
Subtitles?.Clear();
for (int i = 0; i < 10; i++)
{
Subtitles.Add(new model { Title = "Test " + i });
}
}
Everything looks good
Now by clicking on the button, the download button is hidden and another button (open folder) is displayed
Now if we delete the items and add them again, we will face the following problem
As you can see, open folder button already exist (it should not be), and its location changes with each refresh.
Steps to reproduce the bug
Steps to reproduce the behavior:
- Download sample project App30.zip
Expected behavior
By deleting and adding items, the itemTemplate must be re-created and no previous changes left Screenshots
Version Info
NuGet package version:
<PackageReference Include="Microsoft.ProjectReunion" Version="0.8.1" />
<PackageReference Include="Microsoft.ProjectReunion.Foundation" Version="0.8.1" />
<PackageReference Include="Microsoft.ProjectReunion.WinUI" Version="0.8.1" />
Windows 10 version | Saw the problem? |
---|---|
Insider Build (xxxxx) | |
May 2020 Update (19041) | Yes |
November 2019 Update (18363) | |
May 2019 Update (18362) | |
October 2018 Update (17763) |
Additional context
I also see this problem in UWP I could not find a better place to report this problem. So I apologize if I reported in the wrong place
Issue Analytics
- State:
- Created 2 years ago
- Comments:8 (8 by maintainers)
Top GitHub Comments
@ghost1372 @StephenLPeters is right. This is caused by the virtualizing nature of ListView’s default panel (ItemsStackPanel). It essentially reuses the same ListViewItem (containers) and when it reuses them it might be in a state that is not correct. When you use stack panel, there is no virtualization and every item gets a container (no reuse) which as you can imagine can get very time consuming if there are many items in your list. You can try using PrepareContainerForItemOverride, ClearContainerForItemOverride to cleanup the ListViewItem’s state before they get reused. Even better would be to use the ContainerContentChanging event and do it there so you don’t need a derived type.
@ghost1372 whatever you do in the DownloadHoverButton_Click to hide the download button and show the open folder button needs to be undone in the PrepareContainerForItemOverride. Assuming the new contents for that container are infact new and should be showing the download button. If its contents that have already been downloaded you’d want to ensure you are in the downloaded state.