sjmueller

I have been building an application that uses WPF Interop. Up until now, I've been using test data in my TreeViews, and all seemed to be working well.

However, the second I hooked up a TreeView to some real data (~5000 records), performancedropped to unacceptable levels. I have to wait about 8 seconds for the treeviewto display its Items, and the gui is locked for the whole duration. At firstI thought it might have something to do with type of object i was bindingto (Linq to Sql entities). This led me to create a test project thatcould help me isolate the issue.

In my test project, I created a WPF user control with a tree view and a button,which is then added to the testform with an ElementHost control. When thebutton click event is fired, the following method handles the event:

Code Snippet

private void button1_Click(object sender,RoutedEventArgs e) {
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 0; i <2000; i++) {
TreeViewItemtvi = new TreeViewItem();
tvi.Header= "TestNodeText";
treeView.Items.Add(tvi);
}
watch.Stop();
MessageBox.Show(watch.ElapsedMilliseconds.ToString());
}


I also configured a windows forms treeview and button with a similar handler:
Code Snippet
private void button1_Click(object sender, EventArgs e) {
Stopwatch watch = new Stopwatch();
watch.Start();
List<string> appNames= new List<string>();
for (int i = 0; i <2000; i++) {
treeView1.Nodes.Add("TestNodeText");
}
watch.Stop();
System.Windows.Forms.MessageBox.Show(watch.ElapsedMilliseconds.ToString());
}

The message box for the WPF UserControl claimed 400~ milliseconds, compared to 900~for the windows form based treeview. However, those numbers are misleading, because the windows form treeview rendered instantly when the message box popped up, whereas the WPF treeview spent a full 4 seconds rendering/binding *after* the stopwatch stopped. Of course, that whole time the gui is locked.

Just to make sure this wasn't some interop related issue, i wrote the same code in a native wpf app and got the same results.

Here is my XAML for the UserControl:

Code Snippet
<UserControl x:Class="WPFInterop.Sandbox.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid>
<StackPanel Name="dockpanel">
<Button Height="23" Name="button1" Width="75" Click="button1_Click">Button</Button>
<TreeView Name="treeView"Margin="0,3,0,0">
<TreeView.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock Text="{Binding}" Padding="4,3,3,2"/>
</DockPanel>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</StackPanel>
</Grid>
</UserControl>


So I am not sure if this is a databinding issue or a rendering issue, but either way I need to figure out how to get better performance. If WPF databinding/rendering is always this slow, I will be forced to revert back to windows forms.



Re: Windows Presentation Foundation (WPF) Slow TreeView render/databind

Yi-Lun Luo - MSFT

Hello, since you¡¯re using data binding, you shouldn¡¯t manually populate the TreeView with TreeViewItems. You can simply add data to your data source. This should be much faster. For example:

private ObservableCollection<string> source = new ObservableCollection<string>();

treeView.DataContext = source;

for (int i = 0; i < 2000; i++)

{

source.Add("TestNodeText");

}

<TreeView Name="treeView" ItemsSource="{Binding}">






Re: Windows Presentation Foundation (WPF) Slow TreeView render/databind

Sam Bent - MSFT

Actually, adding TreeViewItems directly is faster than adding data items to a source, because there is no data binding going on. (However it's less flexible - you don't get the power of data templates, dynamic changes, etc.)

Which suggests that the overhead you're seeing isn't due to data binding, but rather to layout, styling, templating, etc.