Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Printpreview errors when calling from mdi parent 1

Status
Not open for further replies.

tonyladuk

Programmer
Aug 18, 2006
16
US
The error only kicks in sometimes and when it does, the printpreview does not work again without restarting the application.

PrintPreviewDialog1.ShowDialog()
ArgumentException was unhandled
Parameter is not valid.

I’m not sure what the error is talking about because it works 50% of the time. I thought at first it might have been an issue with the amount of time it took for the graphics drawing which is why I added plenty of pauses inbetween each statement. I can actually comment out all of the code within the print event and it will still not reach it and crash.

Also if my coding looks horrendous (which I’m sure it might seeing as though printing is all self taught) then any hints would be great too.

Below are the printpreview menu click event from the mdi parent and the code for the printpreviewdialog print event for the mdi child.

Code:
    'This code is in the mdi parent and is used to print a preview of the 
    'currently selected mdi form
    Private Sub mnuPrintPreview_Click(ByVal sender As System.Object, _ 
        ByVal e As System.EventArgs) Handles mnuPrintPreview.Click

        'is this the best way to reset the printpreviewdialog?
        PrintPreviewDialog1.Document = Nothing

        Dim intPrintAreaHeight, intPrintAreaWidth, marginLeft, marginTop As Int32
        With PrintDocument1.DefaultPageSettings
            intPrintAreaHeight = .PaperSize.Height - .Margins.Top - .Margins.Bottom
            intPrintAreaWidth = .PaperSize.Width - .Margins.Left - .Margins.Right
            marginLeft = .Margins.Left
            marginTop = .Margins.Top
        End With
        ' If the user selected Landscape mode, swap the area height and width.
        If PrintDocument1.DefaultPageSettings.Landscape Then
            Dim intTemp As Int32
            intTemp = intPrintAreaHeight
            intPrintAreaHeight = intPrintAreaWidth
            intPrintAreaWidth = intTemp
        End If

        Dim frmCurrent As Form = Me.ActiveMdiChild
        Select Case frmCurrent.Name
            Case "frmCFRReport"
               'pass a print area rectangle to the form
                frmCFRReport.PrintAreaRectangle = New Rectangle(marginLeft, _ 
                marginTop, intPrintAreaWidth, intPrintAreaHeight)
                frmCFRReport.PageSettings = PrintDocument1.DefaultPageSettings
               'set the printpreviewdialog1 to the childform printpreviewdocument
                PrintPreviewDialog1.Document = frmCFRReport.PrintCFRDocument
            Case else
                'Other cases here
        End Select

        If PrintPreviewDialog1.Document IsNot Nothing Then
            PrintPreviewDialog1.ShowDialog()
        End If

    End Sub

Code:
    'this is the mdi child form printpreviewdocument print event
    Public Sub PrintCFRDocument_PrintPage(ByVal sender As System.Object, _ 
        ByVal e As System.Drawing.Printing.PrintPageEventArgs) _ 
        Handles PrintCFRDocument.PrintPage

        e.Graphics.Clear(Color.White)
        Threading.Thread.Sleep(50)

        e.Graphics.DrawString(lblMainHeading.Text, MainFont, TextColour, _
        recPrintArea.Left + lblMainHeading.Left, recPrintArea.Top + _
        lblMainHeading.Top)
        Threading.Thread.Sleep(50)

        e.Graphics.FillRectangle(SubHeadingGroupColour, recPrintArea.Left _
        + grpExpenditure.Left + intExpXOffset, recPrintArea.Top + _
        grpExpenditure.Top + intExpYOffset, grpExpenditure.Width, _
        grpExpenditure.Height)
        Threading.Thread.Sleep(50)
    End Sub


Any help would be GREATLY appreciated. I seem to be running around in circles here.
 
Does anyone have any ideas? I'm clutching at straws here! Any help would be fantastic.
 
I tried to recreate what you were doing but I can't seem to understand what you are doing.

So some questions.

The mnupreviewbutton is on the mainform? called?

the printdocument is on the mdiform? Why?

No need for the sleeps.

If it crashes 50% of the time then on wich line. Did you try to put all that code in the mdichild and just have a public Print method on that child.

