繁体   English   中英

Silverlight 4 Render到WriteableBitmap返回空位图

[英]Silverlight 4 Render to WriteableBitmap returns empty bitmap

我有一些旨在将ControlTemplate呈现为writeableBitmap的代码。 创建WBMP的代码如下:

    private static void OnMarkerPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var template = e.NewValue as ControlTemplate;
        if (template != null)
        {
            var c = new Marker();
            c.Template = template;
            c.ApplyTemplate();
            c.MeasureArrange();
            c.Width = c.DesiredSize.Width;
            c.Height = c.DesiredSize.Height;

            // _cachedBitmap is of type WriteableBitmap
            _cachedBitmap = c.RenderToBitmap();
        }
    }   

定义以下扩展方法的位置:

    internal static void MeasureArrange(this UIElement element)
    {
        element.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
        element.Arrange(new Rect(new Point(0, 0), element.DesiredSize));
    }

    public static WriteableBitmap RenderToBitmap(this FrameworkElement element)
    {
        int width = (int)element.DesiredSize.Width;
        int height = (int)element.DesiredSize.Height;

#if SILVERLIGHT
        var result = new WriteableBitmap(width, height);
        result.Render(element, new TranslateTransform());
        result.Invalidate();
        return result;
#else
        // WPF Impl works just fine
        var bmp = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);

        bmp.Render(element);
        return new WriteableBitmap(bmp);
#endif         
    }

并且标记被定义为空控件

public class Marker : Control
{         
}

问题是这个。 在WPF中,一切正常,就像在首次尝试创建位图后在Silverlight中所做的一样。 但是,第一次尝试失败,返回正确大小(7 * 7或49像素)但在int[] Pixels数组中全为零的WriteableBitmap。

有些事情可能会有所帮助。 紧接在RenderToBitmap创建WriteableBitmap之前,元素的宽度/高度为7,7,所需大小为(7,7),但是ActualWidth / ActualHeight为(0,0)。 我相信在WPF中,所有的都是(7,7)。 因此,这可能是布局问题,而不是

仅供参考,Marker和ControlTemplate永远不会进入可视化树。 这是一个纯缓存的位图实现。

有任何想法吗?

啊哈! 我找到了答案。 虽然我不知道为什么。 任何可以解释它的人都将获得“答案”。

我发现此链接建议对ActualWidth / ActualHeight进行异步评估,因此,适当的BeginInvoke可以解决问题。 为什么这在WPF中起作用,但在Silverlight中不起作用?

        var c = new PointMarker();
        c.Template = pointMarkerTemplate;
        c.ApplyTemplate();

        // DispatcherUtil is just a proxy around Dispatcher.BeginInvoke
        DispatcherUtil.Instance.BeginInvoke(() =>
        {
            c.MeasureArrange();
            c.Width = c.DesiredSize.Width;
            c.Height = c.DesiredSize.Height;
            series._pointMarkerCache = c.RenderToBitmap();
            series.OnInvalidateParentSurface();
        });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM