On my datagridview I have 3 columns, when a user uses the search box for a product or word e.g. blue, only so many words appear in column A, if I highlight those words and press the Printer option I would like the Print option to display so I can print that selection.
At present its the long way, do a search, highlight the words in that column, copy and paste into notepad and print. I would like to eliminate the notepad part and print whats selected.
Can someone assist me please with some code on the button to bring up the Printer option, so pressing print will print what I have selected in the datagridview.
Thank you.
Last edited by jokerfool; May 7th, 2013 at 11:24 AM.
Check out the VB.NET CodeBank forum and find a thread by Merrion regarding a DataGridPrinter class. Later on in that thread you will also find a DataGridViewPrinter class. I'm not sure that it does what you want as it is but it would not be too hard to modify it to print just selected rows or provide explicit bounds for the rows to print.
I've downloaded that project already and its confusing. Its also not compatible with vs2012. So I loaded it in 2008 and noticed that it doesnt allow a selection, if I choose a selection it just prints the whole page, so dont know where to go from there.
Private Sub PrintDocument1_PrintPage(sender As System.Object, e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
' this assumes that the selection will fit on a single page
' it gets rather more complicated if you want multipage
e.Graphics.DrawString(My.Computer.Clipboard.GetDataObject.GetData("Text", True).ToString, DataGridView1.Font, Brushes.Black, New Point(0, 0))
End Sub
As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"
Reviews: "dunfiddlin likes his DataTables" - jmcilhinney
Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!
I've downloaded that project already and its confusing. Its also not compatible with vs2012. So I loaded it in 2008 and noticed that it doesnt allow a selection, if I choose a selection it just prints the whole page, so dont know where to go from there.
Well, I haven't looked at that project but I would assume that it uses the Rows collection of the grid at some point. If you only want to print the selected rows then logic would dictate that you use the SelectedRows collection to get the data.
When I add the above code and in the datagridview1 I select e.g. 10 lines from column 1 and click the print button, the print preview opens and says "Document does not contain any pages"
Public Class Form1
Private WithEvents pd As New Printing.PrintDocument
Private WithEvents ppd As New PrintPreviewDialog
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For r As Integer = 1 To 10
DataGridView1.Rows.Add(Enumerable.Range(1, 5).Select(Function(x) String.Format("R{0}:C{1}", r, x)).ToArray)
Next
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ppd.Document = pd
ppd.WindowState = FormWindowState.Maximized
ppd.ShowDialog()
End Sub
Private Sub pd_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles pd.PrintPage
Dim startX As Integer = 50
Dim startY As Integer = 50
Dim sf As New StringFormat
sf.Alignment = StringAlignment.Near
sf.LineAlignment = StringAlignment.Center
Dim cells() As DataGridViewCell = DataGridView1.SelectedCells.Cast(Of DataGridViewCell).OrderBy(Function(c) c.OwningRow.Index).ThenBy(Function(c) c.OwningColumn.Index).ToArray
For x As Integer = 0 To cells.Count - 1
Dim cell As DataGridViewCell = cells(x)
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(startX, startY, cell.Size.Width, cell.Size.Height))
e.Graphics.DrawString(cell.Value.ToString, DataGridView1.Font, Brushes.Black, New Rectangle(startX, startY, cell.Size.Width, cell.Size.Height), sf)
If x < cells.Count - 1 AndAlso cells(x + 1).OwningRow Is cells(x).OwningRow Then
startX += cell.Size.Width
End If
If x < cells.Count - 1 AndAlso cells(x + 1).OwningRow IsNot cells(x).OwningRow Then
startX = 50
startY += cell.Size.Height
End If
Next
End Sub
End Class
Warning 1 Using the iteration variable in a lambda expression may have unexpected results. Instead, create a local variable within the loop and assign it the value of the iteration variable. C:\Projects\Grid Search Application\Grid\Form1.vb 20 105 Grid
Yet if I select the selected text and press print then I get a print preview then I can print the information.
Back on the error, this part
Code:
Private Sub pd_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles pd.PrintPage
Dim startX As Integer = 50
Dim startY As Integer = 50
Dim sf As New StringFormat
sf.Alignment = StringAlignment.Near
sf.LineAlignment = StringAlignment.Center
Dim cells() As DataGridViewCell = DataGridView1.SelectedCells.Cast(Of DataGridViewCell).OrderBy(Function(c) c.OwningRow.Index).ThenBy(Function(c) c.OwningColumn.Index).ToArray
For x As Integer = 0 To cells.Count - 1
Dim cell As DataGridViewCell = cells(x)
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(startX, startY, cell.Size.Width, cell.Size.Height))
e.Graphics.DrawString(cell.Value.ToString, DataGridView1.Font, Brushes.Black, New Rectangle(startX, startY, cell.Size.Width, cell.Size.Height), sf)
If x < cells.Count - 1 AndAlso cells(x + 1).OwningRow Is cells(x).OwningRow Then
startX += cell.Size.Width
End If
If x < cells.Count - 1 AndAlso cells(x + 1).OwningRow IsNot cells(x).OwningRow Then
startX = 50
startY += cell.Size.Height
End If
Next
End Sub
I didn't know if I was to double click on anything then add it or what, so I just added it to the end of the code, is there something else I should of done? Thank you Paul for the help.
Bug report see the attachment
Last edited by jokerfool; May 7th, 2013 at 11:23 AM.
that error isn't an error it's just a warning. the warning is about the code I used in form_load + irrelevant.
the important code in that is the 2 withevents declarations, pd_PrintPage, + the code in Button1_Click
post all of the code you're using, if you want us to check it...
assuming you're using the exact code I posted in post #8, this is what it's warning about:
Code:
Public Class Form1
Private WithEvents pd As New Printing.PrintDocument
Private WithEvents ppd As New PrintPreviewDialog
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For r As Integer = 1 To 10
DataGridView1.Rows.Add(Enumerable.Range(1, 5).Select(Function(x) String.Format("R{0}:C{1}", r, x)).ToArray)
Next
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ppd.Document = pd
ppd.WindowState = FormWindowState.Maximized
ppd.ShowDialog()
End Sub
Private Sub pd_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles pd.PrintPage
Dim startX As Integer = 50
Dim startY As Integer = 50
Dim sf As New StringFormat
sf.Alignment = StringAlignment.Near
sf.LineAlignment = StringAlignment.Center
Dim cells() As DataGridViewCell = DataGridView1.SelectedCells.Cast(Of DataGridViewCell).OrderBy(Function(c) c.OwningRow.Index).ThenBy(Function(c) c.OwningColumn.Index).ToArray
For x As Integer = 0 To cells.Count - 1
Dim cell As DataGridViewCell = cells(x)
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(startX, startY, cell.Size.Width, cell.Size.Height))
e.Graphics.DrawString(cell.Value.ToString, DataGridView1.Font, Brushes.Black, New Rectangle(startX, startY, cell.Size.Width, cell.Size.Height), sf)
If x < cells.Count - 1 AndAlso cells(x + 1).OwningRow Is cells(x).OwningRow Then
startX += cell.Size.Width
End If
If x < cells.Count - 1 AndAlso cells(x + 1).OwningRow IsNot cells(x).OwningRow Then
startX = 50
startY += cell.Size.Height
End If
Next
End Sub
End Class
Remove Form1_Load Sub. That's just an example range of values for the DGV. As your DGV already contains values its not necessary.
I'm really surprised that my own solution didn't work for you. I had very acceptable results from it.
As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"
Reviews: "dunfiddlin likes his DataTables" - jmcilhinney
Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!
Imports System.Xml
Imports System.Data
Public Class Form1
'Added 8th May 2013
Private WithEvents pd As New Printing.PrintDocument
Private WithEvents ppd As New PrintPreviewDialog
'Added 8th May 2013 Above
Dim ds As New DataSet
Private Property iChildFormNumber As Integer
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim xmlFile As XmlReader
xmlFile = XmlReader.Create("C:\ta.xml", New XmlReaderSettings())
ds.ReadXml(xmlFile)
DataGridView1.DataSource = ds.Tables(0)
'Added 8th May 2013
End Sub
Private Sub PrintToolStripButton1_Click(sender As Object, e As EventArgs) Handles PrintToolStripButton1.Click
'Added 8th May 2013
ppd.Document = pd
ppd.WindowState = FormWindowState.Maximized
ppd.ShowDialog()
'Added 8th May 2013 above
End Sub
'Added 8th May 2013
Private Sub pd_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles pd.PrintPage
Dim startX As Integer = 50
Dim startY As Integer = 50
Dim sf As New StringFormat
sf.Alignment = StringAlignment.Near
sf.LineAlignment = StringAlignment.Center
Dim cells() As DataGridViewCell = DataGridView1.SelectedCells.Cast(Of DataGridViewCell).OrderBy(Function(c) c.OwningRow.Index).ThenBy(Function(c) c.OwningColumn.Index).ToArray
For x As Integer = 0 To cells.Count - 1
Dim cell As DataGridViewCell = cells(x)
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(startX, startY, cell.Size.Width, cell.Size.Height))
e.Graphics.DrawString(cell.Value.ToString, DataGridView1.Font, Brushes.Black, New Rectangle(startX, startY, cell.Size.Width, cell.Size.Height), sf)
If x < cells.Count - 1 AndAlso cells(x + 1).OwningRow Is cells(x).OwningRow Then
startX += cell.Size.Width
End If
If x < cells.Count - 1 AndAlso cells(x + 1).OwningRow IsNot cells(x).OwningRow Then
startX = 50
startY += cell.Size.Height
End If
Next
End Sub
'Added 8th May 2013 above
End Class