Линии сетки WPF DataGrid не отображаются при сохранении в формате PDF

Я использую DataGrid для представления некоторых данных в приложении WPF. В функции, в которой я сохраняю конкретное окно WPF с DataGrid в PDF-файл с помощью PDFSharp, я сталкиваюсь с проблемой, что линии сетки DataGrid не отображаются, когда сохраненный PDF-файл просматривается с меньшим процентом просмотра. (Обращайтесь к прикрепленным изображениям, только когда для просмотра PDF установлено значение 139%, линии сетки видны. Однако при меньшем% просмотра некоторые линии сетки пропускаются.)

  1. 66.7%
  2. 75%
  3. 100%
  4. 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);

Я считаю, что это связано с качеством изображения. Затем я попробовал этот фрагмент, в котором я использую DrawImage для создания визуального элемента с более высоким разрешением. Вот фрагмент: -

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);

Этот фрагмент работает, так как линии сетки видны даже при меньшем проценте просмотра, но он заставляет мое приложение зависать при операции сохранения PDF, а также выдает исключение System.OutofMemoryException с сообщением «Недостаточно памяти для продолжения выполнения программы». Однако приложение не вылетает.

Чтобы проверить поведение программы просмотра PDF-файлов, я создал в MS Word таблицу с несколькими строками и столбцами и сохранил ее как PDF-файл. В этом случае линии сетки таблицы хорошо видны даже при небольшом проценте просмотра.

Кто-нибудь может мне с этим помочь?


person KaranKakwani    schedule 18.12.2017    source источник


Ответы (2)


Я предполагаю, что первый фрагмент кода создает таблицу в векторном формате (вы не предоставляете PDF-файл, который позволяет это проверить).

Второй фрагмент кода пытается создать растровое изображение (растровый формат).

В любом случае: как для векторных, так и для растровых изображений зависит от средства просмотра PDF, будут ли видны тонкие линии. В Adobe Reader есть множество опций (например, «Улучшить тонкие линии», «Сглаженные линии», «Сглаженные изображения»), которые будут влиять на фактическое отображение - они должны быть установлены на клиентском компьютере, ничего не должно быть установлено в PDF.

Я предполагаю, что ваш тест с MS Word также создал таблицу в векторном формате, но, возможно, с более толстыми линиями. Так что этот тест ничего не доказывает.

person I liked the old Stack Overflow    schedule 19.12.2017
comment
Я не думаю, что 1-й фрагмент создает таблицу в векторном формате, поскольку видимость GridLines зависит от процента просмотра в PDF Viewer (я проверял в Adobe Reader, а также в Foxit Reader). Как вы сказали, тест с MS Word должен был создать и сохранить его в векторном формате, потому что независимо от того, какой процент просмотра, сетка таблицы видна четко. - person KaranKakwani; 19.12.2017
comment
Я видел несколько документов в векторном формате, где не все тонкие линии видны при малых уровнях масштабирования. Обычно разницу можно заметить при уровне масштабирования 6400% или при попытке выделить текст. - person I liked the old Stack Overflow; 20.12.2017

У меня была такая же проблема с исчезновением линий сетки при уменьшении масштаба PDF-файла, созданного с помощью WPF.

Проблема заключалась в том, что объекты 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);

Но что, если вы хотите, чтобы в ячейке сетки был какой-то фон? Тогда решение состоит в том, чтобы добавить отдельный объект Border в ту же ячейку Grid и использовать 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 и ниже полностью исчезнут.

person Tomas Andersson    schedule 08.07.2020