【问题标题】:How to print entire ScrollViewer to a PDF file in WPF如何在 WPF 中将整个 ScrollViewer 打印到 PDF 文件
【发布时间】:2019-11-13 12:41:26
【问题描述】:

我有一个功能可以将我的布局打印到 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 属性更改为足够大的值,等待新的布局/渲染通道,然后再打印到 PDF?
  • 这似乎是个好主意。
  • 您能否使您的示例 XAML 完全正常运行?删除所有无用的标记、添加结束标记、使用示例数据填充它等。我们希望能够复制粘贴您的代码并立即了解您的问题。
  • 我编辑了一个文本框。它自然会被切断。
  • 您的 XAML 中似乎有 很多 的 Margin、Width、Height... 硬编码值,这使您的窗口绝对没有反应灵敏。我认为您的第一步是删除主要的Canvas,并开始使用更合适的布局面板,如Grid。之后调整大小会容易得多。

标签: c# wpf pdfsharp


【解决方案1】:

您可以临时增加您的MainWindow.Height(或Width,取决于您的ScrollViewer 方向)以容纳整个ScrollViewer 内容,等待新的布局/渲染通道,然后才将其打印为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();
    }
}

【讨论】:

  • 实际上我忘了说的是 ScrollViewer 在 Combobox 中,而 Combobox 在我的 MainCanvas 中。所以我尝试更改 Combobox.Height 和 MainCanvas.Height 而不是 PrintToPdf 但它不起作用。我可以看到高度是如何变化的,但在输出中只有组框被扩展但被画布切断。
  • 你也应该增加画布高度,或者暂时将Canvas.ClipToBounds设置为false。
  • 我这样做了,但它仍然不起作用。主窗口窗口 = 这个;窗口.高度 = 2000; MainCanvas.Height = 1540; GroupBox.Height = 1380;
  • 请编辑您的问题以提供最小的 XAML 示例,以便我可以针对您的具体情况进行尝试!
  • 解决我的问题的方法是将窗口的 min.height 设置为新高度,否则即使 min.height 为 0,它也不会更改。
猜你喜欢
  • 1970-01-01
  • 2016-04-27
  • 1970-01-01
  • 2011-12-23
  • 1970-01-01
  • 2013-07-01
  • 1970-01-01
  • 2021-01-08
  • 1970-01-01
相关资源
最近更新 更多