在 WPF 中使用动态数据打印流单据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13759018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Printing a flowdocument with dynamic data in WPF
提问by ?yvind Br?then
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).
我试图找到一种在 WPF 中打印流文档的好方法。我想要的是有可能看到文档在我设计时的结果,因此将纯 FlowDocument 创建为 XAML 是不可能的(因为 Visual Studio 不会显示它的设计视图)。
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):
所以我现在所做的是创建一个包含这样的 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>
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.
这有点奇怪,因为我永远不会向用户显示这个 Window,而且我只用一个 Window 包装 FlowDocument,这样我就可以在开发它时看到它的样子。这个我可以住。
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).
所以在我的应用程序的其他地方,我想将此 FlowDocument 打印到默认打印机,但我还必须动态设置标题(除了这里省略的许多其他需要动态数据的文档部分)。
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?
所以问题是:如何在打印 FlowDocument 之前更改代码中的内容,或者是否有更好的方法来代替我的方法?
回答by Federico Berasategui
MVVMto the rescue:
MVVM来拯救:
Epiphany: UI is not Data. UI is not a data store. UI is meant to show Data, not to store it.
顿悟:UI 不是数据。UI 不是数据存储。UI 旨在显示数据,而不是存储数据。
1 - Create a simple object to hold your data
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 - Define Bindings in your Document;
2 -Binding在您的文档中定义s;
<Paragraph>
<Run Text="{Binding Header}"/>
</Paragraph>
3 - Set your FlowDocument's DataContextto an instance of this class:
3 - 将 FlowDocument 设置DataContext为此类的实例:
var flowdoc = new YourFlowDocument();
var data = new MyDocumentViewModel { Header = "this is the Header" };
//whatever other data
flowdoc.DataContext = data;
//do the printing stuff.

