locked
RenderTargetBitmap.RenderAsync() & Popup : Value does not fall within the expected range

    Question

  • Hi, I am using RenderTargetBitmap to capture a snapshot of a Page following the instruction of a msdn sample. My problem is: if I put the page on a Popup Control, then RenderTargetBitmap.RenderAsync() would throw ArgumentException(Additional information: "Value does not fall within the expected range"), but if I just Navigate to the page using Frame.Navigate() method, everything would be fine. What's wrong with Popup Control? Below is the code:

    BlankPage1.xaml

    <Page x:Class="Test.BlankPage1"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:local="using:Test"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
    
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
              Width="600"
              Height="600">
            <Button Content="save image"
                    Click="Button_Click"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center" />
        </Grid>
    </Page>

    BlankPage1.xaml.cs

    namespace Test { public sealed partial class BlankPage1 : Page { public BlankPage1() { this.InitializeComponent(); } public async Task CaptureElementToBitmapAsync(FrameworkElement element, string suggestedFileName) { RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(); await renderTargetBitmap.RenderAsync(element); //throw ArgumentException

    IBuffer pixelBuffer = await renderTargetBitmap.GetPixelsAsync(); FileSavePicker savePicker = new FileSavePicker(); savePicker.SuggestedFileName = suggestedFileName; savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary; savePicker.DefaultFileExtension = ".png"; savePicker.FileTypeChoices.Add("png Image", new string[] { ".png" }); StorageFile file = await savePicker.PickSaveFileAsync(); if (file == null) { return; } using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.ReadWrite)) { var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream); encoder.SetPixelData( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, DisplayInformation.GetForCurrentView().LogicalDpi, DisplayInformation.GetForCurrentView().LogicalDpi, pixelBuffer.ToArray()); await encoder.FlushAsync(); } } private async void Button_Click(object sender, RoutedEventArgs e) { await CaptureElementToBitmapAsync(this, "test"); } } }


    Main.xaml.cs

    namespace Test { public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) {

    //method 1: not work BlankPage1 page = new BlankPage1(); Popup popup = new Popup(); popup.Child = page; popup.IsLightDismissEnabled = true; popup.IsOpen = true; //method 2: this would work //this.Frame.Navigate(typeof(BlankPage1)); } } }



    Sunday, February 15, 2015 7:49 AM

Answers

  • This is expected and documented behaviour. See the XAML visuals and RenderTargetBitmap section in the RenderTargetBitmap documentation.

    • Marked as answer by silverbird2015 Friday, February 20, 2015 4:36 PM
    Sunday, February 15, 2015 8:30 AM
    Owner

All replies

  • This is expected and documented behaviour. See the XAML visuals and RenderTargetBitmap section in the RenderTargetBitmap documentation.

    • Marked as answer by silverbird2015 Friday, February 20, 2015 4:36 PM
    Sunday, February 15, 2015 8:30 AM
    Owner
  • This is expected and documented behaviour. See the XAML visuals and RenderTargetBitmap section in the RenderTargetBitmap documentation.

    Thanks! The documentation says:"Content that's not directly connected to the XAML visual tree and the content of the main window won't be captured. This includes Popup content, which is considered to be like a sub-window."

    Is there any way to bypass this limitation? I've to put that Page on a Popup Control.

    Sunday, February 15, 2015 8:40 AM
  • There's no way to render from the popup. You'll have to duplicate the contents to the main page to capture them.
    Monday, February 16, 2015 9:33 PM
    Owner
  • There's no way to render from the popup. You'll have to duplicate the contents to the main page to capture them.
    And the question is: is it possible to duplicate the Popup contents to the main page pragmatically?
    Tuesday, February 17, 2015 3:48 AM
  • That depends on the contents. If you're using databinding it's probably pretty easy. If you're programmatically setting the data on the popup it may be onerous.
    Tuesday, February 17, 2015 4:11 AM
    Owner
  • That depends on the contents. If you're using databinding it's probably pretty easy. If you're programmatically setting the data on the popup it may be onerous.

    I set the content of Popup mannually like this:

    BlankPage1 page = new BlankPage1();
                Popup popup = new Popup();
                popup.Child = page;

    Is there anything I can do to 'duplicate' the page to the main page pragmatically?

     
    Tuesday, February 17, 2015 4:29 AM
  • Create a BlankPage1 control and parent it to a control on the main page.
    Tuesday, February 17, 2015 5:37 PM
    Owner