Condividi tramite


Procedura: estendere lo schema di stampa e creare nuove classi di sistema di stampa

Aggiornamento: novembre 2007

Se nell'applicazione in uso è necessario gestire dispositivi di stampa speciali con caratteristiche non rappresentate nelle classi PrintSystemObject, PrintQueue, PrintCapabilities e PrintTicket esistenti, è possibile derivare nuove classi in base all'ereditarietà, creare versioni estese delle classi PrintCapabilities e PrintTicket ed eventualmente estendere l'oggetto Print Schema. In questo articolo vengono descritte le fasi principali di un progetto di questo tipo e viene illustrato uno dei molti metodi che consentono di estendere le principali classi gestite.

Si consiglia di leggere il presente articolo insieme alla documentazione completa relativa a Print Schema. La lettura di questo articolo presuppone una conoscenza di base del concetto di schema e dei documenti PrintTicket e PrintCapabilities.

Di seguito vengono elencate le diverse sezioni dell'articolo.

Esempio

Nel progetto di esempio presentato in questo articolo non vengono fornite tutte le informazioni necessarie per compilare ed eseguire un'applicazione, ma viene fornito un quadro dei principali passaggi che è necessario eseguire per estendere le funzionalità degli spazi dei nomi System.Printing e System.Printing.IndexedProperties ai dispositivi di stampa le cui funzionalità non sono supportate in modo esplicito negli spazi dei nomi indicati. Gli esempi di codice vengono forniti solo nel caso in cui siano necessarie informazioni dettagliate concrete.

Inoltre, gli esempi di codice non includono necessariamente le tecniche per procedure di programmazione ottimali o il codice protetto. Qualsiasi argomento non strettamente pertinente all'oggetto dell'articolo viene omesso.

Infine, l'articolo si rivolge principalmente agli sviluppatori di applicazioni piuttosto che agli sviluppatori dei driver dei dispositivi. Per questo motivo, l'attenzione maggiore è rivolta alla scrittura di oggetti PrintTicket piuttosto che di oggetti PrintCapabilities.

Derivazione di una nuova classe per ereditarietà

Il primo passaggio consiste nel derivare una classe dalla classe PrintQueue, allo scopo di rappresentare il dispositivo. Nell'esempio di codice descritto di seguito viene derivata una classe BrailleEmbosser. Il braille è un linguaggio che può essere letto dai non vedenti in quanto i simboli sono costituiti da puntini in rilievo rispetto alla superficie del foglio, che possono essere percepiti al tatto con la punta delle dita. Una goffratrice braille è una semplice stampante di testi braille. Alcuni driver per goffratrici braille sono in grado di convertire il linguaggio braille standard in braille di grado 3, denominato anche Braille 3, ossia una versione di braille che consente di risparmiare spazio grazie all'utilizzo di contrazioni e abbreviazioni. Nell'esempio viene fornita una proprietà per rappresentare questa funzionalità.

Spesso può essere necessario inoltre eseguire l'overload di alcuni metodi e proprietà ereditati. Per informazioni dettagliate, vedere la sezione Overload ed estensione di proprietà e metodi di seguito.

class BrailleEmbosser : PrintQueue
{
   public BrailleEmbosser(PrintServer ps, String s, PrintSystemDesiredAccess access) : base(ps, s, access)
   {
      // Optionally, include here code to set non-inherited fields.
   }

   // other constructor declarations omitted

   private Boolean isBraille3Enabled;

   public Boolean IsBraile3Enabled
   {
      get { return isBraille3Enabled; }
      set { isBraille3Enabled = value; }
   }

   // remainder of class definition omitted
}

Verifica della presenza della definizione delle funzionalità del dispositivo nello schema di stampa

Sebbene le classi PrintTicket e PrintCapabilities dispongano di proprietà che rappresentano le funzionalità più comuni delle stampanti, esistono molte altre funzionalità definite nella specifica Print Schema Public Keywords che non sono riflesse in modo esplicito in tali classi. Per un elenco delle funzionalità comuni, vedere le proprietà della classe PrintCapabilities. Per verificare se le funzionalità speciali del dispositivo sono definite all'interno di questa classe, consultare la specifica. Di particolare utilità risulta l'utilizzo del modello della specifica per tutte le funzionalità incluse nella specifica stessa: infatti, un modello e una terminologia comuni consentono l'utilizzo dei documenti XML PrintTicket creati per un determinato dispositivo anche da parte di un'altra stampante. È possibile che quest'ultima sia stata realizzata da un produttore diverso o addirittura progettata dopo la creazione iniziale del documento PrintTicket. È possibile incorporare i PrintTicket nei documenti stessi, in modo che la modalità di stampa e la formattazione definite dall'autore vengano mantenute quando il documento viene distribuito a utenti con stampanti diverse.

