View Full Version : [VB.NET] Problema formato di stampa personalizzato
Buongiorno,
ho bisogno di effettuare la stampa su un formato personalizzato cioè il formato per un contocorrente e nell'evento load del form ho inserito questo:
Dim pSize As New PaperSize()
pSize.PaperName = "Conto Corrente"
pSize.Width = 326.8
pSize.Height = 433.1
PrintDocument1.PrinterSettings.DefaultPageSettings.PaperSize = pSize
effettuo l'anteprima di stampa e tutto funziona correttamente.
Addesso se io nel programma voglio cambiare stampante o voglio cambiare un margine di stampa allora utilizzo PageSetupDialog settato così:
PSDialog.PageSettings = New System.Drawing.Printing.PageSettings
PSDialog.AllowPaper = True
PSDialog.AllowOrientation = False
PSDialog.PrinterSettings = New System.Drawing.Printing.PrinterSettings
PSDialog.Document = documentoCC
PSDialog.ShowDialog()
La pagina si apre correttamente e funziona correttamente cioè se cambio la stampante la cambia se cambio i margini la cambia però il problema è il formato di stampa cioè se cambio margine o la stampante e successivamente faccio ok per apportare le modifiche si prende anche il formato che viene visualizzato tra i formati come faccio per far visualizzare il formato personalizzato Conto Corrente tra i Formati di Default della stampante?
Spero che qualcuno può aiutarmi grazie in anticipo a tutti :help:
Non ho ben chiaro cosa tu vuoi / non ti riesce di fare... :stordita:
Se per un certo job di stampa il formato è sempre quello ( il tuo "Conto Corrente" ) perchè permettere all'utente di modificarlo con una PageSetupDialog ? Non potresti semplicemente mandare in stampa il documento con le dimensioni personalizzate ?
Non ho ben chiaro cosa tu vuoi / non ti riesce di fare... :stordita:
Se per un certo job di stampa il formato è sempre quello ( il tuo "Conto Corrente" ) perchè permettere all'utente di modificarlo con una PageSetupDialog ? Non potresti semplicemente mandare in stampa il documento con le dimensioni personalizzate ?
Ciao Marco,
si hai perfettamente ragione posso mandare direttamente in stampa il documento con le impostazioni personalizzate però devo permettere anche all'utente di impostare i margini e di cambiare la stampante ecco perchè stavo pensado al pagesetupdialog.
Se far comparire il formato personalizzato tra i formati della pagesetupdialog (che cambiano da stampante a stampante) è impossibile oppure è qualcosa di complicato, stavo pensando di crearmi un form tipo quello di pagesetupdialog dove l'utente può impostare i margini e un pulsante che va a chiamare una printdialog così da impostare la stampante se serve cosa ne pensi?hai qualche altra idea?
grazie Marco :D
1. Anzitutto non ho ben capito il perchè del tuo codice... :confused: . Perchè nel secondo blocco fai :
PSDialog.PageSettings = New System.Drawing.Printing.PageSettings
...
PSDialog.PrinterSettings = New System.Drawing.Printing.PrinterSettings
2. Tutte le proprietà attinenti alla collection dei formati di stampa disponibili per ogni stampante sulla PageSetupDialog, some ad esempio PageSetupDialog.PrinterSettings.PaperSizes, sono ReadOnly, perciò con ogni probabilità non riuscirai mai ad infilarci il tuo formato personalizzato...
3. Alla fin fine, questa PageSetupDialog non è così indispensabile, e non è certo difficile da replicare. Puoi costruirti la "tua PageSetupDialog", molto più completa e flessibile, ad esempio filtrando e aggiungendo sulla Combo dei formati disponibili...
Scrivere codice pemettere di costruire oggetti molto più interessanti rispetto a soluzioni precucinate...
Ad esempio, per iniziare, puoi inserire sulla tua "PageSetupDialog", 3 Combo :
- cmb_printers
- cmb_formati
- cmb_alimentazioni
La dichiarazione del document è Private a livello di Form :
Private DOC As New Printing.PrintDocument
cmb_printers contiene l'elenco delle stampanti installate :
cmb_printers.DropDownStyle = ComboBoxStyle.DropDownList
cmb_printers.Items.Clear()
For Each printer As String In Printing.PrinterSettings.InstalledPrinters
cmb_printers.Items.Add(printer)
Next
cmb_printers.SelectedIndex = 0
Sul SelectedIndexChanged della cmb_printers vai a popolare le altre :
Private Sub cmb_printers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmb_printers.SelectedIndexChanged
DOC.PrinterSettings.PrinterName = cmb_printers.Text
'Formati disponibili per printer
cmb_formati.DropDownStyle = ComboBoxStyle.DropDownList
cmb_formati.Items.Clear()
For Each psz As Printing.PaperSize In DOC.PrinterSettings.PaperSizes
cmb_formati.Items.Add(psz.PaperName)
Next
cmb_formati.SelectedIndex = 0
'Alimentazioni disponibili per printer
cmb_alimentazioni.DropDownStyle = ComboBoxStyle.DropDownList
cmb_alimentazioni.Items.Clear()
For Each psc As Printing.PaperSource In DOC.PrinterSettings.PaperSources
cmb_alimentazioni.Items.Add(psc.SourceName)
Next
cmb_alimentazioni.SelectedIndex = 0
End Sub
Ogni azione sulla Form va ad aggiungere o modificare qualcosa su DOC, che è il vero elemento centrale di tutto, non le varie Dialog... ;)
Marco grazie veramente di tutto ora cerco di fare il tutto se ho qualche problema ti faccio sapere :D sei un grande!
Ciao Marco mi sono creato la mia PageSetupDialog personalizzata ciò inserito anche un pulsante proprietà al fianco della combobox stampanti che vorrei che al click si apre le proprietà della stampante (ancora non ci sono riuscito se mi puoi aiutare altrimenti non è importante) la cosa più importante è che al click di ok della mia PageSetupDialog come faccio ad impostare quel formato quella stampante alla mia pagina in modo che quando lancio la stampa prende quelle impostazioni?
Marco grazie per la disponibilità
Ciao Marco mi sono creato la mia PageSetupDialog personalizzata ciò inserito anche un pulsante proprietà al fianco della combobox stampanti che vorrei che al click si apre le proprietà della stampante (ancora non ci sono riuscito se mi puoi aiutare altrimenti non è importante) la cosa più importante è che al click di ok della mia PageSetupDialog come faccio ad impostare quel formato quella stampante alla mia pagina in modo che quando lancio la stampa prende quelle impostazioni?
Marco grazie per la disponibilità
- Proprietà stampante : si può fare direttamente con un certo giro di chiamate API. Ovviamente NON lo farei, fossi in te. Rischi di creare un secondo "binario parallelo" a ciò che già stai facendo con la tua PageSetupDialog custom, mettendo l'utente nella possibilità di cambiare impostazioni che vanno in conflitto con quelle definite a livello di PrintDocument... Non è una bella idea.
- Come già detto l'oggetto su cui focalizzare le azioni è il PrintDocument, ossia DOC, nel mio esempio. Il codice che avevi scritto va bene :
Dim pSize As New Printing.PaperSize
pSize.PaperName = "Conto Corrente"
pSize.Width = 326.8
pSize.Height = 433.1
DOC.DefaultPageSettings.PaperSize = pSize
Per i margini puoi evere 4 TextBox, esattamente come sulla PageSetupDialog, e impostarli sul DOC, una volta definiti :
DOC.DefaultPageSettings.Margins.Bottom = x
DOC.DefaultPageSettings.Margins.Left = y
DOC.DefaultPageSettings.Margins.Right = t
DOC.DefaultPageSettings.Margins.Top = z
In generale il concetto è che tu non "fai prendere alla stampante" il DOC, con tutte le sue impostazioni.
Al centro della scena non c'è la stampante, ed infatti non esiste un oggetto Printer, ma il PrintDocument.
Il percorso è al contrario. Prima fai una lista delle InstalledPrinters, e poi è DOC che semmai "si prende la stampante", come ho già scritto :
Private Sub cmb_printers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmb_printers.SelectedIndexChanged
DOC.PrinterSettings.PrinterName = cmb_printers.Text
...
...
...
La scelta della stampante la si fa per prima. Se l'utente cambia stampante, è ovvio che bisogna resettare tutte le proprietà di DOC fin qui impostate e ricominciare da capo, perchè ad esempio, il tipo di alimentazione fogli scelto per la stampante A può non essere supportato dalla stampante B, e così per il formato, e per mille altre impostazioni...
Spero di essermi spiegato.
Ciao MarcoGG ti sei spiegato perfettamente infatti funziona tutto alla perfezione vorrei chiederti un'ultimo consiglio riguardo i margini di stampa.
C'è la possibilità di impostare i margini di stampa come millimetri e non come centesimi di pollice?se no c'è qualche conversione già preimpostata?oppure devo farmi io la formula per convertire?
grazie ancora una volta :cool:
Ciao MarcoGG ti sei spiegato perfettamente infatti funziona tutto alla perfezione vorrei chiederti un'ultimo consiglio riguardo i margini di stampa.
C'è la possibilità di impostare i margini di stampa come millimetri e non come centesimi di pollice?se no c'è qualche conversione già preimpostata?oppure devo farmi io la formula per convertire?
grazie ancora una volta :cool:
Se richiede centesimi di pollice, è comunque cosa di facile soluzione :
Private Function CentesimiPollice(ByVal millimetri As Double) As Integer
Return millimetri * 100 / 25.4
End Function
VB pensa a restituire già il valore Integer con le dovute approssimazioni per eccesso o difetto... ;)
Grazie Marco sei un mito :cool:
Ciao Marco,
ho un problema con i margini il codice è:
doc.OriginAtMargins=true
DOC.DefaultPageSettings.Margins.Left = CentesimiPollice(sinistra.Text)
DOC.DefaultPageSettings.Margins.Left = CentesimiPollice(sopra.Text)
dove sulla textbox sinistra se ci scrivo 5 che per me sarebbe che il margine sinistro deve essere di 5 millimetri e sopra imposto 10 e deve essere dieci millimetri.
poi con msgbox(DOC.DefaultPageSettings.Margins.Left.tostring) vedo che il margine di sinistra è uguale a 20 e quello di sopra è uguale a 39.
nell'anteprima mi cambiano in base a come cambio la stampante e questo è il primo problema.
il secondo è che ho provato a fare una stampa con questi margini stampando 2 linee una che mi parte con Y=0 e l'altra con X=0 prendendo le misure con un righello il risultato è:
Margine sinistro=10 mm
Margine superiore=31 mm
non c'è una relazione di unità di misura tra il margine superiore e il sinistro non sono ne millimetri ne centesimi di pollice non ci sto capendo più niente :muro:
Spero che mi puoi aiutare :help:
Anzitutto bisogna capire COME stampi sul PrintDocument.
Nell'utilizzo standard bisogna usare l'evento .PrintPage di PrintDocument, nel mio esempio "DOC".
Non è vero che non c'è relazione tra le misure. Quando ad esempio si usa e.Graphics nell'evento PrintPage, le misure inserite nei vari Metodi Draw ( .DrawString, .DrawLine, ecc... ) vengono direttamente interpretate in centesimi di pollice.
Ti posto un semplice test di stampa che puoi provare con ogni stampante, e per capire cosa intendo per "uso corretto" ( o almeno, uno degli usi corretti ) del PrintDocument :
> Dichiarazioni :
Private WithEvents DOC As New Printing.PrintDocument
Private fontTesto1 As New Font("Arial", 14, FontStyle.Regular)
WithEvents per poter scrivere l'evento .PrintPage.
> pSize, margini e colore :
Dim pSize As New Printing.PaperSize
pSize.PaperName = "PROVA_A4"
pSize.Height = CentesimiPollice(297)
pSize.Width = CentesimiPollice(210)
DOC.DefaultPageSettings.PaperSize = pSize
'Margini
DOC.OriginAtMargins = True
DOC.DefaultPageSettings.Margins.Bottom = CentesimiPollice(txtmarginf.Text)
DOC.DefaultPageSettings.Margins.Left = CentesimiPollice(txtmargsn.Text)
DOC.DefaultPageSettings.Margins.Right = CentesimiPollice(txt_margdx.Text)
DOC.DefaultPageSettings.Margins.Top = CentesimiPollice(txt_margsup.Text)
'Colore / BN
If DOC.PrinterSettings.SupportsColor Then
DOC.DefaultPageSettings.Color = True
Else
DOC.DefaultPageSettings.Color = False
End If
La stampante di DOC è già stata scelta, col sistema illustrato in precedenza...
> Il PrintPage :
Private Sub DOC_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles DOC.PrintPage
Dim corniceX As Integer = DOC.DefaultPageSettings.PaperSize.Width - DOC.DefaultPageSettings.Margins.Right - DOC.DefaultPageSettings.Margins.Left
Dim corniceY As Integer = DOC.DefaultPageSettings.PaperSize.Height - DOC.DefaultPageSettings.Margins.Top - DOC.DefaultPageSettings.Margins.Bottom
e.Graphics.DrawLine(Pens.Red, 0, 0, corniceX, 0)
e.Graphics.DrawLine(Pens.Red, corniceX, 0, corniceX, corniceY)
e.Graphics.DrawLine(Pens.Red, 0, 0, 0, corniceY)
e.Graphics.DrawLine(Pens.Red, 0, corniceY, corniceX, corniceY)
For i As Integer = 1 To 5
e.Graphics.DrawString(i * 25 & " mm", fontTesto1, Brushes.Green, 0, i * 50)
e.Graphics.DrawLine(Pens.Green, 0, i * 50, CentesimiPollice(i * 25), i * 50)
Next
End Sub
> La solita Function di conversione :
Private Function CentesimiPollice(ByVal millimetri As Double) As Integer
Return millimetri * 100 / 25.4
End Function
A questo punto, con DOC.Print(), parte la stampa effettiva, e si ottiene un foglio A4 bianco, con un riquadro rosso coincidente con i margini. Al suo interno 5 righe verdi di lunghezze diverse e relative quote. Dopo la stampa puoi controllare che margini e righe hanno distanze e lunghezze corrette. ;)
Grazie Marco sei stato molto chiaro provo e se ho qualche problema ti faccio sapere grazie ancora ;)
Ciao Marco finalmente grazie a te funziona tutto alla perfezione ora volevo chiederti una cosa che ho guardato anche su msdn ma niente l'unico che mi può aiutare sei tu.
Allora io nella mia form ho due pulsanti uno "Anteprima" e l'altro "Stampa":
Private Sub stampa_cc()
'stampa del documento
documentoCC.Print()
If MsgBox("Conti Corrente stampato correttamente?", MsgBoxStyle.YesNo, "Avviso!") = MsgBoxResult.Yes Then
datacc()
visualizzacc()
End If
End Sub
datacc è una procedura che mi memorizza la data e visualizzacc mi aggiorna i dati visualizzati perchè io ho bisogno che al momento della stampa devo memorizzare la data in modo che so quando è stato stampato e questo funziona tutto alla perfezione.
il pulsante anteprima contiene:
Private Sub anteprimacc()
Anteprima.Document = documentoCC
Anteprima.ShowDialog()
End Sub
dove anteprima è un printpreviewdialog il mio problema è come faccio a sapere in visual basic che ho premuto il pulsante stampa della form anteprima?
ho provato ad utilizzare l'evento end_print del printdocument ma me la memorizza più volte quindi l'unica soluzione è intercettare la pressione del pulsante stampa spero che mi puoi aiutare grazie ancora Marco per la pasienza :help:
Semplice. Non usare la PrintPreviewDialog. Usa un PrintPreviewControl direttamente sulla tua Dialog personalizzata. Dovrai scrivere un po' di codice in più, ma avrai pieno controllo su tutto ciò che succede... ;)
Marco ho capito come con la pagesetupdialog ;) grazie ancora di tutto
CIao Marco,
ho un problema riguardo l'impostazione della pagina cioè l'alimentazione del foglio carico la combobox alimentazione (questo funziona bene):
For Each psc As Printing.PaperSource In main.documentoCC.PrinterSettings.PaperSources
cmbAlimentazioni.Items.Add(psc.SourceName)
Next
poi quando salvo i dati li salvo:
main.documentoCC.DefaultPageSettings.PaperSource.SourceName = cmbAlimentazioni.Text
se poi sul caricamento della form inserisco:
msgbox(main.documentoCC.DefaultPageSettings.PaperSource.SourceName)
vedo che mi stampa sempre l'alimentazione di default e non quella che ho selezionato nella combobox mentre per la stampante per il formato per i margini funziona tutto alla perfezione.
Grazie in anticipo :help:
se poi sul caricamento della form inserisco:
msgbox(main.documentoCC.DefaultPageSettings.PaperSource.SourceName)
vedo che mi stampa sempre l'alimentazione di default e non quella che ho selezionato nella combobox mentre per la stampante per il formato per i margini funziona tutto alla perfezione.
Grazie in anticipo :help:
Spiegati meglio. Sul caricamento di quale Form ? In ogni caso se l'assegnazione viene fatta tramite selezione da oggetti grafici come le Combo, non è mai una buona idea interrogarne il valore sul Load delle Form...
Ciao Marco,
allora ora ti spiego se l'impostazione pagina viene aperta per la prima volta mi visualizza la stampante predefinita con tutti i valori predefiniti altrimenti mi visualizza tutti i valori che ho impostato io per esempio:
stampante: Canon
Formato: A4
Alimentazione:Vassoio Superiore
Orientamento: Orizzontale
se io imposto questo poi se la vado a riaprire mi trovo:
stampante: Canon
Formato: A4
Alimentazione:Cassetto
Orientamento: Orizzontale
e trovo tutti i dati come gli ho impostati in precedenza solo alimentazione mi torna come quella predefinita della stampante. io invece vorrei che rimane quella che ho impostata
Spero di essere stato chiaro :D Grazie ancora
In effetti sembra ci sia un problema. Lo fa anche con la mia Canon Pixma...
Non so ancora se è legato solo ad alcune stampanti, o se dipenda da altro.
Se l'assegnazione dell'alimentatore viene fatta da SourceName :
Private Sub cmb_alimentazioni_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmb_alimentazioni.SelectedIndexChanged
DOC.DefaultPageSettings.PaperSource.SourceName = cmb_alimentazioni.Text
MsgBox(DOC.DefaultPageSettings.PaperSource.SourceName)
End Sub
l'impostazione di fatto non viene settata su DOC, anche se la procedura non restituisce eccezioni.
Se invece passo l'indice di PrinterSettings.PaperSources, restituito dalla selezione sulla Combo, tutto fila liscio :
Private Sub cmb_alimentazioni_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmb_alimentazioni.SelectedIndexChanged
DOC.DefaultPageSettings.PaperSource = DOC.PrinterSettings.PaperSources(cmb_alimentazioni.SelectedIndex)
MsgBox(DOC.DefaultPageSettings.PaperSource.SourceName)
End Sub
Sicuramente c'è un problema "silenzioso" nel passaggio diretto del SourceName, in ogni caso la seconda soluzione funziona. ;)
Grazie tante Marco sei un grande :D
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.