Question

I would like to print a form with calculated data, grafs, datagrids... I'm having problems translating the c# code for printing into f# code:

private void CaptureScreen()
{
    Graphics myGraphics = this.CreateGraphics();
    Size s = this.Size;
    memoryImage = new Bitmap(s.Width, s.Height, myGraphics);
    Graphics memoryGraphics = Graphics.FromImage(memoryImage);
    memoryGraphics.CopyFromScreen(this.Location.X, this.Location.Y, 0, 0, s);
}

private void printDocument1_PrintPage(System.Object sender,  
       System.Drawing.Printing.PrintPageEventArgs e)
{
    e.Graphics.DrawImage(memoryImage, 0, 0);
}

I can't seem to link PrintDocument, PrintDialog and PrintPageEventArgs correctly. Can anybody point me in the right direction?

Thanks

Was it helpful?

Solution

A somewhat sketchy, nevertheless fully functional snippet (download source code from here) showing event wiring for printing of the Form containing an FSharp.Charting chart upon a click of the Button placed on the same form:

open System
open FSharp.Charting
open FSharp.Charting.ChartTypes
open System.Drawing
open System.Drawing.Printing
open System.Windows.Forms

[<STAThread; EntryPoint>]
let main args =
    let captureScreen (form: Form) =
        let myGraphics = form.CreateGraphics()
        let size = form.Size
        let memoryImage = new Bitmap(size.Width, size.Height, myGraphics)
        let memoryGraphics = Graphics.FromImage(memoryImage)
        memoryGraphics.CopyFromScreen(form.Location.X, form.Location.Y, 0, 0, size)
        memoryImage

    let myChart = [for x in 0.0 .. 0.1 .. 6.0 -> sin x + cos (2.0 * x)]
                    |> Chart.Line |> Chart.WithYAxis(Title="Test")

    let chart = new ChartControl(myChart, Dock=DockStyle.Fill)
    use printer = new System.Drawing.Printing.PrintDocument()
    let printBtn = new Button(Text="Print", Dock=DockStyle.Bottom) 
    printBtn.Click.Add(fun prt -> printer.Print())
    let form = new Form(Visible = true, TopMost = true, Width = 700, Height = 500)
    printer.PrintPage.Add(fun prt ->
                                printBtn.Visible <- false
                                prt.Graphics.DrawImage(captureScreen(form), 0, 0)
                                printBtn.Visible <- true)

    form.Controls.AddRange([|chart; printBtn |])
    do Application.Run(form) |> ignore
    0

In order to build it add FSharp.Charting with nuget as well as references to System.Drawing and System.Windows.Forms.

The constituents are:

  • captureScreen function returning a Bitmap image of the whole form
  • System.Drawing.Printing.PrintDocument() is printer reusable object (not to be added to the form)
  • Button having printer.Print() method wired to button's Click event
  • printer.PrintPage event handler that makes the button invisible, captures the form into bitmap and draws the latter, then restores button visibility.

I believe this can be a fair enough starting point for you to move forward.

OTHER TIPS

Thanks a lot!

I've added the printdialog in the code below:

let captureScreen (form: Form) =
    let myGraphics = form.CreateGraphics()
    let size = form.Size
    let memoryImage = new Bitmap(size.Width, size.Height, myGraphics)
    let memoryGraphics = Graphics.FromImage(memoryImage)
    memoryGraphics.CopyFromScreen(form.Location.X, form.Location.Y, 0, 0, size)
    memoryImage

let printdoc = new System.Drawing.Printing.PrintDocument()
let printdia = new PrintDialog(Document=printdoc)     
let mutable Image = new Bitmap(main.Size.Width, main.Size.Height)
let mutable printok = new DialogResult()

print.Click.Add(fun prt -> Image <- captureScreen(main)
                           printok <- printdia.ShowDialog()
                           if printok = DialogResult.OK then printdoc.Print())


printdoc.PrintPage.Add(fun prt ->
                            print.Visible <- false
                            prt.Graphics.DrawImage(Image, 0, 0)
                            print.Visible <- true)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top