Nella parte restante di questo articolo le funzionalità supportate in modo esplicito dalle classi PrintTicket e PrintCapabilities saranno definite "funzionalità comuni". Invece, le funzionalità definite nella specifica Print Schema Public Keywords, ma che non sono supportate in modo esplicito dalle due classi, saranno denominate "funzionalità definite". Infine, le funzionalità non definite nella specifica delle parole chiave pubbliche saranno denominate "funzionalità nuove".

È possibile inoltre che il dispositivo utilizzato presenti una funzionalità che corrisponde quasi perfettamente a una funzionalità definita, tranne che per una o più opzioni aggiuntive non riconosciute nella specifica Print Schema Public Keywords. L'oggetto Print Schema può essere esteso per gestire tali funzionalità in modo da sfruttare al meglio la definizione esistente. Per ulteriori informazioni sull'utilizzo di tale funzionalità, vedere la sezione Espansione delle funzionalità definite nello schema di seguito.

Creazione di tipi per la rappresentazione delle funzionalità del dispositivo

Le proprietà delle classi PrintTicket e PrintCapabilities che corrispondono alle funzionalità della stampante accettano tipi speciali, in genere enumerazioni che rappresentano una funzionalità e i relativi valori possibili. L'enumerazione Collation, ad esempio, è il tipo per la proprietà PrintTicket.Collation. È anche il tipo dei membri dell'insieme che corrisponde alla proprietà PrintCapabilities.CollationCapability del tipo.

Per creare delle classi per le funzionalità definite e le funzionalità nuove del dispositivo, utilizzare le classi esistenti come modelli. Nell'esempio di codice riportato di seguito viene dichiarata un'enumerazione BrailleGrade3, costruita sul modello dell'enumerazione Collation, poiché la conversione al grado 3 è analoga alla fascicolazione: tutte le stampanti devono supportare almeno un tipo di output (fascicolato o non fascicolato) in quanto si completano a vicenda. Alcune stampanti supportano entrambi i tipi di output. Le stampanti che supportano solo output fascicolati sono rare, tuttavia è opportuno tenere comunque in considerazione questa possibilità. Allo stesso modo, è possibile che alcune goffratrici supportino solo output di braille non convertiti oppure solo quelli convertiti (si tratta di un'eventualità, sebbene poco probabile) o entrambi. L'enumerazione BrailleGrade3 include un valore Unknown, come accade per l'enumerazione Collation: tale valore, infatti, consente di gestire le situazioni in cui in un'applicazione che genera documenti PrintTicket la funzionalità di fascicolazione è impostata su un valore non riconosciuto nella specifica Print Schema Public Keywords. Se nell'applicazione viene creato un oggetto PrintTicket quando si utilizza questo tipo di documento, la proprietà PrintTicket.Collation otterrà il valore Unknown. Questo valore non viene mai utilizzato per gli oggetti PrintCapabilities.

public enum BrailleGrade3 { Translated, Untranslated, Unknown } 

Non sempre le enumerazioni costituiscono il modo migliore per rappresentare una funzionalità. Talvolta è preferibile utilizzare una classe tipo riferimento, in particolare se la funzionalità presenta una struttura nidificata di elementi subordinati, ciascuno con un proprio valore. Ad esempio, la classe PageMediaSize include le proprietà Height e Width. La classe PageMediaSize rappresenta il tipo della proprietà PrintTicket.PageMediaSize. È anche il tipo dei membri dell'insieme che corrisponde al tipo della proprietà PrintCapabilities.PageMediaSizeCapability.

Estensione delle classi PrintCapabilities e PrintTicket

Sebbene le classi PrintTicket e PrintCapabilities non possano essere ereditate, è possibile estendere l'oggetto Print Schema affinché le funzionalità definite e quelle nuove siano riconosciute.

Estensione della classe PrintTicket

Per utilizzare la classe PrintTicket con il sistema esteso di funzionalità, attenersi alla seguente procedura. Di seguito vengono fornite le indicazioni dettagliate.

Procedura generale per l'estensione della classe PrintTicket

  1. Se il dispositivo presenta delle funzionalità nuove, creare una nuova classe per incapsularle. Per ulteriori informazioni, vedere Procedura per la creazione di una classe NewFeaturesPrintTicket.

  2. Se il dispositivo presenta delle funzionalità definite, creare una classe per incapsularle. Per ulteriori informazioni, vedere Procedura per la creazione di una classe DefineFeaturesPrintTicket.

  3. Creare una classe per rappresentare un intero PrintTicket. Tale classe svolgerà all'interno dell'applicazione il ruolo normalmente svolto dalla classe PrintTicket in assenza di funzionalità nuove o definite per il dispositivo. Per ulteriori informazioni, vedere Procedura per la creazione di una classe WholePrintTicket.