And yes the code looks a mess because you are not giving the right control to the right object. I think that the parent control should only be aware that the children have a print method nothing else. The children should implement an interface that looks something like this

Code:
public interface IPrintable
   Sub Print()
   Sub PrintPreview()
End Interface

And then you implement them. An MDI child should be able to work on it's own without any help of the parent.

So the above code should look something like this in the parent

Code:
Private Sub mnuPrintPreview_Click(ByVal sender As System.Object, _ 
        ByVal e As System.EventArgs) Handles mnuPrintPreview.Click
     ctype(me.activemdichild,IPrintable).PrintPreview
End Sub

And if you have several forms that have the same workings then try inheritance.

Christiaan Baes
Belgium

"My new site" - Me
 
Thanks so much for replying Christiaan, really appreciate the time.

VB.Net is sortof self taught after working with VB6 for a year and programming was taught through uni so you'll have to bear with me for which I am sorry.

If each child has their own Print and Printpreview subs, I assume I have a to add a print preview control to each of the mdi children as well as a printdialog and pagesetupdialog? Am i right on this part? And if so, the pagesetupdialog does not need to be specific to each page, so how do i use inheritence (as mentioned above) to only have one pagesetupdialog (on the parent) and pass its values through to the children for their print/print preview subs?

Finally, if i use the method stated above with the public interface that holds the subs, how do i then associate those subs with the document printpage event? Must I use the (sender, e) in order to call the e.Graphics abilities?

Many thanks in advance,

Tony, Manchester UK

Code:
public interface IPrintable
   Sub Print()
   Sub PrintPreview()
End Interface


Sub Print()

End Sub


'this is the mdi child form printpreviewdocument print event
Public Sub PrintCFRDocument_PrintPage(ByVal sender As System.Object, _ 
    ByVal e As System.Drawing.Printing.PrintPageEventArgs) _ 
    Handles PrintCFRDocument.PrintPage

    e.Graphics.Clear(Color.White)

End Sub
 
Inheritance is very simple

you create a form for example form1 in form1.vb file

Code:
public class class1
  inherits system.windows.forms.form
  implements Iprintable

  private withevents printdocument1 as printdocument
  private withevents prinpreviewdialog1 as prinpreviewdialog
  
  Public sub print() implements Iprintable.Print
    'code goes here
  end sub

  public sub PrintPreview() implements Iprintable.PrintPreview
   'code goes here
  end sub
end class

and then you inherit from that

Code:
public class Form2
  inherits form1


end class

The form2 will now have the print and printpreview methods from form1 and any other code it has.


BTW the interface goes in it's own file and is like a class but without implementation.


You really should learn OOP.

Christiaan Baes
Belgium

"My new site" - Me
 
OK I'm just about getting there, although I'm not sure how to use the inheritance as described above.

Now in the mdichild I have this:

Code:
Public Class Form1

    Inherits System.Windows.Forms.Form
    Implements Iprintable

    Public Interface IPrintable
        Sub Print()
        Sub PrintPreview()
    End Interface

    Private WithEvents Printdialog1 As PrintDialog
    Private WithEvents Printdocument1 As Printing.PrintDocument
    Private WithEvents Printpreviewdialog1 As PrintPreviewDialog

    Public Sub print() Implements Iprintable.Print
        PrintDialog1.Document = PrintDocument1
        If PrintDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
            PrintDocument1.Print()
        End If
    End Sub

    Public Sub PrintPreview() Implements IPrintable.PrintPreview
        PrintPreviewDialog1.Document = PrintDocument1
        PrintPreviewDialog1.ShowDialog()
    End Sub

End Class

And in the parent mdi i have this:

Code:
Public Class MDIParent1

    Private Sub PrintToolStripButton_Click(ByVal sender As System.Object, _ 
        ByVal e As System.EventArgs) Handles PrintToolStripButton.Click
        CType(Me.ActiveMdiChild, Form1.IPrintable).Print()
    End Sub

    Private Sub PrintPreviewToolStripButton_Click(ByVal sender As System.Object, _ 
        ByVal e As System.EventArgs) Handles PrintPreviewToolStripButton.Click
        CType(Me.ActiveMdiChild, Form1.IPrintable).PrintPreview()
    End Sub

    Private Sub HelpToolStripButton_Click(ByVal sender As System.Object, _ 
        ByVal e As System.EventArgs) Handles HelpToolStripButton.Click

        PageSetupDialog1.Document = ???
        PageSetupDialog1.PageSettings = ???

        If PageSetupDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            ??? = PageSetupDialog1.PageSettings
        End If

    End Sub

