如何在drawingContext上绘制FrameworkElement?

时间:2012-11-13 14:25:13

标签: c# .net wpf frameworkelement

我对名为_frameworkElement的FrameworkElement有所了解 我需要在FrameworkElement事件的drawingContext上绘制OnRender

像这样:

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

我需要考虑应用于_frameworkElement

的任何渲染变换

针对此问题的任何干净解决方案? 感谢

修改

为什么我需要覆盖OnRender:

由于我有一个图形应用程序,用户可以绘制形状,并使用可绘制矩形选区的选择工具选择多个形状。

我所做的是我将选定的形状从舞台画布重新显示给用户可以移动和调整大小的选择画布,在选择Canvas转换后,用户将单击舞台画布,然后我将形状重新显示到舞台画布

问题:

将孩子从Canvas移至画布,儿童时存在瓶颈。移除& Children.Add将花费时间来实现,特别是当用户选择大量形状进行转换时。

那么?

我认为不要重新选择所选形状,而是通过覆盖OnRender在选择Canvas的drawingContext上绘制它们

2 个答案:

答案 0 :(得分:0)

不,我不相信你能做到这一点,也不是真的有意义。 DrawingContext对于每个UIElement都是唯一的,并且框架会在枚举时调用适当的绘图方法(例如,每个元素都有自己的OnRender传递)。

我并没有完全遵循你的设计+问题,但也许这些会有所帮助吗?

WPF canvas performance- children.add called many times

How to draw line of ten thousands of points with WPF within 0.5 second?

如果您需要深入了解WPF如何呈现,this是一个很好的阅读。

答案 1 :(得分:0)

呼叫代码:

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方法:

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;
}