вторник, 23 декабря 2008 г.

Копаем дальше

Собственно практически все уже получилось. Правда не идеально, но работает.

Как оказалось DataBinding обновляется не сразу. А только когда пройдет цикл обработки событий (каких не вникал если честно). Выражается это в том, что при экспорте в XPS не вычисляются все свойства на которые есть Binding. Пока не загрузишь этот документ в FlowDocumentReader (ну он его естесвенно на экране отобразит, и когда начнет ждать нажатия кнопок, вот тут событя и пробегают). Причем в отличие от старых добрых средсв разработки, где можно было сказать Apllication.ProcessMessages :) в WPF приложениях пнуть цикл сообщений вручную довольно интересная задача. Решение нашлось не сразу (надо еще знать какие ключевые слова спросить у гугла), но все-таки нашлось. Описано вот тут: http://blog.fohjin.com/2008/07/saving-wpf-xaml-flowdocument-to-xps.html. Насколько я понял вкратце надо выполнить через Invoke (т.е. дернуть и подождать) пустой метод у Dispatcher-а с самым низким приоритетом. А так как приоритет самый низкий, то сначала отработают все "сообщения" (хотя наверно некорректное название) с более высоким приоритетом и таки вычислят все Binding-выражения.

Интересный подход используется и при печати заголовков-подвалов страниц (естественно не сам придумал, честно передрал и рихтанул напильником отсюда). А именно, делается наследник от ReportPaginator, который резервирует место под загловки (устанавливая размер страницы для оригинального Paginator-а на размер страницы минус размер заголовка). И при формировании каждой страницы складывает ее из 3-х частей (заголовок, сама страница, подвал).

Немного прояснена засада с тем, что в DataTemplate не получается положить ContentElement. На самом деле ругается дизайнер студии. Но при этом все компилируется и работает. А так как дизайнер студии все равно не отрабатывает корректно DataBinding, то и фиг с ним. Так что от промежуточного класса избавились.

Файл с исходниками выложил пока на ifolder. Там есть пример, вроде даже работает. Мог конечно ошибиться где-нибудь с размерами, но вроде похоже на правду. Так как времени сейчас особо много нет, то подробно расписывать что там и как не буду, кому интересно пока предлагаю скачать и посмотреть. Там 18 килобайт.

Осталось 2 неприятные вещи.

1. Пока HeaderHeight и FooterHeight задается вручную. Для эксперимента пойдет, но надо будет все-таки сделать возможность вычислять высоту HederTemplate автоматом.

2. Не получилось придумать нормального места для PageNumber и PageCount. Подставлять их через шаблон вроде как идеологически не очень правильно (хотя и самое простое). А привязать к самому отчету с наскоку не получилось. Поэтому пока работает по следующему алгоритму: У DataContext-а отчета (который по идеологии DM-V-VM является просто обычным объектом) через Reflection ищутся свойства PageNumber и PageCount. И если нашлись - то им присваиваются соотв. значения. Ну а в самом отчете на них можно забиндится. В принципе работает, единственное неудобсвто, что надо заводить 2 дополнительных свойсва, которые будут слать NotifyPropertyChanged.

Комментариев нет:

Отправить комментарий

Постоянные читатели