dotnet/wpf

TreeView slower than the Winforms version

Open

#6,407 opened on 2022年4月13日

GitHub で見る
 (2 comments) (0 reactions) (0 assignees)C# (6,683 stars) (1,126 forks)batch import
Performancehelp wanted

説明

  • .NET Core Version: 6.0.200
  • Windows version: 22H2 (OS Build 22593.1)
  • Does the bug reproduce also in WPF for .NET Framework 4.8?
    • Sorry, I don't have that option for some reason :(. And yes I have it installed. image image

Problem description: When expanding nodes, the WPF TreeView takes longer to load than the WinForms one does.

Minimal repro: I've attached a very small project for reproducing this. TreeViewComparison.zip On the left is a WPF TreeView, on the right is a WinForms TreeView wrapped in WindowsFormsHost. Both are prepopulated with an identical bunch of nested nodes. Click the WPF text to run root.ExpandSubtree(), and click the WinForms text to run root.ExpandAll(). Click the text, not the expand arrows, since that will just open one layer. image Here I've copied the two relevant files from the solution:

<Window x:Class="TreeViewComparison.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TreeViewComparison"
        xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TreeView x:Name="WPFTree" Grid.Column="0"/>
        <WindowsFormsHost Grid.Column="1">
            <wf:TreeView x:Name="WinFormsTree"/>
        </WindowsFormsHost>
    </Grid>
</Window>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;

namespace TreeViewComparison;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        var wpf_root = new TreeViewItem() { Header = "Click to expand WPF nodes" };
        var win_root = new TreeNode("Click to expand WinForms nodes");
        WPFTree.Items.Add(wpf_root);
        WinFormsTree.Nodes.Add(win_root);
        AddGenerations(wpf_root, 5, 5);
        AddGenerations(win_root, 5, 5);
        wpf_root.Selected += (s, e) => wpf_root.ExpandSubtree();
        WinFormsTree.AfterSelect += (s, e) => win_root.ExpandAll();
    }

    private void AddGenerations(TreeViewItem item, int children, int generations)
    {
        for (int i = 0; i < children; i++)
        {
            var child = new TreeViewItem() { Header = $"Child #{i + 1}" };
            item.Items.Add(child);
            if (generations > 0)
                AddGenerations(child, children, generations - 1);
        }
    }

    private void AddGenerations(TreeNode item, int children, int generations)
    {
        for (int i = 0; i < children; i++)
        {
            var child = new TreeNode($"Child #{i + 1}");
            item.Nodes.Add(child);
            if (generations > 0)
                AddGenerations(child, children, generations - 1);
        }
    }
}

Expected behavior: WPF should be as fast as, if not faster than, WinForms at loading TreeView nodes.

Actual behavior: The WPF TreeView takes significantly longer to finish. On my computer, the WinForms view fully expands in about 8 seconds, while the WPF view takes a staggering 62 seconds. Honestly, both of these are unacceptably slow.


I am new to this repository and WPF in general so please let me know if I did anything wrong, and thank you for your work! :)

コントリビューターガイド