質問

更新!

バインディングが機能します。問題は、XpsDocumentWriterがFixedDocumentSequenceの最初のドキュメントの最初のページを適切に書き込まないことです。これは、この種のことをしている多くの人々(つまり、世界中の5人の開発者)が遭遇する問題のようです。解決策は少し奇妙です。回答として含めます。


さて、質問が示唆するよりも少し微妙です。

一連のFixedPageがあり、それぞれに個別にDataContextが設定されています。各FixedPageには、コンテキストにバインドされた1つ以上のコントロールもあります。

これらの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();

この2つの唯一の違いは、固定ドキュメントを固定ドキュメントシーケンスに追加していることです。

明らかに、固定ドキュメントがXpsドキュメントに書き込まれていない場合、データバインディングが評価され、バインドされた値が挿入されるようなマジックが発生することはありません。複数の固定ドキュメントを記述できる必要があり、Writeメソッドは1回しか呼び出すことができないため、FixedDocumentsをFixedDocumentSequenceに追加してから記述する必要があります。しかし、同様に機能するためには、いまいましいデータバインディングが必要です

このような状況で助けていただければ幸いです。フレームワークの最も一般的な部分ではありません。私はここの誰かがこれについて何らかの運用経験を持っていることを望んでいます(私はあなたを見ています、MSの従業員に潜んでいます)。

役に立ちましたか?

解決

このバグの原因は、FixedPageのレイアウトが書き込み前に更新されていないことです。これにより、FixedDocumentSequenceの最初のFixedDocumentの最初のFixedPageが誤って書き込まれます。これは、[結果ドキュメントに他のページがありません]に影響し、このバグ/エッジケースの特定が難しくなりました。

次のWORKS(動作しない例の書き直されたバージョン):

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

他のヒント

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のレイアウトを更新しようとしました。ただし、印刷ダイアログを表示した場合、最初のページがうまく印刷されるのは奇妙です。

バインディングを失う理由の1つは、どこかで例外をスローすることです。残念ながら、この例外は静かに飲み込まれ、バインディングは<!> quot; stoping working <!> quot;になります。初回例外をオンにして、何かがヒットするかどうかを確認します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top