gli*_*ite 11 wpf performance rendering canvas shape
作为[Canvas] [2]的孩子,我必须绘制很多形状(大约半数十万).我在我的WPF应用程序中将这项工作分为两部分:首先我通过设置每个属性(如边距,填充,宽度等等)来创建形状,然后我将形状添加为Canvas的子项.
MyCanvas.Children.Add(MyShape)
Run Code Online (Sandbox Code Playgroud)
现在我想提高第二部分的性能,因为当我绘制形状时,我的应用程序被封锁了很长一段时间.所以我尝试使用Dispatcher及其方法[BeginInvoke] [4]与不同的[优先级] [5]:只有当我使用后台优先级时,主应用程序才会阻止,否则应用程序仍然被阻止,"图片"是直到所有形状都添加到我的画布中才会显示,但如果我使用背景优先级,显然一切都会变慢.我也试图创建一个新的线程,而不是使用Dispatcher,但没有重大的变化.
如何解决这个问题,并在将形状添加到Canvas时通常可以提高应用程序的性能?
谢谢.
需要使用Visual对象而不是Shape ; 特别是,如建议的那样,DrawingVisual:一个可用于渲染矢量图形的可视对象.实际上,正如在MSDN库中编写的那样:
DrawingVisual是一个轻量级绘图类,用于渲染形状,图像或文本.此类被视为轻量级,因为它不提供布局,输入,焦点或事件处理,从而提高了性能.因此,图纸非常适合背景和剪贴画.
因此,例如,要创建包含矩形的DrawingVisual:
private DrawingVisual CreateDrawingVisualRectangle()
{
DrawingVisual drawingVisual = new DrawingVisual();
// Retrieve the DrawingContext in order to create new drawing content.
DrawingContext drawingContext = drawingVisual.RenderOpen();
// Create a rectangle and draw it in the DrawingContext.
Rect rect = new Rect(new System.Windows.Point(160, 100), new System.Windows.Size(320, 80));
drawingContext.DrawRectangle(System.Windows.Media.Brushes.LightBlue, (System.Windows.Media.Pen)null, rect);
// Persist the drawing content.
drawingContext.Close();
return drawingVisual;
}
Run Code Online (Sandbox Code Playgroud)
要使用DrawingVisual对象,您需要为对象创建主机容器.主机容器对象必须派生自FrameworkElement类,该类提供DrawingVisual类缺少的布局和事件处理支持.为可视对象创建主机容器对象时,需要将可视对象引用存储在VisualCollection中.
public class MyVisualHost : FrameworkElement
{
// Create a collection of child visual objects.
private VisualCollection _children;
public MyVisualHost()
{
_children = new VisualCollection(this);
_children.Add(CreateDrawingVisualRectangle());
// Add the event handler for MouseLeftButtonUp.
this.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(MyVisualHost_MouseLeftButtonUp);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,事件处理例程可以通过调用HitTest方法来实现命中测试.方法的HitTestResultCallback参数引用用户定义的过程,您可以使用该过程来确定命中测试的结果操作.