- Генерить отчет в коде. Ага, сейчас. Последний раз я это делал в 94-м году на клиппере. А сейчас все-таки 21-й век, опять-таки избаловались всякими FastReport-ами и иже с ними.
- Генерить статический XAML по шаблону. Например как вот здесь: http://janrep.blog.codeplant.net/WPF-Multipage-Reports--Part-IV--Pagination.aspx. Уже конечно интереснее, но все равно попахивает прошлым веком :)
Итак, описание маленького эксперимента. Совсем маленького и простенького, поэтому просьба сильно не пинать.
Так как очевидно, что самое частое применение подхода с ItemsTemplate и ItemSource - это отобразить какие-нибудь табличные данные, то в эту сторону и смотрим. Подходящим кандидатом для надругательств является TableRowGroup. От него и будем плясать.
- Делаем наследника от TableRowGroup
- Приделываем к нему 2 Dependency-свойства
public IEnumerable ItemSource
Что это такое и код целиком пока приводить не буду. Вот разберусь как в блог исходники залить - тогда и качайте :)
Первая засада возникает в том, что у меня с первого раза не получилось в DataTemplate положить TableRow. Ругается, что "Property 'VisualTree' does not support values of type 'TableRow'". Что в общем странно. Пока обошел созданием наследника от FrameworkElement, у кототорого есть только одно свойство:
public TableRow Row
Из-за этого конечно получается довольно большой XAML, но для эксперимента пойдет.
Дальше собсвенно все просто. При установке любого из свойств (либо ItemsTemplate, либо ItemSource) просто перегенерируем заново содержимое TableRowGroup. Примерно следующим образом
void Refresh()
{
if (Rows == null) return;
if (ItemSource == null) return;
Rows.Clear();
foreach (var obj in ItemSource)
{
var content = ItemsTemplate.LoadContent();
if (content is RowTemplate)
{
var rt = (RowTemplate)content;
rt.Row.DataContext = obj;
Rows.Add(rt.Row);
}
}
}
На самом деле код скорее всего не идеолгически правильный, но на скорую руку не нашел как правильно разворачивать ItemsTemplate, а в исходники ItemsControls-а лезть тоже лениво.
Собсвенно этого достаточно. Теперь можно писать примерно вот так
<table>
<table.columns>
<tablecolumn width="160">
<tablecolumn width="80">
<tablecolumn width="80">
</Table.Columns>
<tablerowgroup>
<tablerow> <!-- Тут у нас заголовок таблицы -->
<tablecell borderthickness="1" borderbrush="Black">
<paragraph>Наименование</paragraph>
</tablecell >
<tablecell borderthickness="1" borderbrush="Black">
<paragraph>Цена</paragraph>
</tablecell >
<tablecell borderthickness="1" borderbrush="Black">
<paragraph>Кол-во</paragraph>
</tablecell>
</tablerow>
</tablerowgroup>
<my:templatedtablerowgroup name="MyRow">
<my:templatedtablerowgroup.itemstemplate>
<datatemplate>
<my:rowtemplate>
<my:rowtemplate.row>
<tablerow>
<tablecell>
<paragraph borderthickness="1" borderbrush="Gray">
<my:bindablerun
boundtext="{Binding Name}">
</paragraph>
</tablecell >
<tablecell>
<paragraph borderthickness="1" borderbrush="Gray">
<my:bindablerun
boundtext="{Binding Price}">
</paragraph>
</tablecell >
<tablecell>
<paragraph borderthickness="1" borderbrush="Gray">
<my:bindablerun
boundtext="{Binding Qty}">
</paragraph>
</tablecell>
</tablerow>
</my:RowTemplate.Row>
</my:RowTemplate>
</datatemplate>
</my:TemplatedTableRowGroup.ItemsTemplate>
</my:TemplatedTableRowGroup>
</table>
Осталось выяснить несколько вопросов
- Разобраться почему TableRow не может быть элементом в DataTemplate.
- Идеологически правильно сделать Refresh, что-то мне подсказывает что биндинг надо по другому настраивать :)
- Разобраться как в блогах постить исходные коды, а то запарился вручную <pre> ставить и заменять больше-меньше на lt-gt.
- Разобраться куда бы положить архив с исходниками, если кому будет интересно. А думал его к блогу можно приделать, но либо не разобрался как, либо оно умеет только картинки и видео в блог вставлять. А заводить отдельный сайт лениво, потому как никогда не делал, надо думать какой лучше (на корпоративный вроде как некрасиво, на narod.ru стыдно :) ).
Комментариев нет:
Отправить комментарий