WPF – FlowDocument的自动行号?

我刚开始我当前项目的合同生成例程,其中一个要求是合同中的每一行都必须编号。 该数字应位于左边距,并使用垂直规则将编号与文档内容的其余部分分开。

我很确定我可以用FixedDocument解决这个问题,但它不会很有趣。 反正我是否可以使用FlowDocument来做到这一点?

您可以使用我的WpfPrint助手类轻松地使用FixedDocument完成此操作,如下所示。 要将它用于XPS创建,只需使用XPS的构造函数:

WpfPrint printer = new WpfPrint(new Size(1024, 768)); printer.CurrentElementMargin = new Thickness(2, 2, 2, 2); printer.CurrentFontFamily = new FontFamily("Arial"); printer.CurrentFontSize = BaseFontSize; printer.MarginX = 24; printer.MarginY = 24; 

你现在可以循环并添加你想要的任何东西; TextBlocks很可能是你想要的:

 printer.AddTextBlock("Basics", printer.PageSizeUsed.Width, 0, WpfPrint.ElementFlags.NewLine | WpfPrint.ElementFlags.BottomCheck2); 

如果你把它们包起来,它们会自行包裹; 每个项目在添加时都会被测量。 如果它不适合页面,则助手类会添加一个新页面并将其传递到新页面,以便从FlowDocument中获得所需的内容。 您可以随时更改CurX和CurY以在放置项目时跳过水平或垂直空间。 完成后,您可以打印到这样的打印机:

 // Print final document XpsDocumentWriter xpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(dlg.PrintQueue); xpsDocumentWriter.Write(printer.CurrentFixedDocument); 

或者您可以保存为XPS文件:

 using (XpsDocument doc = new XpsDocument(filename, FileAccess.Write)) { XpsDocumentWriter xpsDocumentWriter = XpsDocument.CreateXpsDocumentWriter(doc); xpsDocumentWriter.Write(printer.CurrentFixedDocument); } 

