У меня есть приложение формы 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