Procedura per la creazione di una classe NewFeaturesPrintTicket

  1. Se il dispositivo presenta delle funzionalità nuove, dichiarare una classe per incapsularle. Tale classe sarà denominata NewFeaturesPrintTicket.

  2. Assegnare alla nuova classe delle proprietà per rappresentare le nuove funzionalità del dispositivo. Di solito, ciascuna proprietà appartiene a un tipo creato dall'utente, in genere un'enumerazione. Vedere la sezione Creazione di tipi per la rappresentazione delle funzionalità del dispositivo riportata in precedenza.

  3. Assegnare alla nuova classe una proprietà aggiuntiva, che sarà denominata PrivateNamespace e che contiene un riferimento allo spazio dei nomi XML privato, nel quale sono definite le nuove funzionalità del dispositivo. Tale stringa sarà necessaria nella scrittura del markup XML nei documenti PrintCapabilities e PrintTicket. Vedere la sezione Lettura e scrittura dei flussi XML PrintCapabilities e PrintTicket di seguito.

  4. Assegnare alla classe due costruttori, che devono essere specificati in base al modello dei due costruttori per la classe PrintTicket. Uno dei costruttori non accetta parametri, mentre l'altro accetta un oggetto Stream con contenuto XML. Il flusso XML sarà un documento PrintTicket nel quale sono definite le funzionalità nuove, anziché quelle comuni. Vedere Print Schema-Related Technologies e PrintTicket Schema and Document Construction. I costruttori con parametro dovranno generare eccezioni sul modello del costruttore a un parametro della classe PrintTicket.

  5. Creare un metodo GetXmlStream e un metodo SaveTo per la classe. Utilizzare la parola chiave di accesso "interno" per entrambi. Questi metodi corrispondono alle funzionalità dei metodi PrintTicket di tali nomi, tranne per il fatto che elaboreranno i documenti PrintTicket che definiscono le funzionalità nuove anziché quelle comuni. Devono inoltre garantire l'esistenza, per i flussi prodotti, di una dichiarazione dello spazio dei nomi aggiuntiva (il valore della proprietà PrivateNamespace) nell'elemento <PrintTicket … > di apertura. Vedere la sezione Lettura e scrittura dei flussi XML PrintCapabilities e PrintTicket di seguito.

Procedura per la creazione di una classe DefinedFeaturesPrintTicket.

  • Se il dispositivo presenta delle funzionalità definite, dichiarare una classe per incapsularle. Tale classe sarà denominata DefinedFeaturesPrintTicket. Il metodo per la creazione di questa classe è analogo a quello descritto in precedenza per la classe NewFeaturesPrintTicket, con le seguenti eccezioni.

    • I nomi delle proprietà della classe devono essere identici al nome della funzionalità corrispondente nella specifica Print Schema Public Keywords.

    • Non creare una proprietà PrivateNamespace. Lo spazio dei nomi per le funzionalità definite corrisponde a quello utilizzato per le funzionalità comuni. Vedere Lettura e scrittura dei flussi XML PrintCapabilities e PrintTicket di seguito.

    • I metodi GetXmlStream e SaveTo non generano flussi con una dichiarazione dello spazio dei nomi aggiuntiva.

