WPF TranslateTransform具有许多对象的性能 [英] WPF TranslateTransform performance with many objects

查看:105
本文介绍了WPF TranslateTransform具有许多对象的性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一些示例代码来显示我遇到的问题.我需要使用鼠标在周围(一起)移动许多对象(> 1000多个),但这确实很耗时,我正在尝试找出原因.
这应该在新的WPF项目中运行,只需要在XAML中将网格命名为"mainGrid"即可:

I''ve written some sample code to show a problem I''m experiencing. I need to move many (>>1000) objects around (all together) using the mouse, but it''s really laggy and I''m trying to work out why.

This should run in a new WPF project, just need to name the grid "mainGrid" in the XAML:

public partial class MainWindow : Window
{
    readonly TranslateTransform _translator = new TranslateTransform();
    readonly Canvas _canvas = new Canvas();

    public MainWindow()
    {
        InitializeComponent();

        Loaded += new RoutedEventHandler(MainWindow_Loaded);
        WindowState = System.Windows.WindowState.Maximized;
            
        _canvas.RenderTransform = _translator;
        mainGrid.Children.Add(_canvas);
    }

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        Ellipse ellipse;

        for (int x = 0; x < 40; x++)
        {
            for (int y = 0; y < 100; y++)
            {
                ellipse = new Ellipse();
                ellipse.Stroke = Brushes.Black;
                ellipse.StrokeThickness = 1;
                ellipse.Fill = Brushes.Green;
                ellipse.Width = ellipse.Height = 10;

                Canvas.SetLeft(ellipse, y * 15);
                Canvas.SetTop(ellipse, x * 15);
                _canvas.Children.Add(ellipse);
            }
        }
    }

    Point _dragPoint;

    protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
    {
        _dragPoint = e.GetPosition(this);
        CaptureMouse();

        base.OnMouseDown(e);
    }

    protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
    {
        if (IsMouseCaptured)
        {
            Point newPosition = e.GetPosition(this);
            Vector dragVector = newPosition - _dragPoint;
            _dragPoint = newPosition;

            _translator.X += dragVector.X;
            _translator.Y += dragVector.Y;
        }

        base.OnMouseMove(e);
    }

    protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e)
    {
        ReleaseMouseCapture();

        base.OnMouseUp(e);
    }
}



我注意到,当您拖动屏幕侧面的大多数椭圆时,整个过程会加快,因此我猜测它与渲染有关,我无能为力.另外,如果您在椭圆上注释掉笔划,则笔划的运行速度会更快.

有任何想法吗?谢谢.



I noticed that when you drag most of the ellipses of the side of the screen the whole thing speeds up so I''m guessing its related to rendering and there''s nothing I can do stop this happening. Also if you comment out the stroke on the ellipses it runs much faster.

Any ideas? Thanks.

推荐答案

来自
这为CPU和GPU节省了重新渲染内容的成本,而使GPU可以直接从缓存进行渲染.缓存了解脏区域,因此,例如,缓存的文本块中闪烁的光标仅需要在帧之间重新渲染光标即可.甚至还有一个专门使用这些智能缓存的新Brush-有效地以一种性能大大提高的VisualBrush.


有关此内容的更多信息:
WPF的新功能:缓存的内容 [
From ScottGu''s Blog[^]:

Massive performance wins are possible with the new Cached Composition feature in WPF 4, which allows applications to cache arbitrary content including live and fully-interactive controls, vector geometry, etc. as bitmaps which persist in video memory. Once cached, these elements can be arbitrarily transformed, animated, manipulated, and can have Effects applied, all without having to re-render the cached element.

This spares both the CPU and the GPU the cost of re-rendering content, and instead allows the GPU to render straight from the cache. The cache(s) understand dirty regions, so a blinking cursor in a cached textblock, for example, will only need to re-render the cursor between frames. There’s even a new Brush which specifically uses these intelligent caches – effectively a VisualBrush with vastly better performance.


A bit more on that here: New WPF Features: Cached Composition[^]


Best regards
Espen Harlinn


WPF并非设计为具有大量繁琐操作的实时环境.它有其局限性,您不应该考虑像这样移动太多的对象.解决此问题的一种方法是为要移动的元素制作一个位图,然后从画布"中删除选定的元素,然后在将其放下时,只需再次添加对象即可.抱歉,但是我真的不能告诉您为什么它能正常工作,以及限制是什么,因为它们可能取决于您计算机上的硬件配置.

无论如何,祝你好运:)
WPF was not designed to be a real time enviroment with lots of heavy manipulations. It has its limitations, and you should consider not to move so many objects around like this. One way to fix the issue is to make a bitmap of the elements you are about to move, and remove the selected elements from the Canvas, and when it drops them, simply add the objects again. Sorry but I cant really tell you why it dosent work, and what the limits are, as they might depende on the hardware configuration on your computer.

Good luck in any case :)


这篇关于WPF TranslateTransform具有许多对象的性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