I'm creating a simple WPF print dialog box to setup a label printer. I want it to be very simple and so I've choosen not to use the standard WPF printdialog.
All is going well accept for one thing, paper sizes.
Having selected a printer from one combobox, a second combobox is populated with the paper sizes available from that device. I'm currently using selectedPrinter.GetPrintCapabilities.PageMediaSizeCapab开发者_开发知识库ility and setting that as itemssource of the combobox.
However, my main issues with this are:
It seems to only get a subset of the available paper sizes (compared to the normal print dialog)
No way to add custom sizes since PageMediaSize is not inheritable and the constructor only allows you to use the PageMediaSizeName Enum
and
The only name I can display is the Enum text by binding the diplaypath to PageMediaSizeName, which is not particularly user friendly.
What I have also found is that if I dump selectedPrinter.GetPrintCapabilitiesAsXml to a file and look at that, I get everything I need; all the availble the paper sizes of the printer each with sizes and importantly a display name element.
My question is, am I missing something with selectedPrinter.GetPrintCapabilities or do I need to create a parser for selectedPrinter.GetPrintCapabilitiesAsXml and use this info instead?
I ended up creating my own PaperSize class (below) and I use this command
PaperSize.ParsePaperSizeXML(New Xml.XmlTextReader(selectPrinter.GetPrintCapabilitiesAsXml))
to retrieve the printer's available paper sizes as a bindinglist (selectedPrinter is a instance of the Printing.PrintQueue class)
Public Class PaperSize
Const FEATURENODE As String = "psf:Feature"
Const PAPERSIZEATTRIBUTE As String = "psk:PageMediaSize"
Const PAPEROPTIONNODE As String = "psf:Option"
Const SCOREDPROPERTYNODE As String = "psf:ScoredProperty"
Const WIDTHATTRIBUTE As String = "psk:MediaSizeWidth"
Const HEIGHTATTRIBUTE As String = "psk:MediaSizeHeight"
Const VALUENODE As String = "psf:Value"
Const PROPERTNODE As String = "psf:Property"
Const DISPLAYNAMEATTRIBUTE As String = "psk:DisplayName"
Const NAMEATTRIBUTE As String = "name"
Public Sub New()
End Sub
Public Sub New(ByVal PaperKey As String, ByVal PaperDisplayName As String)
DisplayName = PaperDisplayName
Width = Nothing
Height = Nothing
End Sub
Public Sub New(ByVal PaperKey As String, ByVal PaperDisplayName As String, ByVal PaperWidth As Double?, ByVal PaperHeight As Double?)
Key = PaperKey
DisplayName = PaperDisplayName
Width = PaperWidth
Height = PaperHeight
End Sub
Property Key As String
Property DisplayName As String
Property Width As Double?
Property Height As Double?
Public ReadOnly Property WidthInMM As Double?
Get
If Width.HasValue Then
Return WidthInInches * 25.4
Else
Return Nothing
End If
End Get
End Property
Public ReadOnly Property HeightInMM As Double?
Get
If Height.HasValue Then
Return HeightInInches * 25.4
Else
Return Nothing
End If
End Get
End Property
Public ReadOnly Property WidthInInches As Double?
Get
If Width.HasValue Then
Return Width / 96
Else
Return Nothing
End If
End Get
End Property
Public ReadOnly Property HeightInInches As Double?
Get
If Height.HasValue Then
Return Height / 96
Else
Return Nothing
End If
End Get
End Property
Public Shared Function ParsePaperSizeXML(ByVal XmlString As Xml.XmlReader) As ComponentModel.BindingList(Of PaperSize)
Dim lstPaperSizes As New ComponentModel.BindingList(Of PaperSize)
Try
While XmlString.Read()
If XmlString.NodeType = Xml.XmlNodeType.Element Then
Select Case XmlString.Name
Case FEATURENODE
If XmlString.AttributeCount = 1 Then
Select Case XmlString.GetAttribute(NAMEATTRIBUTE)
Case PAPERSIZEATTRIBUTE
lstPaperSizes = processAllPaperSizes(XmlString.ReadSubtree)
End Select
End If
End Select
End If
End While
Catch ex As Exception
Throw ex
End Try
Return lstPaperSizes
End Function
Private Shared Function processAllPaperSizes(ByVal PaperSizeXmlString As Xml.XmlReader) As ComponentModel.BindingList(Of PaperSize)
Dim lstPaperSizes As New ComponentModel.BindingList(Of PaperSize)
Dim currentKey As String
Try
While PaperSizeXmlString.Read()
If PaperSizeXmlString.NodeType = Xml.XmlNodeType.Element Then
Select Case PaperSizeXmlString.Name
Case PAPEROPTIONNODE
currentKey = PaperSizeXmlString.GetAttribute(NAMEATTRIBUTE)
lstPaperSizes.Add(processPaperSize(currentKey, PaperSizeXmlString.ReadSubtree))
End Select
End If
End While
Catch ex As Exception
Throw ex
End Try
Return lstPaperSizes
End Function
Private Shared Function processPaperSize(ByVal currentPaperKey As String, ByVal PaperSizeXmlString As Xml.XmlReader) As PaperSize
Dim currentWidth, currentHeight As Double?
Dim currentName As String = String.Empty
Dim stringwidth, stringheight As String
Try
While PaperSizeXmlString.Read()
If PaperSizeXmlString.NodeType = Xml.XmlNodeType.Element Then
Select Case PaperSizeXmlString.Name
Case SCOREDPROPERTYNODE
If PaperSizeXmlString.AttributeCount = 1 Then
Select Case PaperSizeXmlString.GetAttribute(NAMEATTRIBUTE)
Case WIDTHATTRIBUTE
stringwidth = processPaperValue(PaperSizeXmlString.ReadSubtree)
If String.IsNullOrEmpty(stringwidth) Then
currentWidth = Nothing
Else
currentWidth = MasterWPFUtils.MMToDPI(CDbl(stringwidth)) / 1000
End If
Case HEIGHTATTRIBUTE
stringheight = processPaperValue(PaperSizeXmlString.ReadSubtree)
If String.IsNullOrEmpty(stringheight) Then
currentHeight = Nothing
Else
currentHeight = MasterWPFUtils.MMToDPI(CDbl(stringheight)) / 1000
End If
End Select
End If
Case PROPERTNODE
If PaperSizeXmlString.AttributeCount = 1 Then
Select Case PaperSizeXmlString.GetAttribute(NAMEATTRIBUTE)
Case DISPLAYNAMEATTRIBUTE
currentName = processPaperValue(PaperSizeXmlString.ReadSubtree)
End Select
End If
End Select
End If
End While
Return New PaperSize(currentPaperKey, currentName, currentWidth, currentHeight)
Catch ex As Exception
Throw ex
End Try
End Function
Private Shared Function processPaperValue(ByVal valueXmlString As Xml.XmlReader) As String
Try
While valueXmlString.Read()
If valueXmlString.NodeType = Xml.XmlNodeType.Element Then
Select Case valueXmlString.Name
Case VALUENODE
Return valueXmlString.ReadElementContentAsString.Trim
End Select
End If
End While
Catch ex As Exception
Throw ex
End Try
Return String.Empty
End Function
End Class
精彩评论