MSDN 写道:
DrawingVisual 是一个轻量级的绘图类,用于渲染形状、图像或文本。这个类被认为是轻量级的,因为它不提供布局、输入、焦点或事件处理,从而提高了它的性能。出于这个原因,绘图是背景和剪贴画的理想选择。
我编写了一个代码,通过 Line 对象绘制千行,通过 DrawingVisual 对象在图像上绘制千行。比较两种方式的性能我没有看到差异。在任何一种情况下,滚动最终图片都不够流畅。
为什么每种情况下的滚动延迟都相同,而 DrawingVisual 的性能优势在哪里?
第一种方式
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<Canvas Background="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"
Name="layoutView">
<Image>
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<ImageDrawing x:Name="testImage"/>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Canvas>
</ScrollViewer>
和
ImageSource imageSource = new BitmapImage(uri);
testImage.Rect = new Rect(
0, 0, imageSource.Width, imageSource.Height);
testImage.ImageSource = imageSource;
layoutView.Width = imageSource.Width;
layoutView.Height = imageSource.Height;
Random r = new Random();
int max = Math.Min(
(int)imageSource.Height, (int)imageSource.Width);
for (int i = 0; i < 1000; i++)
{
Point p1 = new Point(r.Next(max), r.Next(max));
Point p2 = new Point(r.Next(max), r.Next(max));
Line line = new Line();
line.X1 = p1.X;
line.Y1 = p1.Y;
line.X2 = p2.X;
line.Y2 = p2.Y;
line.Stroke = Brushes.Red;
layoutView.Children.Add(line);
}
第二种方式
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<my:VisualView Background="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"
x:Name="layoutView">
</my:VisualView>
</ScrollViewer>
和
public class VisualView : Canvas
{
List<Visual> visuals = new List<Visual>();
protected override int VisualChildrenCount
{
get
{
return visuals.Count;
}
}
protected override Visual GetVisualChild(int index)
{
return visuals[index];
}
public void AddVisual(Visual visual)
{
visuals.Add(visual);
base.AddVisualChild(visual);
base.AddLogicalChild(visual);
}
public void RemoveVisual(Visual visual)
{
visuals.Remove(visual);
base.RemoveVisualChild(visual);
base.RemoveLogicalChild(visual);
}
}
和
ImageSource imageSource = new BitmapImage(uri);
Random r = new Random();
int max = Math.Min(
(int)imageSource.Height, (int)imageSource.Width);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
dc.DrawImage(imageSource, new Rect(
0, 0, imageSource.Width, imageSource.Height));
dc.Close();
layoutView.AddVisual(dv);
layoutView.Width = imageSource.Width;
layoutView.Height = imageSource.Height;
}
Pen pen = new Pen(Brushes.Red, 1);
for (int i = 0; i < 1000; i++)
{
dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
Point p1 = new Point(r.Next(max), r.Next(max));
Point p2 = new Point(r.Next(max), r.Next(max));
dc.DrawLine(pen, p1, p2);
dc.Close();
layoutView.AddVisual(dv);
}
}