Извлеките точное содержание каждой страницы XAML моего приложения - PullRequest
0 голосов
/ 31 мая 2019

У меня есть приложение формы UWP с несколькими XAML страницами, пользователь должен заполнить каждую страницу и затем сохранить то, что он заполнил.

После этого я сохраняю данные вapp LocalStorage, но я также хочу создать копию каждой страницы в пользовательскую папку, на случай, если локальное сохранение не сработало.

Я искал создание файла формата PDFс содержимым каждой XAML страницы в моем приложении, но я обнаружил, что это сложнее, чем я думал (нет встроенной поддержки генерации PDF, очень дорогие библиотеки третьей части, ...).

Я также думал о создании некоторых изображений страниц, но я действительно не знаю, возможно ли это.

Итак, что я могу использовать, чтобы сгенерировать копию страниц моего приложения и сохранить ее в LocalStorage (без взаимодействия с пользователем, конечно)?

С помощью RenderTargetBitmap я могу захватить корневую страницу, но всякий раз, когда я пытаюсь захватить другую вещь в дереве XAML, это бросает мне ArgumentException

Страница XAML:

<Page x:Name="rootPage"
    x:Class="BasePosteMobilite2.Views.InfosPosteView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:postecomponents="using:BasePosteMobilite2.Services.PosteComponents"
    xmlns:utils="using:BasePosteMobilite2.Utils"
    xmlns:converters="using:BasePosteMobilite2.Utils.Converters"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    DataContext="{Binding InfoPosteViewModel, Source={StaticResource Locator}}">

    <Grid 
        x:Name="ContentArea">
        <Pivot x:Name="Items" Margin="0,84,0,0">
            <PivotItem Header="Généralités" x:Uid="InfosPoste_Generalites">
                <Grid>
                    <ScrollViewer>
                        <Grid x:Name="gridGeneralites" Background="{ThemeResource SystemControlPageBackgroundChromeLowBrush}" Padding="0,12,0,12" Margin="0,0,0,12">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>

                            [content]

                            </Grid>
                    </ScrollViewer>

                </Grid>
            </PivotItem>

            <PivotItem x:Name="pivotHTA" Header="HTA" x:Uid="InfosPoste_HTA">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition Height="70"/>
                    </Grid.RowDefinitions>
                    <ScrollViewer x:Name="scrollHTA">
                        <ListView x:Name="listHTA" Background="{ThemeResource SystemControlPageBackgroundChromeLowBrush}"
                              ItemsSource="{x:Bind ViewModel.CurrentPoste.Hta, Mode=TwoWay}" Margin="0,0,0,12"
                              SelectionMode="None">
                            <ListView.ItemTemplate>
                                <DataTemplate x:DataType="postecomponents:HTA">
                                    <Grid x:Name="gridHTA" BorderBrush="Silver" BorderThickness="0,0,0,1" Padding="0,24,0,24">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition/>
                                            <ColumnDefinition/>
                                            <ColumnDefinition/>
                                            <ColumnDefinition/>
                                            <ColumnDefinition/>
                                            <ColumnDefinition/>
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>

                                        [content]

                                    </Grid>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>
                    </ScrollViewer>
                    <Button x:Name="bAddHTA" Grid.Row="1" HorizontalAlignment="Right" Content="Ajouter HTA" Margin="0,0,0,0" VerticalAlignment="Center" FontSize="16" Click="AddComponentClick"/>

                </Grid>
            </PivotItem>
        </Pivot>

        <TextBlock MaxLines="1" TextTrimming="CharacterEllipsis" HorizontalAlignment="Left" Margin="12,12,0,0" Text="Indice poste :" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="16"/>
        <TextBox x:Name="tbCodePoste" Margin="114,12,0,0" Text="{x:Bind ViewModel.CurrentPoste.CodePoste, Mode=TwoWay}" VerticalAlignment="Top"  FontSize="16" IsTextPredictionEnabled="False" MaxLength="6" CharacterCasing="Upper" HorizontalAlignment="Left" Width="160" KeyUp="Page_KeyUp"/>
        <Button x:Name="bRechercherPoste" Content="Rechercher" Margin="279,12,0,0" VerticalAlignment="Top" Click="BRechercherPoste_Click" FontSize="16" IsDoubleTapEnabled="False" IsHoldingEnabled="False" IsRightTapEnabled="False" Width="117" Height="34" />
        <Button x:Name="bScannerPoste" Content="Scanner code poste" Margin="401,12,0,0" VerticalAlignment="Top" FontSize="16" IsDoubleTapEnabled="False" IsHoldingEnabled="False" IsRightTapEnabled="False" Width="170" Height="34" Click="BScannerPoste_Click" />
        <Button x:Name="bRAZ" Content="Remise à zéro" Margin="576,12,0,0" VerticalAlignment="Top" FontSize="16" IsDoubleTapEnabled="False" IsHoldingEnabled="False" IsRightTapEnabled="False" Width="170" Height="34" Click="BRAZ_Click"/>
        <Grid x:Name="spWarning" Margin="752,16,208,0" VerticalAlignment="Top" Height="63" Visibility="Collapsed">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Image HorizontalAlignment="Left" VerticalAlignment="Top" Source="/Assets/warning.png" Stretch="Fill" Width="24" Height="24"></Image>
            <TextBlock x:Name="tbWarning" Text="Poste introuvable" FontSize="16" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="4,0,0,0" TextWrapping="Wrap" Grid.Column="1"/>
        </Grid>
        <Button x:Name="bEnregistrer" HorizontalAlignment="Right" VerticalAlignment="Top" Content="Enregistrer modifications" Margin="0,12,12,0" Width="191" Click="BEnregistrer_Click"/>
    </Grid>
