在 WPF 中,为什么 ListBox VirtualizingStackPanel 不能在 Windows XP 上运行?

In WPF, why doesn't a ListBox VirtualizingStackPanel work on Windows XP?

出于性能原因,我需要在滚动列表框上使用虚拟化。

我的XAML:

<Grid>
    <StackPanel>
        <Button Content="Fill" Click="Button_Click" />
        <ListBox ItemsSource="{Binding People}" ScrollViewer.CanContentScroll="True" VirtualizingStackPanel.IsVirtualizing="True">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <VirtualizingStackPanel>
                        <TextBox Text="{Binding FirstName}" />
                    </VirtualizingStackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>
</Grid>

我的代码隐藏:

public MainWindow()
{
    InitializeComponent();

    DataContext = _mainViewModel;
}

MainViewModel _mainViewModel = new MainViewModel();

private void Button_Click(object sender, RoutedEventArgs e)
{
    _mainViewModel.FillPeople();
}

我的视图模型:

class MainViewModel : INotifyPropertyChanged
{
    public ObservableCollection<Person> People { get; set; }

    public MainViewModel()
    {
        People = new ObservableCollection<Person>();
    }

    public void FillPeople()
    {
        for (int i = 0; i < 100; i++)
        {
            var person = new Person { FirstName = "John" };
            People.Add(person);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

我的数据Class:

class Person
{
    public string FirstName { get; set; }
}

当我在 Windows 7 和 Windows 10 上 运行 此代码时,列表会快速正确地填写。当我在 POSReady 2009 SP3(Windows XP 的一个变体)上 运行 它时,列表框是空白的。使用常规 StackPanel 修复它,但我需要虚拟化。有谁知道如何使它在 XP 上运行?

...那是 而不是 您使用 VirtualizingStackPanel 的方式。您将每个人 TextBox 放在自己的 VirtualizingStackPanel 中。 ListBox 虽然是 virtualizing by default,所以您不需要做任何事情。

MSDN:

For the ListBox, the default ItemsPanelTemplate specifies the VirtualizingStackPanel. For MenuItem, the default uses WrapPanel. For StatusBar, the default uses DockPanel.

摆脱那些额外的面板,看看它是否再次开始在 XP 上工作。

让我们假装 ListBox 默认情况下没有虚拟化。 正确的 虚拟化方法如下(注意,我设置的是 ItemsPanelTemplate,而不是 ItemTemplate):

<ListBox>
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel IsVirtualizing="True" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</LitBox>