I have been having trouble with the WPF DataGrid and listbox GridView performance when displaying even small amounts of data. I though this problem was simply WPF having poor performance in general, but the problem seems to lie in the textblock control only.
I created a sample panel that I added several items to. If I add rectangles that are simply filled, the resizeing/scroll performance is perfect, but once I use textblocks, the performance goes out the window.
It looks like the performance issue arises from:
child.Measure(constraint);
When the textblock gets measured, it brings performance to a grinding halt. Is there anything that I can to to override the measurement of a textblock or something to improve performance? (I will set the size of the children explicitly)
EDIT: I have now created simplified code to arrange the items as I wanted.
The performance of this code is great except...when the width of the text inside the textblock exceed the actual width of the textblock. This brings my performance back down to a crawl - possibly because it is trying to measure the elements again?
public class TestPanel : Panel
{
private int _rowHeight = 20;
private int _columnWidth = 50;
public TestPanel()
{
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 20; j++)
{
TextBlock cell = new TextBlock();
cell.ClipToBounds = true;
cell.Width = _columnWidth;
cell.Height = _rowHeight;
cell.Text = i.ToString() + ":" + j.ToString();
this.Children.Add(cell);
}
}
}
protected override Size MeasureOverride(Size constraint)
{
return new Size(_columnWidth*20,_rowHeight*100);
}
protected override Size ArrangeOverride(Size arrangeBounds)
{
UIElementCollection children = InternalChildren;
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 20; j++)
{
UIElement child = children[i*20+j];
child.Arrange(new Rect(j * _columnWidth, i * 20, _columnWidth, 20));
}
}
return arrangeBounds;
}
}
public MainWindow()
{
InitializeComponent();
TestPanel myPanel = new TestPanel();
ScrollViewer scroll = new ScrollViewer();
myPanel.Background = Brushes.Aqua;
scroll.Content = myPanel;
this.Content = scroll;
}