强制在内存中呈现WPF控件

Sch*_*rtz 26 wpf wpf-controls

我有以下代码:

void Test()
{
    currentImage.Source = GetBitmap();
    RenderTargetBitmap rtb = new RenderTargetBitmap(100, 100, 96.0, 96.0, PixelFormats.Default);
    rtb.Render(currentImage);
}
Run Code Online (Sandbox Code Playgroud)

这段代码应该渲染currentImage,这是我的xaml中的一个Image控件到RenderTargetBitmap.

它不起作用,rtb返回一个空白图像,问题是currentImage还没有渲染自己,所以这种行为是预期的,我认为......

为了解决这个问题,我编写了这段代码:

void Test()
{
    currentImage.Source = GetBitmap();

    this.Dispatcher.BeginInvoke((Action)delegate()
    {
        RenderTargetBitmap rtb = new RenderTargetBitmap(100, 100, 96.0, 96.0, PixelFormats.Default);
        rtb.Render(currentImage);
    }, System.Windows.Threading.DispatcherPriority.Render, null);

}
Run Code Online (Sandbox Code Playgroud)

基本上,我等待currentImage被渲染,然后我可以将它正确渲染到我的RenderTargetBitmap.

有没有办法让它工作而不使用这种解决方法?强制Image控件在内存中渲染可能吗?

谢谢!

小智 41

使用ViewBox在内存中呈现

Grid grid = new System.Windows.Controls.Grid() { Background = Brushes.Blue, Width = 200, Height = 200 };
Viewbox viewbox = new Viewbox();
viewbox.Child = grid; //control to render
viewbox.Measure(new System.Windows.Size(200, 200));
viewbox.Arrange(new Rect(0, 0, 200, 200));
viewbox.UpdateLayout();
RenderTargetBitmap render = new RenderTargetBitmap(200, 200, 150, 150, PixelFormats.Pbgra32);
render.Render(viewbox);
Run Code Online (Sandbox Code Playgroud)

  • 这应该是市场作为公认的答案!它完美无缺! (7认同)
  • 可以使用其他"容器"(来自Panel的任何东西)来实现相同的结果.ViewBox将缩放内容,而Panel则不会. (2认同)

Mar*_*ing 11

我认为这是一个更好的答案.
viewbox并没有像预期的那样完全发挥作用,结果证明这是一种不必要的开销.

这是答案的副本(而不仅仅是链接)


您需要强制渲染项目,或等待渲染项目.然后,您可以使用ActualHeightActualWidth属性.

强制渲染:

  MenuItem item = new MenuItem();
  item.Header = "bling";
  item.Icon = someIcon;
  //Force render
  item.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
  item.Arrange(new Rect(item.DesiredSize));
Run Code Online (Sandbox Code Playgroud)

在此示例中,MenuItem未给出明确的高度或宽度.但是,强制渲染将使其考虑提供的标题文本和图标.