Home > Enterprise >  ListView in WinUI maintains ListBox text after reset
ListView in WinUI maintains ListBox text after reset

Time:09-03

I have a ListView in a WinUI 3 app (target framework net6.0-windows10.0.19041.0) with a data template that contains a TextBox. The ItemsSource is bound to an ObservableCollection in the code-behind file. There is also a button after the list to clear the collection and add a new item.

I noticed a strange behaviour: if i write anything in the TextBox, that text is retained after i click the Clear button. I would expect it to insert a completely new TextBox in the ListView, with no text in it.

Why does this happen? Does it have something to do with virtualization?

Here is the xaml file:

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

    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <ListView ItemsSource="{x:Bind _items }" >
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="x:String">
                    <TextBox Width="250" /> <!-- intentionally empty -->
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <Button Click="myButton_Click">Clear</Button>
    </StackPanel>
</Window>

And this is the code-behind file:

using Microsoft.UI.Xaml;
using System.Collections.ObjectModel;

namespace WinUISample
{
    public sealed partial class MainWindow : Window
    {
        private readonly ObservableCollection<string> _items;

        public MainWindow()
        {
            InitializeComponent();

            _items = new ObservableCollection<string>(new[]
            {
                "1"
            });
        }

        private void myButton_Click(object sender, RoutedEventArgs e)
        {
            _items.Clear();
            _items.Add("1");
        }
    }
}

CodePudding user response:

This should be because of its Virtualization feature. Since you are not binding your Text, you'll get the same text.

You can avoid this behavior by binding your Text,

<TextBox Width="250" Text="{x:Bind}" />

or by changing the ItemsPanel.

<ListView ItemsSource="{x:Bind _items}" >
    <!--<ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>-->
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="x:String">
            <TextBox Width="250" />
            <!-- intentionally empty -->
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
  • Related