DocumentViewer FixedDocument?
I am looking to start a small project utilising WPF, C# and following MVVM principles. The aim of the project is to learn how to utilise DocumentViewer (which is very new to me) in order to preview before sending to print.
For simplicity lets say I have a list of Names, addresses each with an associated Image. I wish to print each of these as a Business Card. Each page will have a Header (Title) and Footer (page number).
I would also like to be able to Change the scale of the Business Card so that I can change the number of Columns and rows that fit on a page.
How would I go about this? Some guidance and example code would be much appreciated.
Thank you in advance for any assistance.
Windows Presentation Foundation
C#
-
Hui Liu-MSFT 47,341 Reputation points • Microsoft Vendor
2023-03-06T09:55:01.8733333+00:00 Hi,@BigH61. Do you have any code you can share with me for analysis?
-
BigH61 581 Reputation points
2023-03-06T10:42:40.7166667+00:00 @Hui Liu-MSFT Thank you for your response. I haven't started the project as to be honest after all my research I am still unsure were to start.
-
Hui Liu-MSFT 47,341 Reputation points • Microsoft Vendor
2023-03-07T08:34:51.0066667+00:00 Hi,@BigH61. I found the method to add Header and Footer here. I tried to use a FixedDocument but got an error.
System.ArgumentException: 'Width and Height must be non-negative.'
I'm still trying to figure out what caused the problem. You could check to see if it meets your needs. If so, you can also try modifying the code to see if you can complete it.
<Window.DataContext> <local:ViewModel/> </Window.DataContext> <StackPanel> <GroupBox x:Name="PrintPreview_GroupBox"> <Grid Height="100"> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> </Grid.RowDefinitions> <TextBox Text="{Binding data1.Name}" /> <Image Source="{Binding data1.Image}" Grid.Row="1" HorizontalAlignment="Left" Height="100"/> </Grid> </GroupBox> <Button Content="load" Click="Button_Click" Height="50"/> <DocumentViewer x:Name="documentViewer1" Height="200"> </DocumentViewer> <Button Content="print" Click="Button1_Click" Height="50"/> </StackPanel>
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Button1_Click(object sender, RoutedEventArgs e) { PrintDialog pDialog = new PrintDialog(); string documentTitle = "Test Document Header"; string documentFooter = "Test Document Footer"; fd = new FixedDocument(); fd = PrintHelper.GetFixedDocument(PrintPreview_GroupBox, pDialog); SaveAsXps("testxps", this.fd, documentTitle, documentFooter); } public void SaveAsXps(string fileName, System.Windows.Documents.FixedDocument document, string DocumentTitle, string DocumentFooter) { using (Package container = Package.Open(fileName + ".xps", FileMode.Create)) { using (XpsDocument xpsDoc = new XpsDocument(container, CompressionOption.Normal)) { XpsSerializationManager rsm = new XpsSerializationManager(new XpsPackagingPolicy(xpsDoc), false); DocumentPaginator paginator = ((IDocumentPaginatorSource)document).DocumentPaginator; paginator = new DocumentPaginatorWrapper(paginator, new Size(768, 676), new Size(8,8), DocumentTitle, DocumentFooter); rsm.SaveAsXaml(paginator); } } } FixedDocument fd; private void Button_Click(object sender, RoutedEventArgs e) { string documentTitle = "Test Document Header"; string documentFooter = "Test Document Footer"; PrintDialog pDialog = new PrintDialog(); fd = new FixedDocument(); fd =PrintHelper.GetFixedDocument(PrintPreview_GroupBox, pDialog); this.documentViewer1.Document = fd; } } public class ViewModel : INotifyPropertyChanged { private ObservableCollection<Data> datas = new ObservableCollection<Data>(); public ObservableCollection<Data> Datas { get { return datas; } set { if (datas != value) { datas = value; OnPropertyChanged("Datas"); } } } public Data data1 { get; set; } public ViewModel() { data1 = new Data() { Image = "C:...\\tu.jfif", Name = "im1" }; } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string name = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } } public class Data { public string Name { get; set; } public string Image { get; set; } } public static class PrintHelper { public static FixedDocument GetFixedDocument(FrameworkElement toPrint, PrintDialog printDialog) { PrintCapabilities capabilities = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket); Size pageSize = new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight); Size visibleSize = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight); FixedDocument fixedDoc = new FixedDocument(); toPrint.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); toPrint.Arrange(new Rect(new Point(0, 0), toPrint.DesiredSize)); Size size = toPrint.DesiredSize; double yOffset = 0; while (yOffset < size.Height) { VisualBrush vb = new VisualBrush(toPrint); vb.Stretch = Stretch.None; vb.AlignmentX = AlignmentX.Left; vb.AlignmentY = AlignmentY.Top; vb.ViewboxUnits = BrushMappingMode.Absolute; vb.TileMode = TileMode.None; vb.Viewbox = new Rect(0, yOffset, visibleSize.Width, visibleSize.Height); PageContent pageContent = new PageContent(); FixedPage page = new FixedPage(); ((IAddChild)pageContent).AddChild(page); fixedDoc.Pages.Add(pageContent); page.Width = pageSize.Width; page.Height = pageSize.Height; Canvas canvas = new Canvas(); FixedPage.SetLeft(canvas, capabilities.PageImageableArea.OriginWidth); FixedPage.SetTop(canvas, capabilities.PageImageableArea.OriginHeight); canvas.Width = visibleSize.Width; canvas.Height = visibleSize.Height; canvas.Background = vb; page.Children.Add(canvas); yOffset += visibleSize.Height; } return fixedDoc; } } public class DocumentPaginatorWrapper : DocumentPaginator { Size m_PageSize; Size m_Margin; DocumentPaginator m_Paginator; Typeface m_Typeface; public DocumentPaginatorWrapper(DocumentPaginator paginator, Size pageSize, Size margin) { m_PageSize = pageSize; m_Margin = margin; m_Paginator = paginator; m_Paginator.PageSize = new Size(m_PageSize.Width - margin.Width * 2, m_PageSize.Height - margin.Height * 2); } Rect Move(Rect rect) { if (rect.IsEmpty) { return rect; } else { return new Rect(rect.Left + m_Margin.Width, rect.Top + m_Margin.Height, rect.Width, rect.Height); } } public override bool IsPageCountValid { get { return m_Paginator.IsPageCountValid; } } public override int PageCount { get { return m_Paginator.PageCount; } } protected Size pageSize; public override Size PageSize { get { return m_Paginator.PageSize; } set { if (this == m_Paginator) { this.pageSize = value; } else { m_Paginator.PageSize = value; } } } public override IDocumentPaginatorSource Source { get { return m_Paginator.Source; } } String m_DocumentTitle; String m_DocumentFooter; public DocumentPaginatorWrapper(DocumentPaginator paginator, Size pageSize, Size margin, string DocumentTitle, string DocumentFooter) { m_PageSize = pageSize; m_Margin = margin; m_Paginator = paginator; m_DocumentTitle = DocumentTitle; m_DocumentFooter = DocumentFooter; m_Paginator.PageSize = new Size(m_PageSize.Width - margin.Width * 2, m_PageSize.Height - margin.Height * 2); } public void DrawFunction(DrawingVisual content, string drawContent, Point point) { using (DrawingContext ctx = content.RenderOpen()) { if (m_Typeface == null) { m_Typeface = new Typeface("Times New Roman"); } FormattedText text = new FormattedText(drawContent, System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, m_Typeface, 14, Brushes.Black); ctx.DrawText(text, point); } } public override DocumentPage GetPage(int pageNumber) { DocumentPage page = m_Paginator.GetPage(pageNumber); // Create a wrapper visual for transformation and add extras ContainerVisual newpage = new ContainerVisual(); //Title DrawingVisual pagetitle = new DrawingVisual(); DrawFunction(pagetitle, m_DocumentTitle, new Point(m_PageSize.Width / 2 - 100, -96 / 4)); //Page Number DrawingVisual pagenumber = new DrawingVisual(); DrawFunction(pagenumber, "Page " + (pageNumber + 1), new Point(m_PageSize.Width - 200, m_PageSize.Height - 100)); //Footer DrawingVisual pagefooter = new DrawingVisual(); DrawFunction(pagefooter, m_DocumentFooter, new Point(m_PageSize.Width / 2 - 100, m_PageSize.Height - 100)); DrawingVisual background = new DrawingVisual(); using (DrawingContext ctx = background.RenderOpen()) { ctx.DrawRectangle(new SolidColorBrush(Color.FromRgb(240, 240, 240)), null, page.ContentBox); } newpage.Children.Add(background); // Scale down page and center ContainerVisual smallerPage = new ContainerVisual(); smallerPage.Children.Add(page.Visual); //smallerPage.Transform = new MatrixTransform(0.95, 0, 0, 0.95, // 0.025 * page.ContentBox.Width, 0.025 * page.ContentBox.Height); newpage.Children.Add(smallerPage); newpage.Children.Add(pagetitle); newpage.Children.Add(pagenumber); newpage.Children.Add(pagefooter); newpage.Transform = new TranslateTransform(m_Margin.Width, m_Margin.Height); return new DocumentPage(newpage, m_PageSize, Move(page.BleedBox), Move(page.ContentBox)); } }
The result:
Sign in to comment