我希望能够将"reports“创建为常规的MVVM视图,因此为了测试这个想法,我创建了以下视图。它只是由一个绑定文本块、一个ItemsControl (绑定到几百个字符串的集合)和一个第二个文本块组成:
<UserControl ...>
<UserControl.Resources>
<DataTemplate x:Key="myListItemTemplate">
<TextBlock Text="{Binding}"
Foreground="Blue" />
</DataTemplate>
</UserControl.Resources>
<FlowDocument x:Name="flowDoc">
<BlockUIContainer>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Message}" />
<ItemsControl ItemsSource="{Binding SomeList}"
ItemTemplate="{StaticResource myListItemTemplate}" />
<TextBlock Text="THE END" />
</StackPanel>
</BlockUIContainer>
</FlowDocument>
</UserControl>我使用这样的DocumentPaginator打印视图:
private void Print(IPrintableView view)
{
var dlg = new PrintDialog();
if (!dlg.ShowDialog().GetValueOrDefault())
{
return;
}
var paginator = new MyDocumentPaginator(
view.FlowDocument,
new Size(dlg.PrintableAreaWidth, dlg.PrintableAreaHeight),
new Size(DefaultMarginWidthDpi, DefaultMarginHeightDpi));
dlg.PrintDocument(paginator, "My print job");
}不出所料,文档没有被分页,并产生了一个1页的报告,在列表的一半时间内会被截断。(我不认为我的文档分页器实现在这里很重要,它只是为每个页面添加了一个页眉和页脚,如果我使用FlowDocument自己的FlowDocumentPaginator,我会看到同样的问题)。
正如我现在所理解的,文档分页器只会中断“Block(https://learn.microsoft.com/en-us/dotnet/api/system.windows.documents.block?view=netframework-4.6.1&f1url=%3FappId%3DDev16IDEF1%26l%3DEN-US%26k%3Dk(System.Windows.Documents.Block%29%3Bk(vs.objectbrowser%29%3Bk(TargetFrameworkMoniker-.NETFramework%2CVersion%253Dv4.6.1%29%26rd%3Dtrue))”控件,因此我修改了xaml,将每个控件包装在一个BlockUIContainer中。
<UserControl ...>
<UserControl.Resources>
<DataTemplate x:Key="myListItemTemplate">
<TextBlock Text="{Binding}"
Foreground="Blue" />
</DataTemplate>
</UserControl.Resources>
<FlowDocument x:Name="flowDoc">
<BlockUIContainer>
<TextBlock Text="{Binding Message}" />
</BlockUIContainer>
<BlockUIContainer>
<ItemsControl ItemsSource="{Binding SomeList}"
ItemTemplate="{StaticResource myListItemTemplate}" />
</BlockUIContainer>
<BlockUIContainer>
<TextBlock Text="THE END" />
</BlockUIContainer>
</FlowDocument>
</UserControl>在这里,在第一个TextBlock之后会出现一个分页,列表从第2页开始(但仍然在该页的末尾被截断),第二个文本块出现在第3页上。
我假设分页器是作为一个整体来度量和呈现整个ItemsControl,因此我尝试通过BlockUIContainer将每个列表项通过ItemContainerStyle:
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<BlockUIContainer>
<ContentPresenter Content="{Binding}" />
</BlockUIContainer>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.ItemContainerStyle>不过,这没什么区别。有办法让这件事奏效吗?我用正确的方式处理这件事了吗?将每个UI控件放置在一个“块”中似乎非常麻烦,特别是在实现包含大量复杂性的真正报告的时候。真正的报告也不一定是基于列表的,并且更有可能在一个相当自由的布局中包含多种控件--文本、图像、列表等(比带状报告更多的网页)。
发布于 2022-07-25 15:29:12
因此,这并不像我所期望的那样简单,如果不是因为无意中遇到这篇文章,那么我可能永远也找不到解决方案。在本文中,作者创建了一系列类和控件,其中包括一个"FlowDocument友好“列表,并可将其呈现为一个表,这意味着在必要时将在项的TableRows之间出现分页。
这是我更新的“报告视图”xaml。请注意,我还使用了<Paragraph>而不是TextBlock在BlockUIElement中重构文本。您还会注意到,通过自定义BindableRun控件,这些段落也是可绑定的,该控件也是上述文章的一部分:
<UserControl ...>
<FlowDocument x:Name="flowDoc"
TextElement.FontFamily="Arial">
<Paragraph Margin="0,0,0,20">
<flowDocuments:BindableRun BoundText="{Binding Message}" />
</Paragraph>
<flowDocuments:ItemsContent ItemsSource="{Binding SomeList}">
<flowDocuments:ItemsContent.ItemsPanel>
<DataTemplate>
<flowDocuments:Fragment>
<Table>
<Table.Columns>
<TableColumn Width="*" />
</Table.Columns>
<TableRowGroup flowDocuments:Attached.IsItemsHost="True">
<TableRow Background="LightBlue">
<TableCell>
<Paragraph>Heading</Paragraph>
</TableCell>
</TableRow>
</TableRowGroup>
</Table>
</flowDocuments:Fragment>
</DataTemplate>
</flowDocuments:ItemsContent.ItemsPanel>
<flowDocuments:ItemsContent.ItemTemplate>
<DataTemplate>
<flowDocuments:Fragment>
<TableRow>
<TableCell>
<Paragraph>
<flowDocuments:BindableRun BoundText="{Binding}" />
</Paragraph>
</TableCell>
</TableRow>
</flowDocuments:Fragment>
</DataTemplate>
</flowDocuments:ItemsContent.ItemTemplate>
</flowDocuments:ItemsContent>
<Paragraph>THE END</Paragraph>
</FlowDocument>
</UserControl>自定义ItemsContent控件用于呈现列表,并具有一些熟悉的属性:
ItemsSource属性ItemTemplate属性,以及用于呈现VM集合中的字符串项的<TableRow>ItemsPanel,用于定义“容器”--在本例中是一个Table控件。此示例包括用于显示列标题的硬编码TableRow。我相信其他容器是允许的,例如a,虽然我没有详细阅读这篇文章。无论如何,所有这些看起来都正常,并生成一个正确分页的报表,其中字符串列表在正确的位置断开到新页。
如果有人像我一样使用本文生成报告,请注意,ItemsContent加载的事件从不触发,导致列表不呈现(这大概是因为我以编程方式创建视图和/或没有在屏幕上显示视图)。为了使它正常工作,我不得不注释掉本类后面出现的三行if (IsLoaded)行。
https://stackoverflow.com/questions/73110240
复制相似问题