Procedura per la creazione di una classe WholePrintTicket

  1. Dichiarare una classe che rappresenterà un intero PrintTicket e che pertanto svolgerà, all'interno dell'applicazione, il ruolo normalmente svolto dalla classe PrintTicket in assenza di funzionalità nuove o definite per il dispositivo. Tale classe sarà denominata WholePrintTicket.

  2. Assegnare alla classe WholePrintTicket una proprietà di tipo PrintTicket, che verrà denominata CommonFeatures.

  3. Assegnare alla classe WholePrintTicket una o entrambe le proprietà aggiuntive indicate di seguito, a seconda che presenti funzionalità nuove, definite o entrambe.

    • Proprietà NewFeatures di tipo NewFeaturesPrintTicket.

    • Proprietà DefinedFeatures di tipo DefinedFeaturesPrintTicket.

  4. Assegnare alla classe WholePrintTicket due costruttori: uno che non accetta parametri, e l'altro che accetta un oggetto Stream con contenuto XML. Se il costruttore accetta un parametro, verranno eseguite le seguenti operazioni.

    1. Passaggio dell'oggetto Stream al costruttore per l'oggetto PrintTicket a cui fa riferimento la proprietà CommonFeatures. Tutti i markup dell'oggetto Stream che non riguardano le funzionalità comuni verranno ignorati.

    2. Passaggio dell'oggetto Stream al costruttore dell'oggetto NewFeaturesPrintTicket a cui fa riferimento la proprietà NewFeatures. Qualsiasi markup dell'oggetto Stream che non riguarda le funzionalità nuove sarà ignorato. Se è presente un markup di funzionalità nuova, l'oggetto Stream comincerà con <psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1" xmlns:spazio dei nomi-abbreviazione=spazio dei nomi-nome-completo>, dove spazio dei nomi-nome-completo rappresenta l'URL utilizzato per identificare lo schema che definisce le nuove funzionalità e spazio dei nomi-abbreviazione ne è l'abbreviazione. Per ulteriori informazioni, vedere Lettura e scrittura dei flussi XML PrintCapabilities e PrintTicket di seguito.

    3. Passaggio dell'oggetto Stream al costruttore dell'oggetto DefinedFeaturesPrintTicket a cui fa riferimento la proprietà DefinedFeatures. Tutti i markup dell'oggetto Stream che non riguardano le funzionalità definite verranno ignorati.

  5. Creazione di un metodo GetXmlStream e SaveTo per la classe. Questi metodi corrispondono alle funzionalità dei metodi PrintTicket di tali nomi e devono presentare le seguenti caratteristiche.

    • Ciascuno di tali metodi deve chiamare il metodo corrispondente dello stesso nome negli oggetti a cui fanno riferimento le proprietà CommonFeatures, DefinedFeatures (se presente) e NewFeatures (se presente).

    • Ogni metodo deve concatenare i flussi prodotti dalle chiamate descritte al precedente punto elenco. Tutti i tag, ad eccezione dell'ultimo tag di fine </PrintTicket> e del primo tag di inizio <PrintTicket … >, devono essere eliminati. A meno che non sia disponibile alcuna funzionalità nuova, il tag di inizio dovrà contenere la dichiarazione dello spazio dei nomi aggiuntiva (vedere il passaggio 4b). Per questo motivo, è necessario che il flusso delle nuove funzionalità (se presente) sia sempre il primo della concatenazione, dal momento che conterrà tale dichiarazione nel tag di inizio <PrintTicket … >.

    • Per eseguire la concatenazione, i metodi GetXmlStream e SaveTo della classe WholePrintTicket dovranno essere eseguiti dapprima internamente in un flusso temporaneo. In particolare, i contenuti delle tre diverse classi di ciascun metodo dovranno essere serializzati nel flusso temporaneo, quindi verranno effettuate le operazioni di concatenazione ed eliminazione (vedere il punto successivo) e infine il risultato della concatenazione verrà restituito nel flusso di output finale.

    • Dopo la concatenazione, utilizzando i metodi GetXmlStream e SaveTo della classe WholePrintTicket sarà necessario eliminare dal flusso le copie doppie e triple degli elementi, prima di restituire il flusso finale. Tali voci in copia doppia e tripla sono presenti nel flusso perché ciascuno dei tre oggetti, PrintTicket, NewFeaturesPrintTicket e DefinedFeaturesPrintTicket conserva tutto il documento PrintTicket originale utilizzato per creare l'oggetto, nonostante nelle relative proprietà sia esposto solo un sottoinsieme del documento.

    • È possibile evitare il passaggio dell'eliminazione descritto al precedente punto elenco, se il costruttore dell'oggetto WholePrintTicket(Stream) viene utilizzato per suddividere il flusso in ingresso in tre parti, creando flussi distinti per gli elementi markup comuni, nuovi e definiti. Ciascuno di questi flussi di dimensioni inferiori viene quindi passato al costruttore appropriato delle tre proprietà della classe WholePrintTicket. Questa tecnica richiede l'aggiunta di un tag </PrintTicket> di chiusura per ciascuno dei tre flussi. Al flusso delle proprietà CommonFeatures e DefinedFeatures deve essere aggiunto un tag di inizio analogo a quello riportato di seguito: <psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1">. Al tag di inizio per il costruttore della proprietà NewFeatures verrà aggiunto uno spazio dei nomi privato aggiuntivo come quello indicato di seguito: <psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1" xmlns:spazio dei nomi-abbreviazione=spazio dei nomi-nome-completo>, dove spazio dei nomi-nome-completo rappresenta l'URL utilizzato per identificare lo schema che definisce le nuove funzionalità e spazio dei nomi-abbreviazione ne è l'abbreviazione.

Nell'esempio di codice riportato di seguito è illustrata parte del risultato di questa procedura, se applicata alla goffratrice braille. Per esigenze di spazio e di semplicità, molte informazioni sono state omesse. Notare che la proprietà BrailleGrade3 è un tipo Nullable<T>. Pertanto, seguirà il modello delle proprietà di PrintTicket, ad esempio Collation. Nell'esempio si presuppone la presenza di funzionalità nuove e definite, sebbene queste ultime non vengano specificate nel dettaglio.

