Search code examples
f#printdocument

How can i print a form using f#


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


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.