8

アップデート!

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


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

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

これらの FixedPages を 1 つの FixedDocument に追加し、この 1 つの 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の従業員です)。

4

3 に答える 3

9

このバグの原因は、書き込み前に 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();
于 2009-01-16T16:51:34.220 に答える
0

バインディングが失われる理由の 1 つは、どこかで例外をスローすることです。残念ながら、この例外は黙って飲み込まれ、バインディングは単に「動作を停止」します。First-chance Exceptions をオンにして、何かがヒットするかどうかを確認します。

于 2009-01-16T03:05:42.207 に答える