Printing a flowdocument with dynamic data in WPF

冷暖自知 提交于 2019-12-23 03:39:21

问题


I am trying to find a good way to print a flow document in WPF. What I want is to have a possibility to see how the document turns out as I design it, so therefore creating a pure FlowDocument as a XAML is out of the questions (as Visual Studio wont show the design view for it).

So what I have done now is to create a window that contains a FlowDocument like this (some excessive parts have been removed to make the code more consise):

<Window x:Class="MyNamespace.ProjectPrintout...>
  <Grid>
    <FlowDocumentReader>
      <FlowDocument ColumnWidth="500" Name="Document">
        <!-- Header -->
        <Paragraph Name="HeaderText">
          The header will go here
        </Paragraph>
      </FlowDocument>
    </FlowDocumentReader>
  </Grid>
</Window>

This is a bit strange since I will never show this Window to the user, and I only wrap the FlowDocument with a Window so that I can see how it looks like as I develop it. This Ican live with.

So somewhere else in my application, I want to print this FlowDocument to the default printer, but I also have to set the header dynamically (in addition to many other parts of the documents that needs dynamic data that are omitted here).

The code to print looks like this:

  var printout = new ProjectPrintout();
  printout.HeaderText= new Paragraph(new Run("Proper header text"));
  var document = printout.Document;

  var pd = new PrintDialog();
  IDocumentPaginatorSource dps = document;
  pd.PrintDocument(dps.DocumentPaginator, "Document");

The document is getting printed, and looks fine except that the header text still shows "The header will go here", even if I replaced it from my code with "Proper header text". I also tried changing it like this:

(printout.HeaderText.Inlines.FirstInline as Run).Text = "Proper header text";

But the result is the same.

So the question is: How can I change the contents in the FlowDocument from code before I print it, or are there a better way to do this instead of my approach?


回答1:


MVVM to the rescue:

Epiphany: UI is not Data. UI is not a data store. UI is meant to show Data, not to store it.

1 - Create a simple object to hold your data

public class MyDocumentViewModel: INotifyPropertyChanged //Or whatever viewmodel base class
{
    private string _header;
    public string Header 
    {
        get { return _header; }
        set
        {
            _header = value;
            NotifyPropertyChange(() => Header);
         }
     }

     //Whatever other data you need
}

2 - Define Bindings in your Document;

<Paragraph>
    <Run Text="{Binding Header}"/>
</Paragraph>

3 - Set your FlowDocument's DataContext to an instance of this class:

var flowdoc = new YourFlowDocument();
var data = new MyDocumentViewModel { Header = "this is the Header" };
//whatever other data

flowdoc.DataContext = data;

//do the printing stuff.


来源:https://stackoverflow.com/questions/13759018/printing-a-flowdocument-with-dynamic-data-in-wpf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!