在内存中呈现WPF用户控件,而不是在屏幕上

jav*_*irs 6 c# wpf

我有一个复杂的用户控件,它显示一个图像并用阴影和东西覆盖它上面的某些标签.我想在内存中渲染所有这些内容,然后制作此地图的图像,然后在真实用户界面中使用此图像.这就是事情的结局.

在此输入图像描述

我这样做是因为界面开始慢慢移动所有这些元素,我正在尝试简化它.我会走正确的路吗?

这里的问题是我创建了brainMap,用数据提供它,然后尝试创建imagen和BAM!它无法完成,因为整个组件未呈现,ActualWith为零.

这就是我从控件中提取图像的方法(当控件在屏幕中呈现时,该方法非常有效)

    /// <summary>
    /// The controls need actual size, If they are not render an "UpdateLayout()" might be needed.
    /// </summary>
    /// <param name="control"></param>
    /// <param name="Container"></param>
    public static System.Windows.Controls.Image fromControlToImage(System.Windows.FrameworkElement control)
    {
        if (control.ActualWidth == 0)
            throw new Exception("The control has no size, UpdateLayout is needed");
     // Here is where I get fired if the control was not actually rendered in the screen

        RenderTargetBitmap rtb = new RenderTargetBitmap((int)control.ActualWidth, (int)control.ActualHeight, 96, 96, PixelFormats.Pbgra32);
        rtb.Render(control);

        var bitmapImage = new BitmapImage();
        var bitmapEncoder = new PngBitmapEncoder();
        bitmapEncoder.Frames.Add(BitmapFrame.Create(rtb));

        using (var stream = new System.IO.MemoryStream())
        {
            bitmapEncoder.Save(stream);
            stream.Seek(0, System.IO.SeekOrigin.Begin);

            bitmapImage.BeginInit();
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.StreamSource = stream;
            bitmapImage.EndInit();
        }
        System.Windows.Controls.Image testImage = new System.Windows.Controls.Image();
        testImage.Source = bitmapImage;
        return testImage;
    }
Run Code Online (Sandbox Code Playgroud)

如果控件是开头布局的一部分,添加UpdateLayout确实解决了问题(这就是为什么我为自己添加了一个例外),但是当从代码创建控件并且从未到达页面时,UpdateLayout根本无法帮助.

我该怎么做才能确保渲染内存中的所有元素,然后在不进入页面的情况下渲染它的图像?(固定尺寸可以选择)

Sma*_*tis 10

在您的情况下,解决方案将是这样的:

 public static System.Windows.Controls.Image fromControlToImage(System.Windows.FrameworkElement control)
 {
    Size size = new Size(100, 100); // Or what ever size you want...
    control.Measure(size);
    control.Arrange(new Rect(size));
    control.UpdateLayout();
    ...
 }
Run Code Online (Sandbox Code Playgroud)

在SO中通常会询问内存中的WPF :

绘制内存控制

由于控件没有父容器,因此需要调用Measure and Arrange以进行正确的布局.

WPF在内存中获取UIElement的大小

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

为您的目的另外一个:

强制渲染内存中的WPF控件

您可以使用ViewBox在内存中进行渲染