我有一个复杂的用户控件,该控件显示图像并在其上方的某些标签上覆盖阴影和其他东西。我想在内存中渲染所有这些东西,然后制作此地图的图像,然后在真实的用户界面中使用此图像。这就是事情的结局。
之所以这样做,是因为界面开始随着所有这些元素的变化而缓慢移动,因此我试图简化它。我要走正确的路吗?
这里的问题是我创建了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;
}
如果控件在开始时是布局的一部分,则添加UpdateLayout确实可以解决问题(这就是我在那里为自己添加一个异常的原因),但是当控件是通过代码创建而从未到达页面时,UpdateLayout根本没有帮助。
如何确保在内存中呈现所有元素,然后在不进入页面的情况下呈现其图像?(可以接受固定尺寸)
在您的情况下,解决方案将如下所示:
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();
...
}
在SO中经常问到在内存中租用WPF :
由于控件没有父容器,因此您需要调用Measure and Arrange来进行正确的布局。
您需要强制渲染项目,或等待渲染项目。然后,您可以使用ActualHeight和ActualWidth属性。
为您的目的的附加:
可能您可以使用ViewBox在内存中进行渲染
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句