Печать потокового документа с динамическими данными в WPF

Я пытаюсь найти хороший способ распечатать потоковый документ в WPF. Я хочу, чтобы у меня была возможность увидеть, как получается документ, когда я его проектирую, поэтому создание чистого FlowDocument в виде XAML не вызывает вопросов (поскольку Visual Studio не будет показывать для него представление дизайна).

Итак, теперь я создал окно, которое содержит FlowDocument, как этот (некоторые лишние части были удалены, чтобы сделать код более подходящим):

<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>

Это немного странно, так как я никогда не буду показывать это окно пользователю, и я только обертываю FlowDocument окном, чтобы я мог видеть, как он выглядит, когда я его разрабатываю. С этим я могу жить.

Поэтому в другом месте моего приложения я хочу напечатать этот FlowDocument на принтере по умолчанию, но мне также нужно динамически установить заголовок (в дополнение ко многим другим частям документов, которые требуют динамических данных, которые здесь опущены).

Код для печати выглядит следующим образом:

  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");

Документ печатается и выглядит нормально, за исключением того, что текст заголовка по-прежнему показывает "Заголовок здесь будет", даже если я заменил его из своего кода на "Правильный текст заголовка". Я также попытался изменить это так:

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

Но результат тот же.

Таким образом, вопрос заключается в следующем: как я могу изменить содержимое FlowDocument из кода перед его печатью или есть лучший способ сделать это вместо моего подхода?

1 ответ

MVVM на помощь:

Крещение: пользовательский интерфейс - это не данные. Пользовательский интерфейс не является хранилищем данных. Пользовательский интерфейс предназначен для отображения данных, а не для их хранения.

1 - создать простой объект для хранения ваших данных

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 - Определить Binding s в вашем документе;

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

3 - Установите свой FlowDocument's DataContext к экземпляру этого класса:

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

flowdoc.DataContext = data;

//do the printing stuff.
Другие вопросы по тегам