为什么我在打印到XpsDocument时丢失了数据绑定?

时间:2009-01-15 23:54:10

标签: data-binding xps fixedpage fixeddocument fixeddocumentsequence

更新!

绑定有效。问题是XpsDocumentWriter没有正确编写FixedDocumentSequence的第一个文档的第一页。这似乎是很多人在做这类事情时遇到的问题(即全世界有五个开发人员)。解决方案有点奇怪。我把它作为答案包括在内。


好吧,它比问题暗示的更微妙。

我有一系列的FixedPages,每个都有自己的DataContext设置。每个FixedPage还有一个或多个绑定到上下文的控件。

如果我将这些FixedPages添加到单个FixedDocument并将此单个FixedDocument写入XpsDocument,我的绑定将被取消引用(可以这么说),并且正确的值将显示在XpsDocument中。

如果我将这些FixedPages添加到单个FixedDocuments(每个FP添加到新的FD),则将这些FixedDocuments添加到FixedDocumentSequence,然后将此序列写入XpsDocument,我的绑定不会被引用而且我的FixedPages显示为空白。

调试告诉我,我没有丢失绑定或绑定上下文,所以这不是导致失败的原因。

以下是一些示例代码来说明正在发生的事情:

// This works
FixedPage fp = CreateFixedPageWithBinding();
fp.DataContext = CreateDataContext();
// Add my databound fixed page to a new fixed document
var fd = new FixedDocument();
var pc = new PageContent();
((IAddChild)pc).AddChild(fp);
fd.Pages.Add(pageContent);
// Create an xps document and write my fixed document to it
var p = Package.Open("c:\\output.xps", FileMode.CreateNew);
var doc = new XpsDocument(p);
var writer = XpsDocument.CreateXpsDocumentWriter(doc);
wri2.Write(fd);
p.Flush();
p.Close();

// This does NOT work
FixedPage fp = CreateFixedPageWithBinding();
fp.DataContext = CreateDataContext();
// Add my databound fixed page to a new fixed document
var fd = new FixedDocument();
var pc = new PageContent();
((IAddChild)pc).AddChild(fp);
fd.Pages.Add(pageContent);
// Create a fixed document sequence and add the fixed document to it
FixedDocumentSequence fds = CreateFixedDocumentSequence();
var dr = new DocumentReference();
dr.BeginInit();
dr.SetDocument(fd);
dr.EndInit();
(fds as IAddChild).AddChild(dr);
// Create an xps document and write the fixed document sequence to it
var p = Package.Open("c:\\output.xps", FileMode.CreateNew);
var doc = new XpsDocument(p);
var writer = XpsDocument.CreateXpsDocumentWriter(doc);
wri2.Write(fds);
p.Flush();
p.Close();

你可以看到两者之间的唯一区别是我将固定文档添加到固定文档序列,然后编写。

显然,无论何种魔法都会导致数据绑定被评估,并且当我的固定文档没有被写入Xps文档时,不会发生绑定值。我需要能够编写多个固定文档,并且只能调用一次Write方法,因此需要将FixedDocuments添加到我编写的FixedDocumentSequence中。但我需要我该死的数据绑定才能正常工作!

在这种情况下的任何帮助将不胜感激。我知道它不完全是框架中最常见的部分;我只是希望有人在这里有一些操作经验(我在看着你,潜伏着MS员工)。

3 个答案:

答案 0 :(得分:9)

此错误的原因是在写入之前未更新FixedPage的布局。这会导致FixedDocumentSequence中第一个FixedDocument中的第一个FixedPage被错误地写入。这会影响在结果文档中没有其他页面,这使得这个错误/边缘案例更难确定。

以下作品(非工作示例的重写版本):

FixedPage fp = CreateFixedPageWithBinding();
fp.DataContext = CreateDataContext();
var fd = new FixedDocument();

/* PAY ATTENTION HERE */
// set the page size on our fixed document 
fd.DocumentPaginator.PageSize =
   new System.Windows.Size()
   {
       Width = DotsPerInch * PageWidth,
       Height = DotsPerInch * PageHeight
   };
// Update the layout of our FixedPage
var size = fd.DocumentPaginator.PageSize;
page.Measure(size);
page.Arrange(new Rect(new Point(), size));
page.UpdateLayout();    
/* STOP PAYING ATTENTION HERE */

var pc = new PageContent();
((IAddChild)pc).AddChild(fp);
fd.Pages.Add(pageContent);
// Create a fixed document sequence and add the fixed document to it
FixedDocumentSequence fds = CreateFixedDocumentSequence();
var dr = new DocumentReference();
dr.BeginInit();
dr.SetDocument(fd);
dr.EndInit();
(fds as IAddChild).AddChild(dr);
// Create an xps document and write the fixed document sequence to it
var p = Package.Open("c:\\output.xps", FileMode.CreateNew);
var doc = new XpsDocument(p);
var writer = XpsDocument.CreateXpsDocumentWriter(doc);
wri2.Write(fds);
p.Flush();
p.Close();

答案 1 :(得分:1)

我在尝试使用XpsDocumentWriter写入PrintQueue时发现此问题。以下代码正确打印第一页。

//Prints correctly
FixedDocumentSequence Documents = new FixedDocumentSequence();

//some code to add DocumentReferences to FixedDocumentSequence

PrintDialog printDialog = new PrintDialog
{
    PrintQueue = LocalPrintServer.GetDefaultPrintQueue() 
};
printDialog.PrintTicket = printDialog.PrintQueue.DefaultPrintTicket;
if (printDialog.ShowDialog() == true)
{
    Documents.PrintTicket = printDialog.PrintTicket;

    XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(printDialog.PrintQueue);
    writer.Write(Documents, printDialog.PrintTicket);
    printerName = printDialog.PrintQueue.FullName;
}

如果您删除printDialog.ShowDialog()并尝试静默打印到默认打印机,则第一页打印错误。但是,在我的场景中,我不需要使用FixedDocumentSequence,所以我将它换成了一个FixedDocument并且无声打印工作。我尝试更新FixedPage上的布局但没有成功。如果我显示打印对话框,第一页的打印效果会很奇怪。

答案 2 :(得分:0)

丢失绑定的一个原因是你在某个地方抛出异常 - 不幸的是,这个异常被静默吞噬,你的绑定只是“停止工作”。启用第一次机会异常并查看是否有任何问题。