class NewFeaturesPrintTicket
{
    public NewFeaturesPrintTicket()
    {
        // Optionally, initialize fields. For example:
        privateNamespace = "http://www.AjaxEmbossers.com/schemas/deluxemodels/v.1.0";
    }

    public NewFeaturesPrintTicket(Stream printTicketDocument)
    {
    // Parse the stream and initialize fields representing features here.
    // Optionally, initialize other fields. For example:
    privateNamespace = "http://www.AjaxEmbossers.com/schemas/deluxemodels/v.1.0";
    }

    private Nullable<BrailleGrade3> brailleGrade3;
    public Nullable<BrailleGrade3> BrailleGrade3
    {
        get { return brailleGrade3; }
        set { brailleGrade3 = value;}
    }

    private String privateNamespace;
    public String PrivateNamespace
    {
        get { return privateNamespace; }
        set { privateNamespace = value; }
    }
}

class DefinedFeaturesPrintTicket
{
  // Details omitted. Use the NewFeaturesPrintTicket
  // as a model, but leave out the privateNamespace field
  // and property.
}

class WholePrintTicket
{
    public WholePrintTicket()
    {
        commonFeatures = new PrintTicket();
        newFeatures = new NewFeaturesPrintTicket();
        definedFeatures = new DefinedFeaturesPrintTicket();
    }

    public WholePrintTicket(Stream wholePrintTicket)
    {
         // Method 1: Pass the stream to the three constructors.
         // Be sure to reset the read-write position of the stream
         // to the beginning of the stream after each call to a 
         // constructor. 
         // commonFeatures = new PrintTicket(wholePrintTicket);
              // reset read-write head here
        // newFeatures = new NewFeaturesPrintTicket(wholePrintTicket);
              // reset read-write head here
        // definedFeatures = new DefinedFeaturesPrintTicket(wholePrintTicket);
              // reset read-write head here

        // Method 2: Parse the stream and split it into three streams. 
        // Then pass them to the constructors of the three properties. 
        // commonFeatures = new PrintTicket(commonFeaturesPrintTicketDocument);
        // newFeatures = new NewFeaturesPrintTicket(newFeaturesPrintTicketDocument);
        // definedFeatures = new DefinedFeaturesPrintTicket(definedFeaturesPrintTicketDocument);
    }

    private PrintTicket commonFeatures;
    public PrintTicket CommonFeatures
    {
        get { return commonFeatures; }
        set { commonFeatures = value;}
    }

