I'm working on a WPF app that lets users edit data records.
For a test, I'm adding 50 rows to a tree view and this takes ~200ms. This creates noticable stutter as the application isn't interactive during that time. This is only the time for creating and populating controls, no data loading or any work that could be done in a thread.
Since all these rows fit on a screen, I think it would not benefit from making it a virtualizing panel.
Is it possible to make this faster? How would I add these over multiple "frames"? How can I profile this? How can I determine a reasonable number of controls that my WPF app should be able to render?
Edit: Adding a minimal example to reproduce.
MainWindow.xaml:
<Window x:Class="WpfApp1.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"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="10">
<Button Width="100" Click="Button_Click">Test</Button>
<TextBlock Margin="10" x:Name="resultTextBox">Result</TextBlock>
</StackPanel>
<TreeView x:Name="myTreeView"></TreeView>
</DockPanel>
</Window>
MainWindow.cs:
using System.Diagnostics;
using System.Windows;
namespace WpfApp1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var myStopwatch = new Stopwatch();
myStopwatch.Start();
this.myTreeView.Items.Clear();
for (int i = 0; i < 50; i++)
{
this.myTreeView.Items.Add(new MyTreeViewItem());
}
myStopwatch.Stop();
this.resultTextBox.Text = "It took " + myStopwatch.ElapsedMilliseconds + " ms to add 50 tree view items.";
}
}
}
MyTreeViewItem.xaml:
<TreeViewItem x:Class="WpfApp1.MyTreeViewItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock>I'm a TextBlock</TextBlock>
<Button>I'm a button</Button>
<CheckBox>I'm a checkbox</CheckBox>
<TextBox>I'm a text box</TextBox>
<ComboBox SelectedIndex="0">
<ComboBox.Items>
<ComboBoxItem>I'm a combobox</ComboBoxItem>
</ComboBox.Items>
</ComboBox>
</StackPanel>
</TreeViewItem.Header>
<TreeViewItem.Items>
<TreeViewItem Visibility="Collapsed"></TreeViewItem>
</TreeViewItem.Items>
</TreeViewItem>
According to the VS profiler, it takes an additional 150ms for the Layout step after adding the items.