Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 如何提高画布渲染性能?_Wpf_Performance_Canvas_Rendering_Shape - Fatal编程技术网

Wpf 如何提高画布渲染性能?

Wpf 如何提高画布渲染性能?,wpf,performance,canvas,rendering,shape,Wpf,Performance,Canvas,Rendering,Shape,我必须画很多(大约1/20万)作为[画布][2]的孩子。我在我的WPF应用程序中将这项工作分为两部分:首先,在将形状添加为画布的子对象之后,我通过设置每个形状的属性(如边距、填充、宽度等)来创建形状 MyCanvas.Children.Add(MyShape) 现在我想提高第二部分的性能,因为当我绘制形状时,我的应用程序会被阻塞很长一段时间。因此,我尝试使用[BeginInvoke][4]及其方法与不同的[priorities][5]:仅当我使用背景优先级时,主应用程序不会阻止,否则应用程序将

我必须画很多(大约1/20万)作为[画布][2]的孩子。我在我的WPF应用程序中将这项工作分为两部分:首先,在将形状添加为画布的子对象之后,我通过设置每个形状的属性(如边距、填充、宽度等)来创建形状

MyCanvas.Children.Add(MyShape)
现在我想提高第二部分的性能,因为当我绘制形状时,我的应用程序会被阻塞很长一段时间。因此,我尝试使用[BeginInvoke][4]及其方法与不同的[priorities][5]:仅当我使用背景优先级时,主应用程序不会阻止,否则应用程序将保持阻止状态,直到所有形状都添加到画布中,“图片”才会显示,但如果我使用背景优先级,显然一切都会变慢。我还尝试创建一个新线程,而不是使用Dispatcher,但没有重大变化

当我将形状添加到画布时,如何解决此问题,并通常提高应用程序的性能


谢谢。

这是很多元素,可能不会提供您想要的性能。您是否需要能够与正在渲染的每个元素交互?如果不是的话,我强烈建议你改用。如果您需要绘制形状,而不想自己创建所有这些逻辑(谁愿意?)。

同意,如果您想绘制数百万个元素,就不能在WPF中完成。如前所述,WriteableBitmapEx是一个很好的选择

请参阅WPF中的高性能图形以及可用的替代方案

如果您只是必须使用画布,请查看此项。这是一个基于画布的演示,它大量使用虚拟化来获得合理的性能,画布上有1000000个UIElements

需要使用对象而不是对象;特别是,正如建议的那样:一种可用于渲染矢量图形的可视对象。事实上,正如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;
}
为了使用DrawingVisual对象,您需要为对象创建一个宿主容器。宿主容器对象必须派生自FrameworkElement类,该类提供DrawingVisual类所缺乏的布局和事件处理支持。为可视对象创建宿主容器对象时,需要将可视对象引用存储在宿主容器中


然后,事件处理例程可以通过调用该方法来实现命中测试。该方法的HitTestResultCallback参数引用了一个用户定义的过程,您可以使用该过程来确定命中测试的结果操作。

这可能有点不相关,如果您有这种感觉,我很抱歉,但希望它能为其他用户提供一些帮助,我将与大家分享这一小贴士


用于捕获签名的画布控件存在一些性能问题。捕获过程非常曲折,因此我们无法绘制曲线。这与在UI元素上生成阴影的样式有关。禁用阴影效果解决了我们的问题

我需要与所有形状交互,我也使用形状,因为“图片”是一个矢量图形图像(图像可以缩放任何数量而不会降低质量)。使用WritableBitmapEx,我可以做同样的事情?我不会使用Shape,我会使用DrawingVisual。你能把这些细节添加到你的问题中吗?我会考虑并修改我的答案。你试过DrawingVisual吗?没有。你能给我一个如何使用DrawingVisual而不是椭圆或路径之类的形状的例子吗。例如,如何使用DrawingVisual添加到画布路径?是的,google上有一些很棒的信息。这里有一个链接让你开始:这是一个简单的例子,但它的重点是命中测试,没有解释为什么以及前面的链接。我读了第一篇文章,但在MSDN库中看到DrawingVisual不提供事件处理!我需要与我的形状交互,捕捉鼠标事件对我来说非常重要。这会有所帮助,但是WPF不适合处理50000种任何类型的视觉效果。那么什么适合处理十万个矢量图形元素呢?请参阅我链接的Q和A:正确,矢量图形实现效率低下,不适合高对象数。更好的是即时模式API,如位图或基于DirectX的渲染器。相信我,我与WPF合作多年,我从中得到的最好结果是在任何时候都能在屏幕上看到大约5000个视觉效果。再多的话,它就完全倒下了!谢谢,我会尽可能多地考虑写位图的可能性,这是可能的,因为我必须画出大约1/2万个元素(我写的),我已经用了我的答案(自从我问了这个问题已经很久了),不管怎样,谢谢你的回答,但位图不是矢量图形。多亏了这一点,我在网格上画了大量线时遇到了性能问题,通过消除阴影效果,根本没有延迟!
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);
   }
}