0

I'm trying to render a canvas from my ViewModel. After passing the canvas to my VM I render it using this function:

private void GenerateTextures(object obj)
{
    if (!(obj is UIElement))
        return;

    UIElement control = (UIElement)obj;

    for (int i = 0; i <= _textureCount - 1; ++i)
    {
        string path = OutPath + i.ToString() + TextureFormat;
        FontText = i.ToString();

        using (FileStream fs = new FileStream(path,FileMode.Create))
        {
            control.Measure(new Size(_textureSize, _textureSize));
            //control.Measure(size);
            control.Arrange(new Rect(new Size(_textureSize, _textureSize)));
            control.UpdateLayout();

            RenderTargetBitmap bitmap = new RenderTargetBitmap(_textureSize, _textureSize, 96, 96, PixelFormats.Pbgra32);
            bitmap.Render(control);
            BitmapEncoder encoder;
            switch (TextureFormat)
            {
                case ".png":
                    encoder = new PngBitmapEncoder();
                    break;
                case ".jpg":
                    encoder = new JpegBitmapEncoder();
                    break;
                case ".gif":
                    encoder = new GifBitmapEncoder();
                    break;
                default:
                    encoder = new PngBitmapEncoder();
                    break;
            }

            encoder.Frames.Add(BitmapFrame.Create(bitmap));
            encoder.Save(fs);
        }
    }
}

This works fine and all but the arrange() function causes my canvas to move to the top left of it's parent which visually breaks my UI. If I remove the call to arrange() than my rendered bitmap is just a small corner of the cavas.

How can I render my cavas without moving it on the UI?

Andronomos
  • 146
  • 3
  • 14

1 Answers1

0

I think you should specify the location for the Canvas when arranging it. You can use this constructor of Rect:

public Rect(Point location, Size size);

So your code could be like this:

control.Arrange(new Rect(new Point(X,Y), new Size(_textureSize, _textureSize)));

In addition, you should invoke the measure and arrange code once the parent layout has changed or updated.

WPInfo
  • 1,066
  • 1
  • 8
  • 21
  • Thanks for the tip, about moving measure and arrange after updating the layout. As for my canvas, I grabbed its location using `Point controlLoc = control.PointToScreen(new Point(0, 0));` then setting the rectangles location like so: `control.Arrange(new Rect(new Point(controlLoc.X, controlLoc.Y), new Size(_textureSize, _textureSize)));` but my canvas disappears and my bitmaps come out completely transparent. Any idea what I'm doing wrong? – Andronomos Nov 28 '17 at 08:29