Визуализация Silverlight 4 в WriteableBitmap возвращает пустое растровое изображение - PullRequest
0 голосов
/ 01 марта 2012

У меня есть некоторый код, который предназначен для рендеринга 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 после первой попытки создания растрового изображения.Однако первая попытка завершается неудачно, возвращая WriteableBitmap правильного размера (7 * 7 или 49 пикселей), но со всеми нулями в массиве int[] Pixels.

Некоторые вещи, которые могут быть полезны.Непосредственно перед созданием WriteableBitmap в RenderToBitmap ширина / высота элемента составляет 7,7, требуемый размер - (7,7), а ActualWidth / ActualHeight - (0,0).В WPF я верю всем (7,7).Так что это может быть проблема макета, а не

К вашему сведению, Marker и ControlTemplate никогда не доходят до визуального дерева.Это чисто кэшированная реализация растрового изображения.

Есть идеи?

1 Ответ

0 голосов
/ 01 марта 2012

Aha!Я нашел ответ.Хотя я не знаю почему.Галочки «Ответить» достаются всем, кто может это объяснить.

Я нашел эту ссылку , которая предполагает, что 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();
        });
...