Click here to Skip to main content
15,921,941 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I am creating xps report dynamically using wpf. My approach was to use the

method provided by drawing context class to draw text, rectangle, line and etc,

but the "alignment" is not so correct. All my "alignment" is done using some complex

calculation. I Know that WPF is freeflowing can any one suggest the better approach,

so that I can use WPF full functionality and I can aviod the calculation.

I will send the some sample code:

C#
visual = new DrawingVisual();
drawingContext = visual.RenderOpen();

private void PrintHeader() {

      x = Sizes.Gutter;
      y = Sizes.Margin;
      Rect rect = new Rect(Sizes.Gutter,Sizes.Margin,Sizes.Width,Sizes.Header);
      drawingContext.DrawRectangle(color,Pens.Blueline,rect);
      Bitmap bitmap = Resources.Logo;
      BitmapSource imgSource = ConvertToBitmapSource(bitmap);
     drawingContext.DrawImage(imgSource, new Rect(Sizes.Gutter + 10, Sizes.Margin + 10, 150, 50));   

 DrawCentered(GetMetaText("Title").ToUpper(), Font.Header, Brushes.White, rect, FontSizes.Header);
      rect.Offset(0,20);
      DrawCentered(GetMetaText("Department"), Font.Body, Brushes.White, rect, FontSizes.Body);
      rect.Offset(0,10);
      DrawCentered(GetMetaText("Phone"), Font.Body, Brushes.White, rect, FontSizes.Body);

 Rect lineRect = new Rect(rect.Left,0,rect.Width,Sizes.Leading);
        lineRect.Y = rect.Bottom - (((float)value - bounds.MinY) * rect.Height / (bounds.Height));

}

  internal void DrawLeft(string text,Typeface font,Brush brush,Rect rect,int size) {
      rect.Inflate(-Sizes.Padding,-Sizes.Padding);
      drawingContext.DrawText(new FormattedText(text,CultureInfo.GetCultureInfo("en-us"),
                                                FlowDirection.LeftToRight,font,
                                                12,brush),new Point(rect.X,rect.Y));

    }

    internal void DrawCentered(string text,Typeface font,Brush brush,Rect rect,float size) {
      drawingContext.DrawText(new FormattedText(text,CultureInfo.GetCultureInfo("en-us"),
                                  FlowDirection.LeftToRight,font,
                                  size,brush),new Point(rect.X,rect.Y));

    }

    internal void DrawRight(string text,Typeface font,Brush brush,Rect rect,float size) {
      rect.Inflate(-Sizes.Padding,-Sizes.Padding);
      drawingContext.DrawText(new FormattedText(text,CultureInfo.GetCultureInfo("en-us"),
                                                FlowDirection.LeftToRight,font,
                                                size,brush),new Point(rect.Y - 20,rect.Y));
    }
Posted
Updated 8-Feb-12 5:46am
v3

1 solution

I would use the FlowDocument. That way, you can produce your report in XAML.

<FlowDocumentReader>
    <FlowDocument
        Name="flowDocument"
        ColumnWidth="400" FontSize="14" FontFamily="Georgia">
        <Paragraph>
            <Grid>
                <Rectangle Fill="Red" Width="200" Height="100"/>
                <TextBlock Text="Hello World!" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Grid>
        </Paragraph>
    </FlowDocument>
</FlowDocumentReader>


With some C# code to save it as XPS:

C#
public static void SaveAsXps(string path, FlowDocument document)
{
    using (var package = Package.Open(path, FileMode.Create))
    {
        using (var xpsDocument = new XpsDocument(package, System.IO.Packaging.CompressionOption.Maximum))
        {
            var xpsSerializationManager = new XpsSerializationManager(new XpsPackagingPolicy(xpsDocument), false);
            var documentPaginator = ((IDocumentPaginatorSource)document).DocumentPaginator;
            xpsSerializationManager.SaveAsXaml(documentPaginator);
        }
    }
}


And finally the call to this function:

C#
SaveAsXps("temp.xps", flowDocument);
 
Share this answer
 
v2
Comments
sajithnet 10-Feb-12 0:54am    
thanks SteveAdey.
sajithnet 10-Feb-12 6:18am    
hay steve,
As u mentioned i made a usercontrol of Header(Header.xaml)and placed the grid
with rect and text block there .iam calling this template in my Report.xaml
i need to get the Textblock object and need to the Text property of it.can i do this.


Code:
StreamReader reader = new StreamReader(new FileStream(@"Templates/Header.xaml",FileMode.Open,FileAccess.Read));
XmlTextReader xmlReader = new XmlTextReader(reader);

flowDocument = XamlReader.Load(xmlReader) as FlowDocument;
reader.Close();

flowDOcumentViewer.Document = flowDocument;



Regards,
sajith

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900