首先,我不确定我是否正确地表达了标题。有些是UserControls
通过 a 添加的ViewModel
,我通过搜索找到它们VisualTree
并将它们添加到 a ObservableCollection<Grid>
。我想做的是将UserControl
我从 中检索到的每个实例打印VisualTree
到 a中FixedDocument
,但每个实例都UserControl
在一个页面上,直到它填满该页面并移至下一页。
这是我当前的打印按钮单击事件的代码:
private async void btnPrint_Click(object sender, RoutedEventArgs e)
{
try
{
if (tabMain.Items.Count > 0)
{
tab = new TabLayout();
tab.Payslip = new ObservableCollection<Grid>();
foreach (var grid in FindVisualChildren<Grid>(this))
{
if (grid.Name == "pdfFile")
{
tab.Payslip.Add(grid);
}
}
FrameworkElement toPrint = new FrameworkElement();
PrintDialog printDialog = new PrintDialog();
PrintCapabilities capabilities = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);
Size pageSize = new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight);
Size visibleSize = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
FixedDocument fixedDoc = new FixedDocument();
StackPanel panel = new StackPanel(); //was trying to stack them in a stackpanel first but it threw an exception about same instance of usercontrol blah blah...
foreach (var doc in tab.Payslip.ToList())
{
double yOffset = 0;
doc.Measure((new Size(double.PositiveInfinity, double.PositiveInfinity)));
doc.Arrange(new Rect(new Point(0, 0), doc.DesiredSize));
Size size = doc.DesiredSize;
while (yOffset < size.Height)
{
VisualBrush vb = new VisualBrush(doc);
vb.Stretch = Stretch.None;
vb.AlignmentX = AlignmentX.Left;
vb.AlignmentY = AlignmentY.Top;
vb.ViewboxUnits = BrushMappingMode.Absolute;
vb.TileMode = TileMode.None;
vb.Viewbox = new Rect(0, yOffset, visibleSize.Width, visibleSize.Height);
FixedPage page = new FixedPage();
PageContent pageContent = new PageContent();
((IAddChild)pageContent).AddChild(page);
fixedDoc.Pages.Add(pageContent);
page.Width = fixedDoc.DocumentPaginator.PageSize.Width;
page.Height = fixedDoc.DocumentPaginator.PageSize.Height;
Canvas canvas = new Canvas();
FixedPage.SetLeft(canvas, capabilities.PageImageableArea.OriginWidth);
FixedPage.SetTop(canvas, capabilities.PageImageableArea.OriginHeight);
canvas.Width = visibleSize.Width;
canvas.Height = visibleSize.Height;
canvas.Background = vb;
page.Children.Add(canvas);
yOffset += visibleSize.Height;
}
}
//printDialog.PrintDocument(fixedDoc.DocumentPaginator, "");
ShowPrintPreview(fixedDoc);
}
}
catch(Exception ex)
{
var exceptionDialog = new MessageDialog
{
Message = { Text = ex.ToString() }
};
await DialogHost.Show(exceptionDialog, "RootDialog");
}
}
这是我尝试打印三个选项卡时的样子(用户控件托管在选项卡中): 正如您在此处看到的,它打印三个单独的页面
我希望所有三个都在一个页面上,如果我打印 10 个标签,那么它应该填满第一页并继续到下一页。
上次我问了一个类似的问题,有人问我是否写了代码。这段代码的点点滴滴来自类似的FixedDocument
问题,StackOverflow
但它已经被编辑到它真正适合我的地步。所以是的,我知道FixedPage
里面的引用foreach
是导致创建三个单独页面的原因,我确实理解代码。
概括:
我想知道的是如何UserControls
从 each中获取Tab
, 到一个页面直到它满了,而不是得到“指定的元素已经是另一个元素的逻辑子元素。首先断开它。” 错误。