XPSDocument에 인쇄 할 때 데이터베인딩을 잃어 버리는 이유는 무엇입니까?
-
19-08-2019 - |
문제
업데이트!
구속력이 작용합니다. 문제는 XPSDocumentWriter가 FixedDocumentSequence의 첫 번째 문서의 첫 페이지를 올바르게 작성하지 않는다는 것입니다. 이것은 많은 사람들이 이런 종류의 일을하는 문제인 것 같습니다 (예 : 전 세계 5 명의 개발자). 솔루션은 약간 이상합니다. 나는 그것을 대답으로 포함시킨다.
좋아, 질문이 제안하는 것보다 조금 더 미묘합니다.
일련의 고정 페이지가 있으며 각각 데이터 컨트리 텍스트 세트가 개별적으로 설정되어 있습니다. 각 고정 페이지에는 컨텍스트에 묶인 하나 이상의 컨트롤이 있습니다.
이 고정 페이지를 단일 고정 문서에 추가 하고이 단일 고정 문서를 XPSDocument에 작성하면 바인드가 참조되지 않으며 (말하자면) 올바른 값이 XPSDocument에 표시됩니다.
이 고정 페이지를 개별 고정 문구에 추가하면 (각 FP가 새 FD에 추가됩니다), 이러한 고정 문구는 고정 문서화 시퀀스에 추가되면이 시퀀스는 XPSDocument에 기록되며 바인드가 반영되지 않으며 내 고정 페이지가 비워집니다. .
디버깅에 따르면 바인딩이나 바인딩 컨텍스트를 잃어 버리지 않으므로이 실패의 원인이 아닙니다.
다음은 현재 진행중인 작업을 설명하기위한 샘플 코드입니다.
// 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 문서에 기록되지 않으면 데이터베인딩을 평가하고 바운드 값을 삽입하는 마법이 발생하는 모든 마법이 발생하지 않습니다. 하나 이상의 고정 된 문서를 작성할 수 있어야하며, 쓰기 방법을 한 번만 호출 할 수 있으므로 고정 문서를 고정 문서화에 추가해야합니다. 그러나 나는 또한 작동하려면 내 망할 데이터 바인딩이 필요합니다!
이 상황에 대한 도움은 감사하겠습니다. 나는 그것이 프레임 워크의 가장 일반적인 부분이 아니라는 것을 알고 있습니다. 나는 여기 누군가가 이것에 대한 운영 경험을 가지고 있기를 바라고 있습니다 (나는 당신을보고 있습니다.
해결책
이 버그의 원인은 고정 페이지의 레이아웃이 글을 쓰기 전에 업데이트되지 않기 때문입니다. 이로 인해 FixedDocumentSectence의 첫 번째 고정 문서에서 첫 번째 고정 페이지가 잘못 작성됩니다. 이것은 영향을 미칩니다 결과 문서의 다른 페이지가 없습니다, 이 버그/모서리 케이스를 못 박기가 어렵게 만들었습니다.
다음 작품 (비 작업 예제의 버전을 다시 작성) :
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
a 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
성공없이. 인쇄 대화 상자를 보여 주면 첫 번째 페이지가 잘 인쇄되는 방식이 이상합니다.
구속력을 잃은 한 가지 이유는 어딘가에 예외를 던지기 때문입니다. 불행히도이 예외는 조용히 삼켜지고 바인딩은 "작동을 멈추는 것"입니다. 첫 번째 기회 예외를 켜고 어떤 일이 발생하는지 확인하십시오.