Trong Wpf (4.0) hộp danh sách của tôi (sử dụng VirtualizingStackPanel) chứa 500 mục. Mỗi mục là một loại tùy chỉnhTại sao DrawingContext.DrawText của Wpf lại đắt đến vậy?
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)
}
Bây giờ khi di chuyển thanh cuộn của ListBox lui để mỗi của thị giác mục được tạo ra ít nhất một lần sử dụng ram đi lên đến 500 Mb sau một thời gian và sau đó - sau một thời gian - quay trở lại ca 250 Mb nhưng vẫn ở cấp độ này. Bộ nhớ bị rò rỉ ? Tôi nghĩ rằng lợi thế của một VirtualizingStackPanel là hình ảnh mà không cần thiết/có thể nhìn thấy được xử lý ...
Dù sao, sử dụng ram cực đoan này chỉ xuất hiện khi vẽ văn bản bằng cách sử dụng "DrawText". Vẽ các đối tượng khác như "DrawEllipse" không tiêu thụ quá nhiều bộ nhớ.
Có cách nào hiệu quả hơn để vẽ nhiều mục văn bản hơn bằng cách sử dụng "DrawText" của Drawing.Context không?
Đây là mẫu đầy đủ (chỉ cần tạo một dự án WPF Application mới và thay thế mã Window1): (Tôi biết có FlowDocument và FixedDocument nhưng họ không thay thế) 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>
Và các 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++) // draw 1000 "A"s
{
dc.DrawText(formattedText, new Point((i % 80) * 5, yOff));
if (i % 80 == 0) yOff += 10;
}
}
}
Bạn có thể thử StreamGeometry. Đó là trọng lượng tương đối nhẹ. http://msdn.microsoft.com/en-us/library/ms742199.aspx Mặt khác. Tôi phải nói. DrawText là thứ ít được cân nhắc hơn. Không biết tại sao nó lại lấy nhiều tài nguyên. Bạn có mẫu nào cho kịch bản trên không? –
DrawingContext.DrawGlyph có vẻ nhanh hơn nhiều so với DrawText. – fritz