End Class

So how do i pass just the pagesetup information to the children forms from the parent the proper way? I could do it like before and create their own properties but i want to try to get it right and i can only learn from the master!
 
Code:
 Public Interface IPrintable
        Sub Print()
        Sub PrintPreview()
    End Interface

this should go in it's own file or at least outside the public class form1 declaration.

For the rest you would make properties on the children to give you what you want

For example

Code:
Public Class Form1
    Inherits System.Windows.Forms.Form
    Implements IPrintable

    Private WithEvents Printdialog1 As New PrintDialog
    Private WithEvents Printdocument1 As New Printing.PrintDocument
    Private WithEvents Printpreviewdialog1 As New PrintPreviewDialog
    Private WithEvents PageSetupDialog1 As New PageSetupDialog

    Public Sub print() Implements IPrintable.Print
        Printdialog1.Document = Printdocument1
        If Printdialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
            Printdocument1.Print()
        End If
    End Sub

    Public Sub PrintPreview() Implements IPrintable.PrintPreview
        Printpreviewdialog1.Document = Printdocument1
        Printpreviewdialog1.ShowDialog()
    End Sub

    Public Sub PrintSetup() Implements IPrintable.PrintSetup
        PageSetupDialog1.Document = Printdocument1
        PageSetupDialog1.PageSettings = Printdocument1.DefaultPageSettings

        If PageSetupDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            Printdocument1.DefaultPageSettings = PageSetupDialog1.PageSettings
        End If
    End Sub


    Private Sub Printdocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles Printdocument1.PrintPage
        e.Graphics.Clear(Color.White)
        e.Graphics.DrawString(lblMainHeading.Text, MainFont, TextColour, _
        recPrintArea.Left + lblMainHeading.Left, recPrintArea.Top + _
        lblMainHeading.Top)
        e.Graphics.FillRectangle(SubHeadingGroupColour, recPrintArea.Left _
        + grpExpenditure.Left + intExpXOffset, recPrintArea.Top + _
        grpExpenditure.Top + intExpYOffset, grpExpenditure.Width, _
        grpExpenditure.Height)
    End Sub
End Class

Public Interface IPrintable
    Sub Print()
    Sub PrintPreview()
    Sub PrintSetup()
End Interface

Code:
Public Class MDIParent1

    Private Sub PrintToolStripButton_Click(ByVal sender As System.Object, _ 
        ByVal e As System.EventArgs) Handles PrintToolStripButton.Click
        CType(Me.ActiveMdiChild, Form1.IPrintable).Print()
    End Sub

    Private Sub PrintPreviewToolStripButton_Click(ByVal sender As System.Object, _ 
        ByVal e As System.EventArgs) Handles PrintPreviewToolStripButton.Click
        CType(Me.ActiveMdiChild, Form1.IPrintable).PrintPreview()
    End Sub

    Private Sub HelpToolStripButton_Click(ByVal sender As System.Object, _ 
        ByVal e As System.EventArgs) Handles HelpToolStripButton.Click
        CType(Me.ActiveMdiChild, Form1.IPrintable).PrintSetup()
    End Sub

End Class



Christiaan Baes
Belgium

"My new site" - Me
 
If you were here, i'd buy you a pint!

Thanks for the help.

FYI my OO is getting better all the time. The inheritance part always confuses me. Its hard when you're going from your own back so i'm learning as i go along. For example, when i discovered Properties, I had to go back and change all my public subroutines! The same was true with overrideables, very interesting I thought.

But thanks again.
 
The equivalent of buying chrissie a pint is for you to click on


Thank chrissie1
for this valuable post!


which you can find at the bottom of any one of his replies. [wink]


[vampire][bat]
 
Well not exactly the equivalent but close enough.

Strange I would give one to myself but I can't see a link on the bottom of my post. Do you think the site is broken?

Christiaan Baes
Belgium

"My new site" - Me
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top