    private PrintTicket newFeatures;
    public PrintTicket NewFeatures
    {   // Details omitted. See CommonFeatures above.}

    private PrintTicket definedFeatures;
    public PrintTicket DefinedFeatures
    {   // Details omitted. See CommonFeatures above.}
}

Estensione della classe PrintCapabilities

Per utilizzare la classe PrintCapabilities con il proprio dispositivo, è necessario estenderla mediante una procedura analoga a quella eseguita per la classe PrintTicket. Dal momento che è possibile utilizzare come modello l'estensione della classe PrintTicket, di seguito vengono forniti solo dei brevi cenni generali.

  • Creare tre nuove classi, una per incapsulare le funzionalità nuove (NewFeaturesPrintCapabilities), una per incapsulare le funzionalità definite (DefinedFeaturesPrintCapabilities) e una per rappresentare un intero documento PrintCapabilities (WholePrintCapabilities).

  • I tipi delle proprietà delle prime due nuove classi saranno in genere ReadOnlyCollection<T>. Utilizzare le proprietà esistenti della classe PrintCapabilities, ad esempio CollationCapability, come modelli.

  • Inoltre, attenendosi al modello della classe PrintCapabilities esistente, i nomi delle proprietà dovranno terminare con la parola "Capability"; ad esempio, BrailleGrade3Capability.

  • La classe NewFeaturesPrintCapabilities disporrà di una proprietà PrivateNamespace identica a quella creata per NewFeaturesPrintTicket.

  • Nessuna delle classi disporrà di metodi diversi da quelli ereditati dalla classe Object.

  • Ciascuna classe disporrà di un solo costruttore che accetta un parametro Stream. Tale oggetto Stream sarà un documento PrintCapabilities.

  • Il costruttore della classe DefinedFeaturesPrintCapabilities deve confermare che il parametro Stream ricevuto è conforme all'oggetto Print Schema Framework prima di utilizzarlo per inizializzare le proprietà. A tal fine, è consigliabile passare il parametro Stream prima al costruttore della classe PrintCapabilities. Se non vengono generate eccezioni, il flusso è valido.

  • Il costruttore della classe NewFeaturesPrintCapabilities deve confermare che il parametro Stream ricevuto è conforme allo spazio dei nomi privato prima di utilizzarlo per inizializzare le proprietà.

  • Entrambi i costruttori delle classi DefinedFeaturesPrintCapabilities e NewFeaturesPrintCapabilities genereranno eccezioni sul modello del costruttore PrintCapabilities esistente.

  • La classe WholePrintCapabilities disporrà delle proprietà CommonFeatures, DefinedFeatures e NewFeatures, i cui tipi saranno, rispettivamente, PrintCapabilities, DefinedFeaturesPrintCapabilities e NewFeaturesPrintCapabilties. Ciascuno sarà costruito sul modello delle proprietà della classe WholePrintTicket.

  • Il costruttore della classe WholePrintCapabilities accetterà un solo parametro Stream, che rappresenta un intero documento PrintCapabilities. Il costruttore deve passare l'intero parametro Stream di input a tutti e tre i costruttori per le relative proprietà dei membri. Dal momento che la classe WholePrintCapabilities non dispone di alcun metodo per esportare le impostazioni nel formato XML (ad esempio i metodi GetXmlStream e SaveTo della classe WholePrintTicket), l'esistenza di markup in copia doppia e tripla all'interno delle tre proprietà non crea problemi.

Per ulteriori informazioni, vedere PrintCapabilities Schema and Document Construction.

Lettura e scrittura dei flussi XML PrintCapabilities e PrintTicket

L'attività principale dei costruttori e dei metodi delle classi PrintTicket e PrintCapabilities esistenti e delle nuove classi create in precedenza nella sezione Estensione delle classi PrintCapabilities e PrintTicket consiste nella lettura, nell'analisi, nella scrittura e talvolta nella convalida di oggetti Stream il cui contenuto è un documento PrintTicket o un documento PrintCapabilities. È necessario avere una certa familiarità con i concetti di I/O di file di base e con i metodi di tali classi. Dal momento che il contenuto dei flussi è in formato XML, è opportuno inoltre acquisire familiarità con il supporto delle funzionalità di lettura e scrittura di dati XML descritto in Opzioni di elaborazione XML in .NET Framework. Se nell'applicazione vengono gestiti documenti XML Paper Specification (XPS), negli spazi dei nomi System.Windows.Xps, System.Windows.Xps.Packaging e System.Windows.Xps.Serialization saranno presenti le API progettate per la lettura e la scrittura di documenti XPS, inclusa la lettura e la scrittura di PrintTicket. Vedere anche PackageRelationship per informazioni sull'aggiunta di una relazione alla classe PrintTicket in un package.

Per gli esempi completi di un documento PrintTicket e di un documento PrintCapabilities, vedere PrintTicket Example e PrintCapabilities Document Example.

Di seguito viene fornito un esempio semplice di un documento PrintCapabilities in cui sono state omesse tutte le funzionalità del dispositivo tranne una. La funzionalità illustrata è DocumentCollate, vale a dire la funzionalità rappresentata dalle proprietà PrintCapabilities.CollationCapability e PrintTicket.Collation.

<psf:PrintCapabilities xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1">

   <!-- other features omitted --> 
   
   <psf:Feature name="psk:DocumentCollate">
        <psf:Property name="psf:SelectionType">
            <psf:Value xsi:type="xsd:QName">psk:PickOne</psf:Value>
        </psf:Property>
        <psf:Property name="psk:DisplayName">
            <psf:Value xsi:type="xsd:string">Collate Copies</psf:Value>
        </psf:Property>
        <psf:Option name="psk:Collated" constrained="psk:None">
            <psf:Property name="psk:DisplayName">
                <psf:Value xsi:type="xsd:string">Yes</psf:Value>
            </psf:Property>
        </psf:Option>
        <psf:Option name="psk:Uncollated" constrained="psk:None">
            <psf:Property name="psk:DisplayName">
                <psf:Value xsi:type="xsd:string">No</psf:Value>
            </psf:Property>
        </psf:Option>
    </psf:Feature>
                   
   <!-- other features omitted --> 
   
</PrintCapabilities>

Notare che sono elencate tutte le possibili opzioni della funzionalità (fascicolata o non fascicolata) e viene identificato lo stato di ciascuna di esse (ossia, se è vincolata o meno). In un documento PrintCapabilities completo viene identificato lo stato di tutte le opzioni di ciascuna funzionalità. Il documento costituisce quindi una sorta di snapshot della configurazione del dispositivo.

Di seguito viene fornito un esempio semplice di un documento PrintTicket con una sola funzionalità.

<psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1">
  
  <!-- other features omitted -->
  
  <psf:Feature name="psk:DocumentCollate">
    <psf:Option name="psk:Collated" />
  </psf:Feature>  
    
  <!-- other features omitted -->
  
</PrintTicket>

Notare che la struttura può essere ulteriormente semplificata, in quanto non è necessario specificare in modo esplicito lo stato di ciascuna opzione in un documento PrintTicket. È sufficiente indicare solo l'opzione richiesta.

La sintassi e la struttura della funzionalità vengono definite nell'elemento DocumentCollate mediante le sezioni Print Schema Framework e Print Schema Public Keywords. Quando si utilizzano delle funzionalità nuove, queste vengono definite in uno spazio dei nomi XML privato in uno schema supplementare. In genere quest'ultimo viene fornito dal produttore del dispositivo, da un'associazione commerciale o da un ente normativo no-profit, tuttavia è possibile anche crearlo autonomamente. Utilizzare le sezioni Print Schema Framework e Print Schema Public Keywords esistenti per apprendere la sintassi richiesta e per trovare i modelli su cui basare le proprie definizioni. Anche Microsoft ha creato un nuovo spazio dei nomi al fine di estendere il sistema di PrintCapabilities e PrintTicket al nuovo driver Microsoft XPS Document Writer (MXDW). Per informazioni dettagliate, vedere Impostazioni di configurazione di MXDW.

Supponendo che un'azienda fittizia di goffratrici Ajax abbia definito la funzionalità di conversione in braille di grado 3 in modo parallelo a quella creata da Microsoft per la fascicolazione del documento, sarà possibile osservare l'aspetto delle voci relative ai documenti PrintCapabilities e PrintTicket per quella determinata funzionalità. Notare che lo spazio dei nomi nel quale è definita la funzionalità deve essere dichiarato nei tag di inizio <PrintCapabilities … > e <PrintTicket … >.

Markup dei documenti PrintCapabilities

<psf:PrintCapabilities xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
           xmlns:ajax="http://www.AjaxEmbossers.com/schemas/deluxemodels" version="1">

   <!-- other features omitted --> 
   
   <psf:Feature name="ajax:BrailleGrade3Translation">
        <psf:Property name="psf:SelectionType">
            <psf:Value xsi:type="xsd:QName">psk:PickOne</psf:Value>
        </psf:Property>
        <psf:Property name="psk:DisplayName">
            <psf:Value xsi:type="xsd:string">Braille3 translation</psf:Value>
        </psf:Property>
        <psf:Option name="ajax:Translated" constrained="psk:None">
            <psf:Property name="psk:DisplayName">
                <psf:Value xsi:type="xsd:string">Yes</psf:Value>
            </psf:Property>
        </psf:Option>
        <psf:Option name="ajax:Untranslated" constrained="psk:None">
            <psf:Property name="psk:DisplayName">
                <psf:Value xsi:type="xsd:string">No</psf:Value>
            </psf:Property>
        </psf:Option>
    </psf:Feature>
                   
   <!-- other features omitted --> 
   
</PrintCapabilities>

Markup dei documenti PrintTicket

<psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
           xmlns:ajax="http://www.AjaxEmbossers.com/schemas/deluxemodels" version="1">
  
  <!-- other features omitted -->
  
  <psf:Feature name="ajax:BrailleGrade3Translation">
    <psf:Option name="ajax:Translated" />
  </psf:Feature>  
    
  <!-- other features omitted -->
  
</PrintTicket>

Per ulteriori informazioni sulla scrittura di documenti PrintTicket che gestiscono nuove funzionalità, vedere Creating a Device-Specific PrintTicket. Per informazioni più approfondite sulla creazione di documenti PrintTicket e PrintCapabilities, vedere le sezioni PrintCapabilities Schema and Document Construction e PrintTicket Schema and Document Construction della documentazione relativa allo schema di stampa.

Overload ed estensione di proprietà e metodi

I metodi delle classi che accettano un parametro PrintTicket oppure restituiscono un oggetto PrintTicket e che si desidera utilizzare con il sistema di funzionalità esteso, dovranno essere sostituiti con un metodo che utilizza la classe WholePrintTicket anziché PrintTicket. Analogamente, le proprietà di tipo PrintTicket che si desidera utilizzare devono essere sostituite con proprietà di tipo WholePrintTicket. Tale sostituzione deve essere applicata, con le opportune modifiche, anche alle classi PrintCapabilities e WholePrintCapabilities.

Quando la classe che ospita il metodo o la proprietà è ereditabile, è possibile derivare una classe ed eseguire l'overload del metodo o della proprietà per utilizzare la classe WholePrintTicket al posto di PrintTicket.

Se la classe di hosting non è ereditabile, sarà necessario estenderla mediante la procedura effettuata per le classi PrintTicket e PrintCapabilities, ossia creando una classe che include come membro la classe di hosting. Assegnare quindi ai metodi e alle proprietà della classe esterna gli stessi nomi dei metodi corrispondenti che presentano (o restituiscono) il parametro PrintTicket o PrintCapabilities. In genere, la funzionalità della classe esterna deve corrispondere a quella della classe interna con lo stesso nome, ma utilizzerà i parametri WholePrintTicket o WholePrintCapabilities anziché PrintTicket o PrintCapabilities. Inoltre, per le proprietà della classe interna di tipo PrintTicket o PrintCapabilities, creare una proprietà corrispondente con lo stesso nome nella classe esterna che utilizza il parametro WholePrintTicket o WholePrintCapabilities.

I metodi più importanti di cui eseguire l'overload saranno probabilmente le due versioni di MergeAndValidatePrintTicket Per la classe BrailleEmbosser (vedere la sezione precedente Derivazione di una nuova classe per ereditarietà) saranno necessarie delle sostituzioni che utilizzano i parametri WholePrintTicket e aggiungono la logica per la convalida dei ticket con le nuove funzionalità, utilizzando lo schema dello spazio dei nomi privato. È possibile eseguire l'overload dei metodi esistenti oppure crearne di nuovi con nome MergeAndValidateWholePrintTicket.

ConvertDevModeToPrintTicket e Clone sono due metodi che restituiscono un oggetto PrintTicket. In .NET Framework sono disponibili altri 15 metodi, senza contare gli overload, che accettano un parametro PrintTicket e 19 proprietà di tipo PrintTicket. Tuttavia è probabile che le applicazioni ne utilizzino solo un numero ridotto, pertanto il carico di lavoro non sarà elevato come potrebbe apparire da queste cifre. Invece, l'unico metodo che restituisce un oggetto PrintCapabilities è GetPrintCapabilities e non esistono proprietà di tipo PrintCapabilities.

Espansione delle funzionalità definite nello schema

Le funzionalità del tutto nuove non rappresentano l'unico caso in cui è richiesta un'estensione dell'oggetto Print Schema. È possibile anche che un dispositivo offra nuove opzioni non definite per una funzionalità nota e definita. Dal momento che per le nuove opzioni non definite è necessario utilizzare uno spazio dei nomi privato proprio come nel caso delle funzionalità completamente nuove, è consigliabile considerare tali funzionalità estese alla stregua di quelle del tutto nuove (utilizzando tuttavia i nomi definiti nello schema per la funzionalità e quelli delle relative opzioni che sono già state definite) e inserirle negli oggetti NewFeaturesPrintTicket e NewFeaturesPrintCapabilities. La discussione relativa a tutti i dettagli necessari per implementare questo tipo di estensione dello schema esula dagli argomenti di questo articolo, ma è importante notare che l'operazione di concatenazione che deve essere eseguita dai metodi WholePrintTicket.GetXmlStream e WholePrintTicket.SaveAs diventa in questo caso più complicata.

Estensione dello spazio dei nomi System.Printing.IndexedProperties

Se si desidera utilizzare le API nello spazio dei nomi System.Printing.IndexedProperties, sarà necessario derivare una nuova classe dalla classe PrintProperty. Tale operazione deve essere eseguita nel caso in cui una proprietà che è stata creata per la classe derivata da PrintQueue presenti un tipo non rappresentato da nessuna delle classi esistenti nello spazio dei nomi System.Printing.IndexedProperties. Per alcuni esempi delle operazioni eseguibili con lo spazio dei nomi System.Printing.IndexedProperties, vedere Procedura: duplicare una stampante e Procedura: ottenere le proprietà di un oggetto di sistema di stampa senza ricorrere alla riflessione

L'operazione di derivazione non è necessaria nell'esempio riportato in precedenza, in quanto l'unica proprietà che è stata aggiunta alla classe BrailleEmbosser è IsBraile3Enabled, vale a dire un valore Boolean. La classe System.Printing.IndexedProperties.PrintBooleanProperty esiste già.

Vedere anche

Attività

Procedura: duplicare una stampante

Procedura: ottenere le proprietà di un oggetto di sistema di stampa senza ricorrere alla riflessione

Concetti

Opzioni di elaborazione XML in .NET Framework

Documenti di Windows Presentation Foundation

Cenni preliminari sulla stampa

Riferimenti

System.Printing

System.Printing.IndexedProperties

System.Printing.Interop

System.Windows.Xps

System.Windows.Xps.Packaging

System.Windows.Xps.Serialization

GetPrintCapabilities

PackageRelationship

PrintCapabilities

PrintQueue

PrintSystemObject

PrintTicket

Impostazioni di configurazione di MXDW

Altre risorse

Schema di stampa

Framework dello schema di stampa

Creazione di una classe PrintTicket specifica del dispositivo

Tecnologie correlate allo schema di stampa

Creazione di schemi e documenti PrintTicket

Esempio di PrintTicket

Esempio di documenti PrintCapabilities

Creazione di schemi e documenti PrintCapabilities

Parole chiave pubbliche dello schema di stampa

Esempi relativi alla stampa

Processo di scrittura documenti XPS Microsoft