这是助手类。 请享用! 你再也不想使用FlowDocument了:-)

 //**************************************************************************************** // WpfPrint // // Various helpers for printing WPF UI to a printer //**************************************************************************************** using System; using System.Collections.Generic; using System.Text; using System.Windows.Documents; using System.Windows.Markup; using System.Windows.Controls; using System.Windows.Xps; using System.Windows; using System.Printing; using System.Windows.Media; namespace csheet { ///  /// Various helpers for printing WPF UI to a printer ///  public class WpfPrint { #region Supporting Types //**************************************************************************************** // Suporting Types //**************************************************************************************** ///  /// Element flags define the way the elements print; OR them for multiple effects ///  [Flags] public enum ElementFlags { /// No special flags None = 0, /// Move to the next line after output NewLine = 1, /// if there isn't 2x room, then do new page first BottomCheck2 = 2, /// Center the item horizontally HorzCenter = 4, /// Right align the item (center overrides) HorzRight = 8 } #endregion Supporting Types #region Data //**************************************************************************************** // Data //**************************************************************************************** FixedDocument _fixedDocument; FixedPage _curFixedPage; Canvas _curCanvas; double _marginX; double _marginY; Size _infiniteSize = new Size(double.PositiveInfinity, double.PositiveInfinity); #endregion Data #region Properties //**************************************************************************************** // Properties //**************************************************************************************** /// Current font family used for known objects public FontFamily CurrentFontFamily { get; set; } /// Current font size used for known objects public double CurrentFontSize { get; set; } /// Current font weight used for known objects public FontWeight CurrentFontWeight { get; set; } /// Current font style used for known objects public FontStyle CurrentFontStyle { get; set; } /// Current margin for known objects public Thickness CurrentElementMargin { get; set; } /// Current background for known objects public Brush CurrentElementBackground { get; set; } /// Current foreground for known objects public Brush CurrentElementForeground { get; set; } /// Gets the current fixed document being worked on public FixedDocument CurrentFixedDocument { get { return _fixedDocument; } } /// The current horizontal position public double CurX { get; set; } /// The current vertical position public double CurY { get; set; } /// The starting and ending X margins on the page public double MarginX { get { return _marginX; } set { if (value < 0) value = 0; _marginX = value; if (CurX < _marginX) CurX = _marginX; } } /// The starting and ending Y margins on the page public double MarginY { get { return _marginY; } set { if (value < 0) value = 0; _marginY = value; if (CurY < _marginY) CurY = _marginY; } } /// Gets the page size for the document minus the margins public Size PageSizeUsed { get { Size sz = CurrentFixedDocument.DocumentPaginator.PageSize; sz.Width -= 2 * _marginX; sz.Height -= 2 * _marginY; return sz; } } #endregion Properties #region Construction //**************************************************************************************** // Construction //**************************************************************************************** ///  /// Constructor for printing ///  ///  ///  public WpfPrint(PrintQueue printQueue, PrintTicket printTicket) { PrintCapabilities capabilities = printQueue.GetPrintCapabilities(printTicket); Size sz = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight); _fixedDocument = new FixedDocument(); _fixedDocument.DocumentPaginator.PageSize = sz; StartPage(); } ///  /// Constructor for XPS creation ///  ///  public WpfPrint(Size sz) { _fixedDocument = new FixedDocument(); _fixedDocument.DocumentPaginator.PageSize = sz; StartPage(); } #endregion Construction #region Interfaces //**************************************************************************************** // Interfaces //**************************************************************************************** ///  /// Add a new page to the document (start a new page) ///  public void StartPage() { // Create a new page content and fixed page PageContent content = new PageContent(); _fixedDocument.Pages.Add(content); _curFixedPage = new FixedPage(); ((IAddChild)content).AddChild(_curFixedPage); // Create a new drawing canvas for the page _curCanvas = new Canvas(); _curCanvas.Width = _fixedDocument.DocumentPaginator.PageSize.Width; _curCanvas.Height = _fixedDocument.DocumentPaginator.PageSize.Height; _curFixedPage.Children.Add(_curCanvas); // Reset the current position CurX = MarginX; CurY = MarginY; } ///  /// Adds a new element at the current position, and updates the current position ///  /// New element to add /// Print options public void AddUIElement(UIElement element, ElementFlags flags) { element.Measure(_infiniteSize); if (CurX > _fixedDocument.DocumentPaginator.PageSize.Width - MarginX) { CurY += element.DesiredSize.Height; CurX = MarginX; } double extraCheck = 0; if ((flags & ElementFlags.BottomCheck2) == ElementFlags.BottomCheck2) extraCheck = element.DesiredSize.Height; if (CurY > _fixedDocument.DocumentPaginator.PageSize.Height - MarginY - extraCheck) StartPage(); _curCanvas.Children.Add(element); element.SetValue(Canvas.LeftProperty, CurX); element.SetValue(Canvas.TopProperty, CurY); CurX += element.DesiredSize.Width; if ((flags & ElementFlags.NewLine) == ElementFlags.NewLine) { CurX = MarginX; CurY += element.DesiredSize.Height; } } ///  /// Add a current style TextBlock element at the current position ///  /// Text to add /// Width of element /// Height of element /// Print options public void AddTextBlock(string text, double width, double height, ElementFlags flags) { TextBlock tb = new TextBlock(); tb.Text = text; tb.FontFamily = CurrentFontFamily; tb.FontSize = CurrentFontSize; tb.FontWeight = CurrentFontWeight; tb.FontStyle = CurrentFontStyle; tb.VerticalAlignment = VerticalAlignment.Center; if ((flags & ElementFlags.HorzCenter) == ElementFlags.HorzCenter) tb.HorizontalAlignment = HorizontalAlignment.Center; else if ((flags & ElementFlags.HorzRight) == ElementFlags.HorzRight) tb.HorizontalAlignment = HorizontalAlignment.Right; tb.Margin = CurrentElementMargin; if (CurrentElementForeground != null) tb.Foreground = CurrentElementForeground; if (CurrentElementBackground != null) tb.Background = CurrentElementBackground; Grid grid = new Grid(); if (CurrentElementBackground != null) grid.Background = CurrentElementBackground; if (width != 0) grid.Width = width; if (height != 0) grid.Height = height; grid.Children.Add(tb); AddUIElement(grid, flags); } ///  /// Adds a current style TextBox element at the current position ///  /// Text to add /// Width of element /// Height of element /// Print options public void AddTextBox(string text, double width, double height, ElementFlags flags) { TextBox tb = new TextBox(); tb.Text = text; tb.FontFamily = CurrentFontFamily; tb.FontSize = CurrentFontSize; tb.FontWeight = CurrentFontWeight; tb.FontStyle = CurrentFontStyle; tb.VerticalAlignment = VerticalAlignment.Center; tb.VerticalContentAlignment = VerticalAlignment.Center; if ((flags & ElementFlags.HorzCenter) == ElementFlags.HorzCenter) tb.HorizontalContentAlignment = HorizontalAlignment.Center; else if ((flags & ElementFlags.HorzRight) == ElementFlags.HorzRight) tb.HorizontalContentAlignment = HorizontalAlignment.Right; tb.Margin = CurrentElementMargin; if (CurrentElementBackground != null) tb.Background = CurrentElementBackground; if (CurrentElementForeground != null) tb.Foreground = CurrentElementForeground; Grid grid = new Grid(); if (CurrentElementBackground != null) grid.Background = CurrentElementBackground; if (width != 0) grid.Width = width; if (height != 0) grid.Height = height; grid.Children.Add(tb); AddUIElement(grid, flags); } ///  /// Add a current style CheckBox element at the current position ///  /// Checkbox value to add /// Width of element /// Height of element /// Print options public void AddCheckBox(bool value, double width, double height, ElementFlags flags) { CheckBox cb = new CheckBox(); cb.IsChecked = value; cb.VerticalAlignment = VerticalAlignment.Center; if ((flags & ElementFlags.HorzCenter) == ElementFlags.HorzCenter) cb.HorizontalAlignment = HorizontalAlignment.Center; else if ((flags & ElementFlags.HorzRight) == ElementFlags.HorzRight) cb.HorizontalAlignment = HorizontalAlignment.Right; if (CurrentElementForeground != null) cb.Foreground = CurrentElementForeground; if (CurrentElementBackground != null) cb.Background = CurrentElementBackground; Grid grid = new Grid(); if (CurrentElementBackground != null) grid.Background = CurrentElementBackground; if (width != 0) grid.Width = width; if (height != 0) grid.Height = height; grid.Children.Add(cb); AddUIElement(grid, flags); } #endregion Interfaces } }