【问题标题】:How to draw FrameworkElement on drawingContext?如何在drawingContext上绘制FrameworkElement?
【发布时间】:2012-11-13 14:25:13
【问题描述】:

我参考了一个名为 _frameworkElement 的 FrameworkElement 我需要在OnRender 事件的drawingContext 上绘制FrameworkElement

像这样:

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

我需要考虑应用于 _frameworkElement 的任何渲染转换

这个问题有什么干净的解决方案吗? 谢谢

编辑

为什么我需要重写 OnRender:

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

我所做的是将舞台画布中的选定形状重新设置为用户可以移动和调整大小的选择画布,在选择画布上进行转换后,用户将单击舞台画布,然后将形状重新设置为舞台画布的父级.

问题:

将子元素从 Canvas 移除到 Canvas 时存在瓶颈,Children.Remove & Children.Add 将花费时间来实现,特别是当用户选择大量形状进行变换时。

那么?

我认为不要重新设置选定形状的父级,而是通过覆盖 OnRender 在选择 Canvas 的绘图上下文上绘制它们

【问题讨论】:

  • 你为什么要这样做?我想不出您需要在 WPF 中覆盖 OnRender() 的情况。请提供更多详细信息,说明您正在尝试做什么。
  • 在某些情况下需要覆盖。我用它来绘制响应鼠标定位和事件的实时数据表示(如果你愿意的话,想象一下心脏 EKG)。这是一个有效的场景。但是,如果我们要帮助您实现目标,了解您需要完成的工作会很有帮助。 :)
  • 请参阅上面的编辑以解释为什么我需要覆盖 OnRender()

标签: c# .net wpf frameworkelement


【解决方案1】:

不,我不相信你能做到这一点,也没有任何意义。 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 是一本不错的读物。

【讨论】:

  • 非常感谢您的链接
【解决方案2】:

调用代码:

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

辅助方法:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多