In Wpf (4.0), my list (using VirtualizingStackPanel) contains 500 items. Each element has its own type.
class Page : FrameworkElement ... protected override void OnRender(DrawingContext dc) { // Drawing 1000 single characters to different positions //(formattedText is a static member which is only instantiated once and contains the string "A" or "B"...) for (int i = 0; i < 1000; i++) dc.DrawText(formattedText, new Point(....)) // Drawing 1000 ellipses: very fast and low ram usage for (int i = 0; i < 1000; i++) dc.DrawEllipse(Brushes.Black, null, new Point(....),10,10) }
Now, when you move the scroll bar of the list back and forth so that each visual of an element is created at least once, when the use of the ram-server increases to 500 MB after a while, and then - after a while - it returns to 250 MB but remains at that level. Memory leak? I thought the advantage of VirtualizationStackPanel is that visual effects that are not needed / visible are removed ...
In any case, this extreme use of ram only appears when drawing text using "DrawText". Drawing other objects, such as "DrawEllipse", does not consume so much memory.
Is there a more efficient way to draw many text elements than using Drawing.Context "DrawText"?
Here is a complete sample (just create a new Wpf application project and replace the window1 code): (I know there are FlowDocument and FixedDocument, but they are not an alternative) Xaml:
<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="900" Width="800"> <Grid Background="Black"> <ListBox Name="lb" ScrollViewer.CanContentScroll="True" Background="Black"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> </ListBox> </Grid> </Window>
And Window1.xaml.cs:
public partial class Window1 : Window { readonly ObservableCollection<FrameworkElement> collection = new ObservableCollection<FrameworkElement>(); public Window1() { InitializeComponent(); for (int i = 0; i < 500; i++) { collection.Add(new Page(){ Width = 500, Height = 800 }); } lb.ItemsSource = collection; } } public class Page : FrameworkElement { static FormattedText formattedText = new FormattedText("A", CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, new Typeface(new FontFamily("Arial").ToString()), 12,Brushes.Black); protected override void OnRender(DrawingContext dc) { dc.DrawRectangle(Brushes.White, null, new Rect(0, 0, Width, Height)); double yOff = 0; for (int i = 0; i < 1000; i++)