我需要使用具有标题网格和可变行数的 XAML 生成一个打印表单,随着行数的增加,这可能会导致多个页面。标题必须出现在每一页上,并且由于行内的文本换行,每一行的高度可能会有所不同。我目前正在尝试使用ItemsControl (行容器)的ActualHeight来确定何时生成新页面,但ActualHeight 的值始终为零。
我的“XAML_Form”具有以下结构。在 ItemTemplate 中使用了一个网格,以允许将行中的列与标题网格中的列对齐。
<Grid Width="980" Height="757">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Name="_headerControl" Grid.Row="0"/>
<ItemsControl Name=_rowsControl ItemsSource={Binding Rows} Grid.Row="1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Grid>
我们的架构有一个报告类,用于处理添加页脚、页码以及将页面聚合到 PDF 中。此报表类对每个 XAML 视图页面都有一个嵌套的 ViewModel。每个页面的 ViewModel 使用行对象的后备列表:
List<RowClass> RowsList;
ViewModel 还有一个 ICollectionView 用于绑定为 ItemsSource:
ICollectionView Rows = new ListCollectionView(RowsList);
我的报表类有一个 CreatePages 方法,其中包含如下代码:
IList<XAML_Form> pages = new List<XAML_Form>();
var vm = new PageViewModelClass();
var page = new XAML_Form { DataContext = vm };
page.InitializeComponent();
page.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity);
page.Arrange(new Rect(new Point(0,0), page.DesiredSize));
var maxRowsHeight = page.DesiredSize.Height - page._headerControl.ActualHeight;
pages.Add(page);
var rowsOnPage = 0;
foreach (var row in sourceRowsObjectList)
{
rowsOnPage++;
vm.RowsList.Add(row);
vm.Rows.Refresh();
page.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity);
page.Arrange(new Rect(new Point(0,0), page.DesiredSize));
if (page._rowsControl.ActualHeight <= maxRowsHeight)
continue;
// The rows exceed the available space; the row needs to go on the next page.
vm.RowsList.RemoveAt(--rowsOnPage);
vm = new PageViewModelClass();
vm.RowsList.Add(row);
rowsOnPage = 1;
page = new XAML_Form { DataContext = vm };
page.InitializeComponent();
pages.Add(page);
}
return pages;
最初的 Measure/Arrange确实为我提供了 maxRowsHeight 的预期值。生成的表单对于有几行的单个页面看起来很好。我的具体问题是:为什么 page._rowsControl.ActualHeight 总是零?一般来说,有没有更好的方法来解决这个问题?