简体   繁体   English

如何在drawingContext上绘制FrameworkElement?

[英]How to draw FrameworkElement on drawingContext?

I have a refrence to a FrameworkElement named _frameworkElement I need to draw a FrameworkElement on a drawingContext at the OnRender event.我有一个名为 _frameworkElement 的FrameworkElement的参考,我需要在OnRender事件中在drawingContext 上绘制一个FrameworkElement

Like this:像这样:

protected override void OnRender(DrawingContext drawingContext)
{
   drawingContext. ??
   base.OnRender(drawingContext);
}

What I need is to consider any render transform applied to the _frameworkElement我需要的是考虑应用于 _frameworkElement 的任何渲染变换

Any clean solution for this problem ?这个问题有什么干净的解决方案吗? Thanks谢谢

EDIT编辑

Why would I need to override OnRender:为什么我需要覆盖 OnRender:

As I have a graphical application, user can draw shapes, and select multiple shapes using a selection tool that would draw rectangle selection area.由于我有一个图形应用程序,用户可以绘制形状,并使用可以绘制矩形选择区域的选择工具来选择多个形状。

What I do is I re-parent selected shapes from stage Canvas to a selection Canvas which user can move and resize, after transformation on selection Canvas, user will click on stage Canvas, then I re-parent shapes to the stage Canvas.我所做的是将舞台画布中的选定形状重新设置为用户可以移动和调整大小的选择画布,在选择画布上进行转换后,用户将单击舞台画布,然后我将形状重新设置为舞台画布。

The problem:问题:

There is a bottleneck when removing children from Canvas to Canvas, Children.Remove & Children.Add will cost time to implement, specially when user selects large number of shapes to transform.从 Canvas 到 Canvas 移除子元素时存在瓶颈,Children.Remove & Children.Add 需要时间来实现,特别是当用户选择大量形状进行变换时。

So ?所以 ?

I thought not to re-parent selected shapes, instead draw them on the drawingContext of the selection Canvas by overriding OnRender我想不要重新设置选定形状的父级,而是通过覆盖 OnRender 在选择 Canvas 的drawingContext 上绘制它们

No I don't believe you can do that nor does it really make sense.不,我不相信你能做到这一点,这也没有任何意义。 The DrawingContext is unique to each UIElement and the framework handles calling the appropriate drawing methods as they're being enumerated (eg each element has it's own OnRender pass). DrawingContext对于每个UIElement都是唯一的,并且框架会在枚举它们时处理调用适当的绘图方法(例如,每个元素都有自己的 OnRender 传递)。

I'm not entirely following your design + problem, but maybe these will help?我并没有完全遵循您的设计+问题,但也许这些会有所帮助?

WPF canvas performance- children.add called many times WPF 画布性能- children.add 调用多次

How to draw line of ten thousands of points with WPF within 0.5 second? 如何在 0.5 秒内用 WPF 绘制一万个点的线?

If you need to deep-dive into how WPF renders,this is a good read.如果您需要深入了解 WPF 的呈现方式,是一本很好的读物。

Calling Code:调用代码:

private FrameworkElement _frameworkElement = null;

protected override void OnRender(DrawingContext dc)
{
    var rect = new Rect(new Point(0, 0), new Size(Width, Height));

    dc.DrawImage(UtilityWPF.RenderControl(_frameworkElement, Width.ToInt_Round(), Height.ToInt_Round(), false), rect);
}

Helper Method:辅助方法:

public const double DPI = 96;

/// <summary>
/// This tells a visual to render itself to a wpf bitmap
/// </summary>
/// <remarks>
/// This fixes an issue where the rendered image is blank:
/// http://blogs.msdn.com/b/jaimer/archive/2009/07/03/rendertargetbitmap-tips.aspx
/// </remarks>
public static BitmapSource RenderControl(FrameworkElement visual, int width, int height, bool isInVisualTree)
{
    if (!isInVisualTree)
    {
        // If the visual isn't part of the visual tree, then it needs to be forced to finish its layout
        visual.Width = width;
        visual.Height = height;
        visual.Measure(new Size(width, height));        //  I thought these two statements would be expensive, but profiling shows it's mostly all on Render
        visual.Arrange(new Rect(0, 0, width, height));
    }

    RenderTargetBitmap retVal = new RenderTargetBitmap(width, height, DPI, DPI, PixelFormats.Pbgra32);

    DrawingVisual dv = new DrawingVisual();
    using (DrawingContext ctx = dv.RenderOpen())
    {
        VisualBrush vb = new VisualBrush(visual);
        ctx.DrawRectangle(vb, null, new Rect(new Point(0, 0), new Point(width, height)));
    }

    retVal.Render(dv);      //  profiling shows this is the biggest hit

    return retVal;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM