使用Adorner图层打印RichTextBox内容时出现问题

时间:2011-08-03 18:41:17

标签: c# wpf printing richtextbox

我正在尝试打印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);
        }

我面临的问题是这段代码只打印屏幕上可见的内容,而不是编辑器的全部内容。

修改 图片是装饰图层,如果我使用上述方法打印,它只打印屏幕上的可见部分而不是整个文档。

enter image description here

修改

我正在尝试单独打印每个页面,但在执行Editor.InvalidateVisual();后我无法强制Editor.PageDown();我是否有办法在我的方法中执行此操作?

4 个答案:

答案 0 :(得分:1)

当控件在装饰图层上绘制时,它们会向上搜索树,直到找到装饰图层。通常这是一个窗口级别。在某些情况下,您需要一个更接近控件的装饰层,或者直接在控件周围。在这种情况下,使用<AdornerDecorator><RichTextBox /></AdornerDecorator>

包装控件

在您的情况下,您可能希望将adorner装饰器的父元素或装饰器本身传递给打印逻辑。这样,打印逻辑将包括装饰层作为视觉的一部分。也许是这样的:

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

然后,将“EditorWrapper”传递给打印逻辑。

修改

如果您只想打印RichTextBox的内容,那么最好使用FlowDocument的内置分页功能。 FlowDocument实现了IDocumentPaginatorSource,它将返回一个可以打印文档的分页器。将该paginator传递给XpsDocumentWriter,它应该正确地转储内容。

var doc = Editor.Document;
var src = doc as IDocumentPaginatorSource;
var pag = src.DocumentPaginator;
xpsdw.Write(pag);

答案 1 :(得分:0)

我找到了这段代码here

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

答案 2 :(得分:0)

Adorner图层面向绘图。因此,剩下的一个选项是将整个RichTextBox转换为绘图并在XPS中将其打印为图像。

虽然这会带来多个问题......

  1. 它将打印由richtextbox占据或占用的外部和内部内容,即编辑器工具栏(如果它是富文本框的控件模板的一部分),内部滚动条等。
  2. 如果有滚动条,则不会打印滚动条中的内容,因为图像将是文本框的确切“快照”(其余文本由滚动条剪切)。
  3. 你会对此感到高兴吗?

答案 3 :(得分:0)

我没有找到任何可以100%解决这个问题的方法,所以我试图将我所有的装饰层转换为实际图像。一旦我获得100%可行的解决方案,我就会更新问题。