【问题标题】:WPF DataGrid GridLines not visible when saved as PDFWPF DataGrid GridLines 保存为 PDF 时不可见
【发布时间】:2017-12-18 15:51:26
【问题描述】:

我正在使用 DataGrid 来表示 WPF 应用程序中的一些数据。在我使用 PDFSharp 将具有 DataGrid 的特定 WPF 窗口保存到 PDF 的功能中,我面临一个问题,即当以较小的查看百分比查看保存的 PDF 时,DataGrid GridLines 不可见。 (参考附图,只有当PDF视图设置为139%时,网格线才可见。但是,在较小的查看%中,一些网格线会被忽略。)

这是 PDF 保存代码:-

MemoryStream lMemoryStream = new MemoryStream();
Package package = Package.Open(lMemoryStream, FileMode.Create);
var doc = new System.Windows.Xps.Packaging.XpsDocument(package);
XpsDocumentWriter writer = System.Windows.Xps.Packaging.XpsDocument.CreateXpsDocumentWriter(doc);

VisualBrush sourceBrush = new VisualBrush(this);
DrawingVisual drawingVisual = new DrawingVisual();

using (var drawingContext = drawingVisual.RenderOpen())
{
    drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(this.ActualWidth, this.ActualHeight)));
}

writer.Write(drawingVisual);
doc.Close();
package.Close();

var pdfXpsDoc = PdfSharp.Xps.XpsModel.XpsDocument.Open(lMemoryStream);
XpsConverter.Convert(pdfXpsDoc, sFileName, 0);

我认为这与绘制视觉效果的质量有关。然后我尝试了这个 sn-p,我使用 DrawImage 以更高分辨率制作视觉效果。这是sn-p:-

MemoryStream lMemoryStream = new MemoryStream();
Package package = Package.Open(lMemoryStream, FileMode.Create);
var doc = new System.Windows.Xps.Packaging.XpsDocument(package);
XpsDocumentWriter writer = System.Windows.Xps.Packaging.XpsDocument.CreateXpsDocumentWriter(doc);

double dpiScale = 600.0 / 96.0;
var renderBitmap = new RenderTargetBitmap(Convert.ToInt32(this.Width * dpiScale),
                       Convert.ToInt32(this.Height * dpiScale),
                       600.0,
                       600.0,
                       PixelFormats.Pbgra32);
renderBitmap.Render(this);
var visual = new DrawingVisual();
using (var dc = visual.RenderOpen())
{
    dc.DrawImage(renderBitmap, new Rect(0, 0, this.Width, this.Height));
}                

writer.Write(visual);
doc.Close();
package.Close();

var pdfXpsDoc = PdfSharp.Xps.XpsModel.XpsDocument.Open(lMemoryStream);
XpsConverter.Convert(pdfXpsDoc, _pdfFileName, 0);

这个 sn-p 正在工作,因为网格线即使在较小的查看百分比下也可见,但它使我的应用程序卡在 PDF 保存操作中,并且它抛出 System.OutofMemoryException 并显示消息“内存不足,无法继续执行程序。”但是,应用程序不会崩溃。

为了检查 PDF 查看器的行为,我在 MS Word 中生成了一个包含多行和多列的表格,并将其保存为 PDF。在这种情况下,即使在较小的查看百分比下,表格网格线也清晰可见。

谁能帮我解决这个问题?

【问题讨论】:

    标签: wpf datagrid resolution pdfsharp gridlines


    【解决方案1】:

    我假设第一个代码 sn-p 创建了一个矢量格式的表格(您不提供允许验证这一点的 PDF)。

    第二个代码 sn-p 尝试创建位图图像(光栅格式)。

    无论哪种方式:无论是矢量图像还是光栅图像,细线是否可见都取决于 PDF 查看器。 Adobe Reader 有许多选项(如“增强细线”、“平滑线条艺术”、“平滑图像”)会对实际显示产生影响 - 在客户端计算机上设置,在 PDF 中无需设置。

    我假设您使用 MS Word 进行的测试也创建了一个矢量格式的表格,但可能线条更粗。所以这个测试证明不了。

    【讨论】:

    • 我认为第一个 sn-p 不会创建矢量格式的表格,因为 GridLines 的可见性取决于 PDF 查看器中的查看百分比(我检查了 Adob​​e Reader 和 Foxit Reader)。正如你所说的,用MS Word做的测试肯定是用矢量格式创建并保存的,因为无论查看百分比是多少,表格网格都是清晰可见的。
    • 我看过几个矢量格式的文档,在低缩放级别下,并非所有细线都可见。通常,您可以在 6400% 的缩放级别或尝试选择文本时分辨出差异。
    【解决方案2】:

    在缩小使用 WPF 创建的 PDF 时,我遇到了网格线消失的问题。

    问题在于 Grid 单元格中的 TextBox 对象具有默认的背景颜色(白色)和边框颜色(黑色),并且在缩小时两者都绘制在相同的位置。解决方案是完全没有背景,将背景设置为透明。

    TextBox tx = new TextBox();
    tx.Text = "X";
    tx.SetValue(Grid.RowProperty, row);
    tx.SetValue(Grid.ColumnProperty, col);
    tx.BorderThickness = new Thickness(0.3, 0.3, 0, 0);
    tx.BorderBrush = System.Windows.Media.Brushes.Black;
    tx.Background = Brushes.Transparent;
    grid.Children.Add(tx);
    

    但是,如果您想在网格单元格中添加一些背景怎么办?那么解决方法就是在同一个Grid单元格中添加一个单独的Border对象,并使用Zindex确保Border对象绘制在其他内容的前面。

    TextBox tx = new TextBox();
    tx.Text = "X";
    tx.SetValue(Grid.RowProperty, row);
    tx.SetValue(Grid.ColumnProperty, col);
    tx.BorderThickness = new Thickness(0);
    tx.Background = Brushes.LightPink;
    grid.Children.Add(tx);
    
    Border ct = new Border();
    ct.SetValue(Grid.RowProperty, row);
    ct.SetValue(Grid.ColumnProperty, col);
    ct.BorderThickness = new Thickness(0.3, 0.3, 0, 0);
    ct.BorderBrush = System.Windows.Media.Brushes.Black;
    ct.Background = Brushes.Transparent;
    ct.HorizontalAlignment = HorizontalAlignment.Stretch;
    ct.VerticalAlignment = VerticalAlignment.Stretch;
    Grid.SetZIndex(ct, 100);
    grid.Children.Add(ct);
    
    

    此外,UseLayoutRounding 必须设置为 false(默认为 false)。否则厚度为 0.5 或更低的线条将完全消失。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-07
      • 2014-10-30
      • 1970-01-01
      • 1970-01-01
      • 2019-09-01
      相关资源
      最近更新 更多