【问题标题】:Loading WPF ContentControl via Resources as Bitmap does not work通过资源加载 WPF ContentControl 作为位图不起作用
【发布时间】:2018-09-27 09:58:11
【问题描述】:

对于第三方产品,我需要将 ContentControl 转换为位图。我认为这没问题,因为 ContentControl 是一个 UIElement,可以在 Bitmap 中呈现。

但如果我绘制此位图,则看不到任何图像。

它似乎不起作用,因为我的应用程序资源中有 contentControl,如果我尝试加载它,但所有属性都为 null 或处于异常状态。这里出了什么问题?

这是我的内容控件

<ContentControl x:Key="LocationMarker" Width="356" Height="524">
<Canvas Width="356" Height="524">
  <Path Width="355.912" Height="524.355" Canvas.Left="0" Canvas.Top="-0.354675" Stretch="Fill" Fill="{DynamicResource HeaderColorBrush}" Data="...."/>
  <Path Width="150" Height="200" Canvas.Left="100" Canvas.Top="50" Stretch="Fill" Fill="{DynamicResource HeaderColorBrush}" Data="..."/>
  <Path Width="200" Height="170" Canvas.Left="78" Canvas.Top="300" Stretch="Fill" Fill="{DynamicResource HeaderColorBrush}" Data="..."/>
</Canvas>

这就是我尝试得到它的方式:

var contentControl = Application.Current.Resources.MergedDictionaries.SelectMany(x => x.MergedDictionaries).FirstOrDefault(x => x.Source.OriginalString.Contains("ContentControls.xaml"))?["LocationMarker"] as ContentControl;
  if (contentControl != null)
  {
    var renderTargetBitmap = new RenderTargetBitmap(41, 74, 96, 96, PixelFormats.Pbgra32);
    renderTargetBitmap.Render(contentControl);
    var encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
    var stream = new MemoryStream();
    encoder.Save(stream);}

contentControl 可能是错误的类型吗? Resources获取它的方式是错误的吗?

这就是它在调试器中的样子:

感谢每一个提示!

【问题讨论】:

  • 为什么不Application.Current.FindResource("LocationMarker") as ContentControl
  • 在保存到位图之前尝试实际加载 ContentControl 以便您可以看到它。看看有没有区别。此方法捕获您看到的内容(忽略那些可见性是不可见的),它不会捕获 VisualTree 中没有的内容。
  • @vasily,谢谢这样看起来好多了,但太糟糕了,它并没有改变问题
  • @kennyzx 我不知道你到底是什么意思,但我认为我从资源中加载的对象,内容控制不好,因为除了你在调试器中看到的,如果我保存位图,它的大小也为 0 kb。但我不明白他为什么从资源中加载如此奇怪的对象……这是一种线程问题吗?
  • 我的意思是,如果 UIElement 在屏幕上可见,您只能保存它。因此,您需要将控件加载到 Grid 或 Canvas... 并确保它没有被隐藏或在屏幕之外。您不能只在内存中创建控件并将其保存到 WritableBitmap。阅读 Render 方法的文档,有详细的解释。

标签: c# wpf bitmap resourcedictionary contentcontrol


【解决方案1】:

这对我有用,请注意添加到原始代码中的 MeasureArrange 调用。

var contentControl = Resources["LocationMarker"] as ContentControl;
if (contentControl != null)
{
    contentControl.Measure(new Size(356, 524));
    contentControl.Arrange(new Rect(new Size(356, 524)));
    var target = new RenderTargetBitmap(
        (int)contentControl.RenderSize.Width, (int)contentControl.RenderSize.Height,
        96, 96, PixelFormats.Pbgra32);
    target.Render(contentControl);

    var encoder = new PngBitmapEncoder();
    var outputFrame = BitmapFrame.Create(target);
    encoder.Frames.Add(outputFrame);

    using (var file = File.OpenWrite("TestImage.png"))
    {
        encoder.Save(file);
    }
}

代码取自this answer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多