如何在 WPF 中将整个 ScrollViewer 打印到 PDF 文件
How to print entire ScrollViewer to a PDF file in WPF
我有一个功能可以将我的布局打印到 PDF 文件(使用 PDFSharp
库)。
我的问题是我的 Grid
包含一个 ScrollViewer
。
问题是 ScrollViewer
显然不能在 PDF 文件中滚动。
有什么办法可以改变吗?
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = "NHF Tool";
dlg.DefaultExt = ".pdf";
dlg.Filter = "PDF (.pdf)|*.pdf";
Nullable<bool> result = dlg.ShowDialog();
try
{
if (result == true)
{
MemoryStream lMemoryStream = new MemoryStream();
Package package = Package.Open(lMemoryStream, FileMode.Create);
XpsDocument doc = new XpsDocument(package);
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
writer.Write(MainCanvas);
doc.Close();
package.Close();
var pdfXpsDoc = PdfSharp.Xps.XpsModel.XpsDocument.Open(lMemoryStream);
PdfSharp.Xps.XpsConverter.Convert(pdfXpsDoc, dlg.FileName, 0);
}
}
catch (System.IO.IOException)
{
MessageBox.Show("TEMP");
}
<Window x:Class="NHF_Tool.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:NHF_Tool"
Title="Test" Height="800" Width="1525">
<Grid Background="Gainsboro">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" Header="Test1" Margin="10">
<Grid>
<Button Content="Sample content" Margin="20"/>
</Grid>
</GroupBox>
<GroupBox Grid.Row="1" Header="Test2" Margin="10">
<ScrollViewer x:Name="ScrollViewer">
<StackPanel Orientation="Vertical">
<Rectangle Fill="LightYellow" Height="300" Margin="20"/>
<TextBox HorizontalAlignment="Center" Grid.Row="1" Text="TextBox"/>
</StackPanel>
</ScrollViewer>
</GroupBox>
</Grid>
</Window>
您可以暂时增加 MainWindow.Height
(或 Width
,取决于您的 ScrollViewer
方向)以容纳整个 ScrollViewer
内容,等待新的 layout/render 通过,然后才打印成 PDF。
MainWindow window = this;
double oldHeight = window.Height; // saving regular Height for rollback
window.Height = 5000; // large enough temporary increase
window.SynchronouslyRedraw();
PrintToPdf(); // the method you already have
window.Height = oldHeight; // undo temporary increase
我喜欢用这个扩展方法进行同步重绘操作:
public static class UIElementExtensions {
/// <summary>
/// Synchronously redraws this <see cref="UIElement"/>. Only works if in a <see cref="Window"/> visual tree.
/// </summary>
public static void SynchronouslyRedraw(this UIElement uiElement) {
uiElement.InvalidateVisual();
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => { })).Wait();
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() => { })).Wait();
}
}
我有一个功能可以将我的布局打印到 PDF 文件(使用 PDFSharp
库)。
我的问题是我的 Grid
包含一个 ScrollViewer
。
问题是 ScrollViewer
显然不能在 PDF 文件中滚动。
有什么办法可以改变吗?
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = "NHF Tool";
dlg.DefaultExt = ".pdf";
dlg.Filter = "PDF (.pdf)|*.pdf";
Nullable<bool> result = dlg.ShowDialog();
try
{
if (result == true)
{
MemoryStream lMemoryStream = new MemoryStream();
Package package = Package.Open(lMemoryStream, FileMode.Create);
XpsDocument doc = new XpsDocument(package);
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
writer.Write(MainCanvas);
doc.Close();
package.Close();
var pdfXpsDoc = PdfSharp.Xps.XpsModel.XpsDocument.Open(lMemoryStream);
PdfSharp.Xps.XpsConverter.Convert(pdfXpsDoc, dlg.FileName, 0);
}
}
catch (System.IO.IOException)
{
MessageBox.Show("TEMP");
}
<Window x:Class="NHF_Tool.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:NHF_Tool"
Title="Test" Height="800" Width="1525">
<Grid Background="Gainsboro">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" Header="Test1" Margin="10">
<Grid>
<Button Content="Sample content" Margin="20"/>
</Grid>
</GroupBox>
<GroupBox Grid.Row="1" Header="Test2" Margin="10">
<ScrollViewer x:Name="ScrollViewer">
<StackPanel Orientation="Vertical">
<Rectangle Fill="LightYellow" Height="300" Margin="20"/>
<TextBox HorizontalAlignment="Center" Grid.Row="1" Text="TextBox"/>
</StackPanel>
</ScrollViewer>
</GroupBox>
</Grid>
</Window>
您可以暂时增加 MainWindow.Height
(或 Width
,取决于您的 ScrollViewer
方向)以容纳整个 ScrollViewer
内容,等待新的 layout/render 通过,然后才打印成 PDF。
MainWindow window = this;
double oldHeight = window.Height; // saving regular Height for rollback
window.Height = 5000; // large enough temporary increase
window.SynchronouslyRedraw();
PrintToPdf(); // the method you already have
window.Height = oldHeight; // undo temporary increase
我喜欢用这个扩展方法进行同步重绘操作:
public static class UIElementExtensions {
/// <summary>
/// Synchronously redraws this <see cref="UIElement"/>. Only works if in a <see cref="Window"/> visual tree.
/// </summary>
public static void SynchronouslyRedraw(this UIElement uiElement) {
uiElement.InvalidateVisual();
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => { })).Wait();
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() => { })).Wait();
}
}