</Page>

Класс SaveXamlToPng:

public static class SaveXamlAsPng
{
    public static async Task XAMLtoPNG(UIElement element, string filename)
    {
        try
        {
            RenderTargetBitmap rtb = new RenderTargetBitmap();
            await rtb.RenderAsync(element);

            var pixelBuffer = await rtb.GetPixelsAsync();
            var pixels = pixelBuffer.ToArray();
            var displayInformation = DisplayInformation.GetForCurrentView();
            var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename + ".png", CreationCollisionOption.GenerateUniqueName);
            using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
            {
                var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
                encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                                        BitmapAlphaMode.Premultiplied,
                                        (uint)rtb.PixelWidth,
                                        (uint)rtb.PixelHeight,
                                        displayInformation.RawDpiX,
                                        displayInformation.RawDpiY,
                                        pixels);
                await encoder.FlushAsync();
            }
        }
        catch (Exception e)
        {
            Debug.WriteLine(e.Message);
        }
    }
}

Нажатие кнопки с использованием этого метода:

private async void BEnregistrer_Click(object sender, RoutedEventArgs e)
{
    await SaveXamlAsPng.XAMLtoPNG(pivotHTA, "test");
}

Так, например, я могу получить .png от rootPage, но когда я использую pivotHTA в качестве параметра в renderAsync(), это выдает ArgumentException высказывание System.ArgumentException : 'The specified buffer index is not within the buffer capacity.'

Примечание: я не знаю, если это что-то меняет, но страница XAML находится вNavigationView

1 Ответ

0 голосов
/ 03 июня 2019

Я также думал о создании некоторых изображений страниц, но я действительно не знаю, возможно ли это.

Да. Это конечно возможно. Вы можете использовать RenderTargetBitmap Class с соответствующими методами для рендеринга XAML в растровое изображение и сохранения его в StorageFile.

Пожалуйста, проверьте мой код в теме Сохранить сетку как png .

private async void saveButton_Click(object sender, RoutedEventArgs e)
{
    RenderTargetBitmap rtb = new RenderTargetBitmap();
    await rtb.RenderAsync(pivotHTA);

    var pixelBuffer = await rtb.GetPixelsAsync();
    var pixels = pixelBuffer.ToArray();
    var displayInformation = DisplayInformation.GetForCurrentView();
    var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("testImage" + ".png", CreationCollisionOption.ReplaceExisting);
    using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
    {
        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
        encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                             BitmapAlphaMode.Premultiplied,
                             (uint)rtb.PixelWidth,
                             (uint)rtb.PixelHeight,
                             displayInformation.RawDpiX,
                             displayInformation.RawDpiY,
                             pixels);
        await encoder.FlushAsync();
    }
}
<Grid 
    x:Name="ContentArea">
    <Pivot x:Name="Items" Margin="0,84,0,0">
        <PivotItem Header="Généralités" x:Uid="InfosPoste_Generalites">
            <Grid>
            </Grid>
        </PivotItem>
        <PivotItem x:Name="pivotHTA" Header="HTA" x:Uid="InfosPoste_HTA">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition Height="70"/>
                </Grid.RowDefinitions>
                <Image Source="Assets/panda.jpg">
                </Image>
            </Grid>
        </PivotItem>
    </Pivot>
    <Button Content="render" Click="Button_Click"></Button>
</Grid>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...