[英]How to draw FrameworkElement on drawingContext?
我有一個名為 _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 的drawingContext 上繪制它們
不,我不相信你能做到這一點,這也沒有任何意義。 DrawingContext
對於每個UIElement
都是唯一的,並且框架會在枚舉它們時處理調用適當的繪圖方法(例如,每個元素都有自己的 OnRender 傳遞)。
我並沒有完全遵循您的設計+問題,但也許這些會有所幫助?
如果您需要深入了解 WPF 的呈現方式,這是一本很好的讀物。
調用代碼:
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.