提取应用程序的每个 XAML 页的确切内容



我有一个UWP表单应用程序,其中包含多个XAML页面,用户应该填写每一页,然后保存他填写的内容。

之后,我将数据保存到应用程序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");
}

因此,例如,我能够从rootPage那里获得.png但是当我在renderAsync()中使用pivotHTA作为参数时,它抛给我一个ArgumentExceptionSystem.ArgumentException : 'The specified buffer index is not within the buffer capacity.'

注意:我不知道它是否更改了任何内容,但 XAML 页面处于NavigationView

我也想过创建一些页面的图像,但我真的不知道这是否可能。

是的。这当然是可能的。可以将 RenderTargetBitmap 类与相关方法结合使用,将 XAML 呈现为位图图像,并将其保存在存储文件中。

请检查我在线程上的代码 将网格另存为 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>

最新更新