私は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のどちらかを指定すると、ビューボックスがバックグラウンドでレンダリングされないと考えられます。各ページでこれを繰り返すことができる方法はありますか?
問題は、私のヘッダーに1つの画像と2つの部分のテキストが含まれていることです。私はすでに最初のページだけに置くように作成しましたが、今は要件が変更されており、すべてのページでそれを繰り返さなければなりません。
ご協力いただきまして誠にありがとうございます。
後編集:これも試しましたが、どちらもうまくいきませんでした。 getHeaderメソッドに
vb.Measure(new System.Windows.Size(headerWidth, headerHeight));
vb.Arrange(new Rect(15,15,headerWidth,headerHeight));
vb.UpdateLayout();
を追加することによって修正
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;
}