我正在尝试找到一种在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>
这有点奇怪,因为我永远不会向用户显示这个窗口,我只用一个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中的内容,还是有更好的方法来代替我的方法?
答案 0 :(得分:4)
MVVM 救援:
顿悟:用户界面不是数据。 UI不是数据存储。 UI旨在显示数据,而不是存储数据。
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
;
<Paragraph>
<Run Text="{Binding Header}"/>
</Paragraph>
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.