Проблема с печатью содержимого RichTextBox со слоями Adorner - PullRequest
0 голосов
/ 03 августа 2011

Я пытаюсь напечатать содержимое RichTextBox, включая слои Adorner внутри. Я использую этот код для печати

        double w = Editor.ExtentWidth;  // Editor is the RichTextBox
        double h = Editor.ExtentHeight;

        LocalPrintServer ps = new LocalPrintServer();
        PrintQueue pq = ps.DefaultPrintQueue;
        XpsDocumentWriter xpsdw = PrintQueue.CreateXpsDocumentWriter(pq);
        PrintTicket pt = pq.UserPrintTicket;
        if (xpsdw != null)
        {
            pt.PageOrientation = PageOrientation.Portrait;
            PageMediaSize pageMediaSize = new PageMediaSize(w, h);
            pt.PageMediaSize = pageMediaSize;

            xpsdw.Write(Editor);
        }

Проблема, с которой я сталкиваюсь, заключается в том, что этот код печатает только содержимое, видимое на экране, а не все содержимое редактора.

EDIT * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} * * Тогда, если я печатаю описанным выше способом, он печатает только видимую часть экрана, а не весь документ

enter image description here

Редактировать

Я пытаюсь напечатать каждую страницу отдельно, но не могу принудительно Editor.InvalidateVisual(); после выполнения Editor.PageDown(); Есть ли способ, которым я могу сделать это в моем методе?

Ответы [ 4 ]

1 голос
/ 04 августа 2011

Когда элементы управления рисуют на слое аксессуаров, они ищут в дереве, пока не найдут слой аксессуаров.Часто это уровень окна.В некоторых случаях вам нужно, чтобы слой надстройки был ближе к элементу управления или непосредственно вокруг элемента управления.В этом случае оберните элемент управления <AdornerDecorator><RichTextBox /></AdornerDecorator>

В вашем случае вы, вероятно, захотите передать родительский элемент декоратора adorner или сам декоратор в логику печати.Таким образом, логика печати будет включать слой рекламного элемента как часть визуального.Может быть что-то вроде этого:

<Grid Name="EditorWrapper">
   <AdornerDecorator>
      <RichTextBox />
   </AdornerDecorator>
</Grid>

Затем передайте «EditorWrapper» логике печати. ​​

EDIT

Если вы просто хотите напечататьсодержимое RichTextBox, тогда вам лучше всего использовать встроенные возможности нумерации страниц FlowDocument.FlowDocument реализует IDocumentPaginatorSource, который будет возвращать paginator, который может печатать документ.Передайте этот paginator в XpsDocumentWriter, и он должен правильно сбросить содержимое.

var doc = Editor.Document;
var src = doc as IDocumentPaginatorSource;
var pag = src.DocumentPaginator;
xpsdw.Write(pag);
0 голосов
/ 09 августа 2011

Я не нашел способа, который бы работал на 100% для этой проблемы, поэтому я пытаюсь преобразовать все слои рекламного объявления в реальные изображения.Я обновлю вопрос, как только получу 100% рабочее решение.

0 голосов
/ 04 августа 2011

Слои Adorner ориентированы на рисунок. Таким образом, остается один вариант - преобразовать весь RichTextBox в чертеж и распечатать его как изображение в XPS.

Хотя это создает несколько проблем ...

  1. Он будет печатать внешнее и внутреннее содержимое, занимаемое или занимаемое панелью инструментов редактора richtextbox, т. Е. Если оно является частью шаблона элемента управления текстового поля), внутренними полосами прокрутки и т. Д.
  2. Если имеются полосы прокрутки, то содержимое вне полос прокрутки не будет напечатано, поскольку изображение будет точным «снимком» текстового поля (с оставшимся текстом, обрезанным полосами прокрутки).

Будете ли вы счастливы с этим?

0 голосов
/ 03 августа 2011

Я нашел этот код здесь :

// Serialize RichTextBox content into a stream in Xaml or XamlPackage format. (Note: XamlPackage format isn't supported in partial trust.)
TextRange sourceDocument = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
MemoryStream stream = new MemoryStream();
sourceDocument.Save(stream, DataFormats.Xaml);

// Clone the source document's content into a new FlowDocument.
FlowDocument flowDocumentCopy = new FlowDocument();
TextRange copyDocumentRange = new TextRange(flowDocumentCopy.ContentStart, flowDocumentCopy.ContentEnd);
copyDocumentRange.Load(stream, DataFormats.Xaml);

// Create a XpsDocumentWriter object, open a Windows common print dialog.
// This methods returns a ref parameter that represents information about the dimensions of the printer media.
PrintDocumentImageableArea ia = null;
XpsDocumentWriter docWriter = PrintQueue.CreateXpsDocumentWriter(ref ia);

if (docWriter != null && ia != null)
{
    DocumentPaginator paginator = ((IDocumentPaginatorSource)flowDocumentCopy).DocumentPaginator;

    // Change the PageSize and PagePadding for the document to match the CanvasSize for the printer device.
    paginator.PageSize = new Size(ia.MediaSizeWidth, ia.MediaSizeHeight);
    Thickness pagePadding = flowDocumentCopy.PagePadding;
    flowDocumentCopy.PagePadding = new Thickness(
            Math.Max(ia.OriginWidth, pagePadding.Left),
            Math.Max(ia.OriginHeight, pagePadding.Top),
            Math.Max(ia.MediaSizeWidth - (ia.OriginWidth + ia.ExtentWidth), pagePadding.Right),
            Math.Max(ia.MediaSizeHeight - (ia.OriginHeight + ia.ExtentHeight), pagePadding.Bottom));
    flowDocumentCopy.ColumnWidth = double.PositiveInfinity;

    // Send DocumentPaginator to the printer.
    docWriter.Write(paginator);
}
...