Почему я теряю привязку данных при печати в XpsDocument?
Обновить!
Переплетные работы. Проблема в том, что 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 ответа
Причиной этой ошибки является то, что макет FixedPage не обновляется до записи. Это приводит к тому, что первая FixedPage в первом FixedDocument в FixedDocumentSequence будет написана неправильно. Это не влияет на ДРУГИЕ СТРАНИЦЫ В РЕЗУЛЬТАТИВНОМ ДОКУМЕНТЕ, из-за чего этот баг / крайний случай сложнее зафиксировать
Следующие РАБОТЫ (переписанная версия нерабочего примера):
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
безуспешно. Странно, как хорошо печатается первая страница, если я покажу диалоговое окно печати.
Одна из причин, по которой вы теряете привязку, заключается в том, что вы генерируете исключение где-то - к сожалению, это исключение незаметно проглатывается, и ваша привязка просто "перестает работать". Включите исключения первого шанса и посмотрите, не попало ли что-нибудь.