强制渲染Viewbox以便在页面上绘制它

时间:2016-08-30 08:02:27

标签: c# flowdocument paginator

我正在使用FlowDocument创建报告。现在,我创建了一个分页器,以便能够在每个页面上重复标题,但是,它不会在每个页面上呈现。我怀疑问题在于,在您尝试显示Viewbox时,不会渲染/创建Viewbox。

这是我的GetPage方法:

public override DocumentPage GetPage(int pageNumber) {
        DocumentPage page = m_Paginator.GetPage(pageNumber);

        ContainerVisual newpage = new ContainerVisual();
        DrawingVisual title = new DrawingVisual();
        using (DrawingContext ctx = title.RenderOpen())
        {
            var header = getHeader();
            RenderTargetBitmap bmp = new RenderTargetBitmap(165, 32, 96, 96,
                PixelFormats.Pbgra32);
            bmp.Render(header);
            ctx.DrawImage(bmp,new Rect(new Point(0,0),new Size(166, 33)));
        }
        ContainerVisual smallerPage = new ContainerVisual();
        title.Children.Add(getHeader());

        newpage.Children.Add(title);
        smallerPage.Children.Add(page.Visual);
        smallerPage.Transform = new MatrixTransform(0.95, 0, 0, 0.95, 0.025 * page.ContentBox.Width, 0.025 * page.ContentBox.Height);

        newpage.Children.Add(smallerPage);
        newpage.Transform = new TranslateTransform(m_Margin.Width, m_Margin.Height);
        return new DocumentPage(newpage, m_PageSize, Move(page.BleedBox), Move(page.ContentBox));
    }

这是Move方法:

Rect Move(Rect rect) {

        if (rect.IsEmpty) {
            return rect;
        }

        else {
            return new Rect(rect.Left + m_Margin.Width, rect.Top + m_Margin.Height,
                            rect.Width, rect.Height);
        }
    }

这是getHeader()(是的,我知道,它应该是GetHeader() - 它们的约定)

private Viewbox getHeader() {
        Grid gr = new Grid();
        var sr = Application.GetResourceStream(new Uri("Propuestas;component/img/log.xaml", UriKind.Relative));

        var img = (Canvas)XamlReader.Load(new XmlTextReader(sr.Stream));

        var logo = new Viewbox {
            Child = img,
            HorizontalAlignment = HorizontalAlignment.Left,
            VerticalAlignment = VerticalAlignment.Center,
            Width = 165
        };
        var detalles = new TextBlock {
            FontSize = 10,
            FontFamily = new FontFamily("Verdana"),
            Padding = new Thickness(logo.Width + 15, 0, 0, 0)
        };
        App.Comando.CommandText = "SELECT RazEmp, DirEmp, CpEmp, PobEmp, ProEmp, TelEmp, CifEmp FROM META4.Empresa";
        using (var reader = App.Comando.ExecuteReader())
            while (reader.Read())
                detalles.Text = "" + reader.GetString(0).Trim() + "\n" + reader.GetString(1).Trim() + "\n" +
                                reader.GetDecimal(2) + " - " + reader.GetString(3).Trim() + "(" +
                                reader.GetString(4).Trim() + ")\n" + "Tlf: " + reader.GetString(5).Trim() +
                                "\nCIF: " + reader.GetString(6).Trim();

        var pd = new TextBox {
            Text = "PEDIDO DE COMPRA",
            TextAlignment = TextAlignment.Left,
            FontSize = 19,
            FontFamily = new FontFamily("Verdana"),
            FontWeight = FontWeights.Bold,
            Background = new SolidColorBrush(Color.FromRgb(192, 192, 192)),
            Margin = new Thickness(logo.Width + 15, 10, 0, 20),
            BorderThickness = new Thickness(0)
        };
        gr.ColumnDefinitions.Add(new ColumnDefinition());
        gr.ColumnDefinitions.Add(new ColumnDefinition());
        gr.RowDefinitions.Add(new RowDefinition());
        gr.RowDefinitions.Add(new RowDefinition());
        Grid.SetRow(logo, 0);
        Grid.SetRow(detalles, 0);
        Grid.SetRow(pd, 1);
        Grid.SetColumn(pd, 0);
        Grid.SetColumnSpan(pd, 2);
        Grid.SetColumnSpan(detalles, 2);

        gr.Children.Add(logo);
        gr.Children.Add(detalles);
        gr.Children.Add(pd);
        Viewbox vb = new Viewbox();
        vb.Child = gr;
        return vb;
    }

然而,当我点击打印时,它会正常打印,而不会重复标题。我可以看到调试中运行的查询,因此执行addHeader()。宽度和高度是预定和固定的。 header.Width / header.Height和header.ActualWidth / header.ActualHeight都给我0或NaN,这让我相信视图框不会在后台渲染。有什么办法可以在每一页上重复这个吗?

问题是我的标题包含一个图像和两个部分文本。我已经将它创建为仅放在第一页,但现在要求已经改变,我必须在每一页上重复它。

非常感谢任何帮助。

后来编辑:也尝试了这个,也没用。

private static BitmapSource CaptureScreen(Visual target, double dpiX, double dpiY) {
        if (target == null)
            return null;
        Size size = new Size(165, 31.536);
        RenderTargetBitmap rtb = new RenderTargetBitmap((int)(size.Width * dpiX / 96.0),
                                                    (int)(size.Height * dpiY / 96.0),
                                                    dpiX,
                                                    dpiY,
                                                    PixelFormats.Pbgra32);
        DrawingVisual dv = new DrawingVisual();
        using (DrawingContext ctx = dv.RenderOpen()) {
            VisualBrush vb = new VisualBrush(target);
            ctx.DrawRectangle(vb, null, new Rect(new Point(), size));
        }

        rtb.Render(dv);
        return rtb;
    }

1 个答案:

答案 0 :(得分:0)

通过添加

修复
EOL

到getHeader方法。现在它看起来像这样:

        vb.Measure(new System.Windows.Size(headerWidth, headerHeight));
        vb.Arrange(new Rect(15,15,headerWidth,headerHeight));
        vb.UpdateLayout();