Поделиться через


Практическое руководство. Расширение схемы печати и создание новых классов системы печати

Обновлен: Ноябрь 2007

Если приложение должно работать со специальными печатающими устройствами, которые имеют характеристики, не отражаемые существующими классами PrintSystemObject, PrintQueue, PrintCapabilities и PrintTicket, возможно, потребуется создание новых производных классов путем наследования, создание расширенных версий классов PrintCapabilities и PrintTicket и, возможно, также расширение Print Schema. В этом разделе описываются основные части такого проекта; но в нем описывается лишь один из многих способов расширения соответствующих управляемых классов.

Рекомендуется ознакомление с этой статьей в сочетании с подробной документацией Print Schema. В данной статье предполагается наличие хотя бы общего представления о том, что такое схема и документы PrintTicket и PrintCapabilities.

Данный раздел состоит из следующих подразделов.

  • Создание нового производного класса путем наследования

  • Проверка того, определены ли уже возможности устройства в схеме печати

  • Создание типов для представления возможностей устройства

  • Расширение классов PrintCapabilities и PrintTicket

    • Расширение класса PrintTicket

    • Расширение класса PrintCapabilities

  • Чтение и запись XML потоков PrintCapabilities и PrintTicket

  • Перегрузка и расширение свойств и методов

  • Расширение определенных схемой возможностей

  • Расширение пространства имен System.Printing.IndexedProperties

Пример

Приведенный в этом разделе пример проекта не предоставляет всех сведений, необходимых для компиляции и запуска приложения. Он предназначен для приведения лишь основных шагов, необходимых для расширения функциональных возможностей пространств имен System.Printing и System.Printing.IndexedProperties для устройств печати, имеющих функциональные возможности, поддерживаемые в этих пространствах имен неявно. Примеры кода предоставляются только в тех случаях, когда нужны конкретные подробности.

Кроме того, примеры кода необязательно выполнены с применением хорошего стиля программирования или безопасного кода. Никакие материалы, непосредственно относящиеся к теме раздела, не были опущены.

Наконец, данный раздел предназначен главным образом для разработчиков приложений, а не для разработчиков драйверов устройств. По этой причине акцент сделан на написании объектов PrintTicket, а не объектов PrintCapabilities.

Создание нового производного класса путем наследования

Начать следует с создания производного класса, представляющего устройство из класса PrintQueue. В следующем примере кода класс BrailleEmbosser является производным. Шрифт Брайля создан для невидящих людей, его символы состоят из рельефных "точек" на бумаге и их можно "читать" пальцами. BrailleEmbosser является просто принтером, печатающим шрифтом Брайля. Некоторые драйверы для BrailleEmbosser способны переводить обычный шрифт Брайля в шрифт Брайля 3 Уровня, иногда называемый шрифтом Брайля 3, то есть уплотненную версию шрифта Брайля, использующую много сокращений и аббревиатур. В примере предоставлено свойство для представления этой функции.

Часто будет возникать необходимость перегрузки некоторых унаследованных свойств и методов. Дополнительные сведения см. ниже в подразделе Перегрузка и расширение свойств и методов.

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
}

Проверка того, определены ли уже возможности устройства в схеме печати

Классы PrintTicket и PrintCapabilities обладают свойствами, представляющими наиболее распространенные возможности принтера, но существует множество дополнительных возможностей, определенных в спецификации Print Schema Public Keywords, которые неявно отражаются в этих классах. (Список общих возможностей см. в свойствах класса PrintCapabilities.) Следует прочитать спецификацию, чтобы проверить, определены ли в ней специальные возможности устройства. Для любой возможности, включенной в спецификацию, существует преимущество в использовании модели спецификации: общая модель и терминология позволяет использовать документы PrintTicket XML, созданные на одном устройстве, на другом устройстве. (Второе устройство может быть разработано другим производителем, и поэтому оно может быть разработано после создания документа PrintTicket.) Настройки печати (Print tickets) могут быть встроены в сами документы, так что авторский замысел печати и форматирования может передаваться вместе с документом и распространяться для людей с разными принтерами.

В дальнейшем в этом разделе возможности, явно поддерживаемые классами PrintTicket и PrintCapabilities, будут называться "общие возможности". А те, которые определены в спецификации Print Schema Public Keywords, но поддерживаются обоими классами неявно, будут называться "определенные возможности". Возможности, не определенные в спецификации общих ключевых слов, будут называться "новые возможности".

Также вероятно, что устройство имеет возможности, почти в точности совпадающие с определенными, но имеет один или несколько дополнительных параметров, не описанных в спецификации Print Schema Public Keywords. Схема Print Schema может быть расширена для обработки этих возможностей таким образом, чтобы максимально расширить существующее определение. Дополнительные сведения о работе с такими возможностями см. ниже в подразделе Расширение определенных схемой возможностей.

Создание типов для представления возможностей устройства

Свойства PrintTicket и PrintCapabilities, соответствующие возможностям принтера, принимают специальные типы, обычно перечислимые, которые представляют возможность и ее возможные значения. Например, перечисление Collation является типом свойства PrintTicket.Collation. Это также тип членов коллекции, являющейся типом свойства PrintCapabilities.CollationCapability.

Используя эти классы в качестве моделей, можно создавать классы для определенных и новых возможностей устройства. В следующем примере кода объявлено перечисление BrailleGrade3. Оно создается на модели перечисления Collation, поскольку перевод шрифта Брайля 3 Уровня аналогичен упорядочению. Любой принтер должен поддерживать по крайней мере один тип вывода (упорядоченного или нет), поскольку они являются взаимно исчерпывающими. Некоторые принтеры поддерживают оба типа. (Принтеры, поддерживающие только упорядоченный вывод, являются редкими, но эту возможность надо учитывать.) Также могут быть устройства, поддерживающие только непреобразованный вывод шрифта Брайля, только преобразованные выходные данные (маловероятно, но возможно) или оба типа. Перечисление BrailleGrade3 включает значение Unknown по той же причине, что и Collation — для обработки ситуаций, когда приложение, производящее документы настройки печати, задало возможности упорядочения значением, которое не распознается в спецификации Print Schema Public Keywords. Если приложение создает объект PrintTicket с помощью такого документа, то свойство PrintTicket.Collation получит значение Unknown. (Значение "Unknown" никогда не используется объектами PrintCapabilities.)

public enum BrailleGrade3 { Translated, Untranslated, Unknown } 

Перечисления не всегда являются лучшим способом представления возможности. Иногда лучше использовать класс ссылочного типа. В частности, это так, когда возможность имеет вложенную структуру из подчиненных частей, каждая из которых имеет свое собственное значение. Например, класс PageMediaSize имеет свойства Height и Width. PageMediaSize является типом свойства PrintTicket.PageMediaSize. Это также тип членов коллекции, являющейся типом свойства PrintCapabilities.PageMediaSizeCapability.

Расширение классов PrintCapabilities и PrintTicket

Несмотря на то, что классы PrintTicket и PrintCapabilities не могут наследоваться, можно расширить Print Schema для распознавания определенных и новых возможностей.

Расширение класса PrintTicket

Чтобы использовать класс PrintTicket в расширенной системе или возможностях, следует выполнить следующие шаги. Некоторые дополнительные сведения приведены ниже.

Высокоуровневая процедура расширения класса PrintTicket

  1. Если устройство имеет новые возможности, создайте новый класс для инкапсуляции новых возможностей. (Дополнительные сведения см. в подразделе Создание класса NewFeaturesPrintTicket.)

  2. Если устройство имеет определенные возможности, необходимо создать класс для инкапсуляции определенных возможностей. (Дополнительные сведения см. в подразделе Создание класса DefinedFeaturesPrintTicket.)

  3. Следует создать класс для представления всех настроек печати. Этот класс будет играть ту роль в приложении, которую играл бы класс PrintTicket, если бы устройство не имело определенных и новых возможностей. (Дополнительные сведения см. в подразделе Создание класса WholePrintTicket.)

Процедура создания класса NewFeaturesPrintTicket

  1. Если устройство имеет новые возможности, следует объявить класс для инкапсуляции этих возможностей. Назовем его NewFeaturesPrintTicket.

  2. Предоставьте новому классу свойства для представления новых возможностей устройства. Как правило, каждое свойство будет созданного типа, обычно перечислимого. См. Создание типов для представления возможностей устройства выше.

  3. Предоставьте новому классу дополнительное свойство, назовем его PrivateNamespace, которое будет хранить ссылку на закрытое пространство имен XML, определяющее новые возможности устройства. Эта строка понадобится при написании разметки XML для документов PrintCapabilities и PrintTicket. См. Чтение и запись XML потоков PrintCapabilities и PrintTicket ниже.

  4. Предоставьте классу два конструктора. Конструкторы должны быть смоделированы на двух конструкторах для PrintTicket. Один не принимает параметров, другой принимает объект Stream с XML содержимым. Поток XML будет документом PrintTicket, определяющим новые, а не общие возможности. (См. Print Schema-Related Technologies и PrintTicket Schema and Document Construction). Конструкторы с параметром должны вызывать исключения в шаблоне принимающего один параметр конструктора класса PrintTicket.

  5. Создайте методы GetXmlStream и SaveTo для класса. Используйте ключевое слово доступа "internal" для обоих. Они должны соответствовать функциональным возможностям методов PrintTicket этих имен, за исключением того, что они будут обрабатывать документы PrintTicket, которые определяют новые, а не общие возможности. Эти методы должны обеспечивать наличие у произведенных потоков объявления дополнительного пространства имен (значение свойства PrivateNamespace) в открывающем элементе <PrintTicket … >. См. Чтение и запись XML потоков PrintCapabilities и PrintTicket ниже.

Процедура создания класса DefinedFeaturesPrintTicket

  • Если устройство имеет определенные возможности, объявите класс для инкапсуляции этих возможностей. Назовем его DefinedFeaturesPrintTicket. Он должен быть сконструирован так же, как и NewFeaturesPrintTicket выше, со следующими отличиями.

    • Свойства класса должны иметь имена, которые соответствуют соответствующему имени возможности в спецификации Print Schema Public Keywords.

    • Не создавайте свойство PrivateNamespace. Пространство имен для определенных возможностей такое же, как и для общих возможностей. См. Чтение и запись XML потоков PrintCapabilities и PrintTicket ниже.

    • Методы GetXmlStream и SaveTo не производят потоки с объявлением дополнительного пространства имен.

Процедура создания класса WholePrintTicket

  1. Объявите класс, который будет представлять настройки печати целиком и, таким образом, будет играть ту роль в приложении, которую класс PrintTicket играл бы, если бы устройство не имело определенных и новых возможностей. Назовем его WholePrintTicket.

  2. Предоставьте WholePrintTicket свойство, назовем его CommonFeatures, типа PrintTicket.

  3. Предоставьте WholePrintTicket одно или оба следующие дополнительные свойства, в зависимости от того, есть ли новые возможности, определенные возможности или оба типа.

    • NewFeatures типа NewFeaturesPrintTicket.

    • DefinedFeatures типа DefinedFeaturesPrintTicket.

  4. Задайте WholePrintTicket два конструктора. Один не принимает параметров, другой принимает объект Stream с XML содержимым. Конструктор с параметром будет выполнять следующие действия.

    1. Передавать Stream конструктору объекта PrintTicket, на который ссылается свойство CommonFeatures. Этот конструктор будет игнорировать любую разметку в Stream, не относящуюся к общим возможностям.

    2. Передавать Stream конструктору объекта NewFeaturesPrintTicket, на который ссылается свойство NewFeatures. Этот конструктор будет игнорировать любую разметку в Stream, не относящуюся к новым возможностям. Если имеется разметка новых возможностей, то Stream начнется с <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:аббревиатура-пространства-имен=полное-имя-пространства-имен>, где полное-имя-пространства-имен является URL, используемым для идентификации схемы, определяющей новые возможности, а аббревиатура-пространства-имен — его сокращением. (Дополнительные сведения см. в разделе Чтение и запись XML потоков PrintCapabilities и PrintTicket ниже.).

    3. Передавать Stream конструктору объекта DefinedFeaturesPrintTicket, на который ссылается свойство DefinedFeatures. Этот конструктор будет игнорировать любую разметку в Stream, не относящуюся к определенным возможностям.

  5. Создайте методы GetXmlStream и SaveTo для класса. Они предназначены для соответствия функциональных возможностей методов PrintTicket этих имен. Они должны иметь следующие характеристики.

    • Каждый такой метод должен вызывать соответствующий метод с тем же именем в объектах, на которые ссылаются свойства CommonFeatures, DefinedFeatures (если такое есть) и NewFeatures (если такое есть).

    • Каждый метод должен объединять потоки, созданные вызовами, описанными в предыдущем случае. Разумеется, должно быть удалено все, кроме последнего закрывающего тега </PrintTicket> и первого открывающего тега <PrintTicket … >. Если нет новых возможностей, открывающий тег должен иметь дополнительное объявление пространства имен. (См. шаг 4b). По этой причине следует всегда считать создание потока новых возможностей (при наличии такового) первым в объединенном потоке, так как он уже будет иметь это объявление в своем открывающем теге <PrintTicket … >.

    • Чтобы выполнить конкатенацию, методам WholePrintTicketGetXmlStream и SaveTo должны будут первыми отработать во временном потоке. В частности, каждый из трех их различных классов сериализует свое содержимое во временный поток, выполнит действия конкатенации (и работу по очистке, см. далее) и затем выведет результаты конкатенации в итоговый выходной поток.

    • После конкатенации методам WholePrintTicketGetXmlStream и SaveTo нужно будет также удалить дубликаты и тройные копии элементов из потока до возврата конечного потока. В потоке будут двойные и тройные вхождения, так как каждый из трех объектов, PrintTicket, NewFeaturesPrintTicket и DefinedFeaturesPrintTicket, сохраняет весь исходный документ PrintTicket, который был использован для его построения, несмотря на то, что каждый из них представляет в своих свойствах только подмножество документа.

    • Можно избежать вышеописанного этапа очистки, если конструктор WholePrintTicket(Stream) (см. выше) разделит входящий поток на три части, создав отдельные потоки для общих, новых и определенных элементов разметки. Каждый из этих меньших потоков затем передается соответствующему конструктору трех свойств WholePrintTicket. Такой метод потребует добавления закрывающего тега </PrintTicket> для каждого из трех потоков. Для потока свойств DefinedFeatures и CommonFeatures добавьте открывающий тег: <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">. В открывающем теге конструктора свойства NewFeatures добавьте дополнительное закрытое пространство имен: <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:аббревиатура-пространства-имен=полное-имя-пространства-имен>, где полное-имя-пространства-имен является URL, используемым для идентификации схемы, определяющей новые возможности, а аббревиатура-пространства-имен — его сокращением).

В следующем примера кода иллюстрируется часть результата этой процедуры при применении к примеру с шрифтом Брайля. (Из соображений объема и простоты кода значительная часть была опущена.) Обратите внимание на то, что свойство BrailleGrade3 — типа Nullable<T>. Это соответствует шаблону свойств PrintTicket, например, Collation. В примере предполагается, что есть и новые, и определенные возможности, несмотря на то, что не задаются никакие конкретные определенные возможности.

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.}
}

Расширение класса PrintCapabilities

Чтобы использовать класс PrintCapabilities с устройством, необходимо расширить его подобно классу PrintTicket. Поскольку созданное расширение PrintTicket можно использовать как модель, здесь приведен только краткий обзор.

  • Создайте три новых класса, один для инкапсуляции новых возможностей (NewFeaturesPrintCapabilities), один для инкапсуляции определенных возможностей (DefinedFeaturesPrintCapabilities) и один для представления всего документа PrintCapabilities (WholePrintCapabilities).

  • Типы свойств первых двух новых классов, как правило, ReadOnlyCollection<T>. Используйте существующие свойства PrintCapabilities, например, CollationCapability, как модели.

  • Кроме того, следуя шаблону существующего класса PrintCapabilities, имена свойств должны иметь "Capability" в конце; например, BrailleGrade3Capability.

  • У класса NewFeaturesPrintCapabilities будет свойство PrivateNamespace, идентичное созданному для NewFeaturesPrintTicket.

  • У всех классов будут только методы, унаследованные от класса Object.

  • У каждого класса будет один конструктор, принимающий параметр Stream. Stream будет документом PrintCapabilities.

  • Конструктор DefinedFeaturesPrintCapabilities должен проверить, что переданный ему Stream соответствует Print Schema Framework, прежде чем он использует Stream для инициализации свойств. (Простой способ: сначала передать Stream конструктору PrintCapabilities. Если здесь не возникнет исключений, поток является допустимым).

  • Конструктор NewFeaturesPrintCapabilities должен проверить, что переданный ему Stream соответствует частному пространству имен, прежде чем он использует Stream для инициализации свойств.

  • И конструктор DefinedFeaturesPrintCapabilities, и конструктор NewFeaturesPrintCapabilities вызовет исключение шаблона существующего конструктора PrintCapabilities.

  • У класса WholePrintCapabilities будут свойства CommonFeatures, DefinedFeatures и NewFeatures. Типами этих свойств будут соответственно PrintCapabilities, DefinedFeaturesPrintCapabilities и NewFeaturesPrintCapabilties. Каждый из них будет создан по шаблону свойств WholePrintTicket.

  • Конструктор класса WholePrintCapabilities принимает один параметр Stream, представляющий весь документ PrintCapabilities. Конструктор должен передать весь входной Stream всем трем конструкторам его свойствам элемента. Поскольку у класса WholePrintCapabilities нет методов, экспортирующих его параметры в XML формат (например, методы WholePrintTicketGetXmlStream и SaveTo), тот факт, что в этих свойствах будет дублирующаяся разметка, безопасен.

Дополнительные сведения см. в разделе PrintCapabilities Schema and Document Construction.

Чтение и запись XML потоков PrintCapabilities и PrintTicket

Основная задача конструкторов и методов существующих классов PrintTicket и PrintCapabilities и новых классов, созданных выше в подразделе Расширение классов PrintCapabilities и PrintTicket — чтение, синтаксический анализ, запись и иногда проверка объектов Stream, содержимое которых является либо документом PrintTicket, либо документом PrintCapabilities. Необходимо ознакомиться с Основы файлового ввода-вывода и методами этих классов. Поскольку содержимое этих потоков — XML, следует также ознакомиться с поддержкой чтения и записи XML, описанной в разделе Режимы обработки XML в .NET Framework. Если приложение работает с документами Формат XPS (XML Paper Specification), существуют API-интерфейс в пространствах имен System.Windows.Xps, System.Windows.Xps.Packaging и System.Windows.Xps.Serialization, разработанные для чтения и записи в документах XPS, включая чтение и запись PrintTicket. См. также PackageRelationship для получения сведений о добавлении отношений к PrintTicket в пакете.

Полный пример документов PrintTicket и PrintCapabilities приведен в PrintTicket Example и PrintCapabilities Document Example.

Далее приведен простой пример документа PrintCapabilities, в котором приведена только одна возможность устройства. Приведенная возможность, DocumentCollate, предоставляется свойствами PrintCapabilities.CollationCapability и 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>

Следует обратить внимание на то, что указан каждый возможный параметр функции (упорядоченный и неупорядоченный) и его состояние определено (то есть, ограничен он или нет). В полном документе PrintCapabilities определено состояние каждого параметра каждой возможности, поэтому документ похож на снимок конфигурации устройства.

Ниже приведен простой пример документа 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" version="1">
  
  <!-- other features omitted -->
  
  <psf:Feature name="psk:DocumentCollate">
    <psf:Option name="psk:Collated" />
  </psf:Feature>  
    
  <!-- other features omitted -->
  
</PrintTicket>

Обратите внимание, что структура может быть довольно простой, так в документе PrintTicket не обязательно явно задавать состояние каждого параметра. Нужно только задавать требуемые параметры.

Синтаксис и структура возможности определяются в DocumentCollate с помощью Print Schema Framework и Print Schema Public Keywords. При работе с новыми возможностями работа будет происходить с возможностями, определенными в частном пространстве имен XML, заданном в добавочной схеме. Обычно это предоставляется изготовителем устройства, торговой ассоциацией или некоммерческой организацией; но можно создать и самостоятельно. Чтобы узнать необходимый синтаксис и найти модели, на которых можно построить определения следует использовать существующие Print Schema Framework и Print Schema Public Keywords. В Майкрософт было создано новое пространство имен, чтобы расширить систему PrintCapabilities и PrintTicket для нового драйвера Microsoft XPS Document Writer (MXDW). Дополнительные сведения см. в разделе Настройки конфигурации MXDW.

Если предположить, что вымышленная компания Ajax Embosser определила возможность преобразования BrailleGrade3 аналогично определенной Майкрософт возможности упорядочения документов, то увидим, как для возможности выглядят вхождения документов PrintCapabilities и PrintTicket. Следует обратить внимание на то, что пространство имен, в котором определена возможность, должно быть объявлено в открывающих тегах <PrintCapabilities … > и < PrintTicket … >.

Разметка документа 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>

Разметка документа 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>

Дополнительные сведения о написании документов PrintTicket, обрабатывающих новые возможности, см. в разделе Creating a Device-Specific PrintTicket. Подробная документация по созданию документов PrintTicket и PrintCapabilities представлена в подразделах PrintCapabilities Schema and Document Construction и PrintTicket Schema and Document Construction документации Схемы печати.

Перегрузка и расширение свойств и методов

Любой метод любого класса, принимающий параметр PrintTicket или возвращающий PrintTicket, который требуется использовать с расширенной системой возможностей, нужно будет заменить методом, использующим WholePrintTicket вместо PrintTicket. Аналогичным образом любые свойства типа PrintTicket, которые требуется использовать, нужно будет заменить свойствами типа WholePrintTicket. То же самое применяется, внеся необходимые изменения, к PrintCapabilities и WholePrintCapabilities.

Если класс, содержащий метод или свойство, является наследуемым, можно создать производный класс и перегрузить метод или свойство, чтобы использовать WholePrintTicket вместо PrintTicket.

Если содержащий класс не наследуется, необходимо расширить его аналогично вышеописанному расширению PrintTicket и PrintCapabilities: следует создать класс, членом которого будет являться содержащий класс. Затем необходимо задать внешнему классу методы и свойства с теми же именами, что и у соответствующих методов, имеющих (или возвращающих) параметры PrintTicket или PrintCapabilities. Как правило, внешний класс должен соответствовать по функциональности одноименному внутреннему классу, но он будет использовать параметры WholePrintCapabilities или WholePrintTicket вместо параметров PrintTicket или PrintCapabilities. Кроме того, для свойств типа PrintTicket или PrintCapabilities внутреннего класса следует создать соответствующее свойство с тем же именем во внешнем классе, использующем WholePrintTicket или WholePrintCapabilities.

Вероятно, наиболее важными методами, которые необходимо перегрузить, являются две версии MergeAndValidatePrintTicket Класс BrailleEmbosser (см. Создание нового производного класса путем наследования выше) потребует замен, использующих параметры WholePrintTicket и добавляющих логику для проверки настроек с новыми возможностями на соответствие схеме частного пространства имен. Можно также перегрузить существующие методы или создать новые, назвав их MergeAndValidateWholePrintTicket.

Двумя методами, возвращающими PrintTicket, являются ConvertDevModeToPrintTicket и Clone. В .NET Framework существует 15 других методов, не считая перегрузки, которые принимают параметр PrintTicket, и 19 свойств типа PrintTicket. Но вероятность того, что любое заданное приложение будет использовать большое их число, мала, поэтому рабочая нагрузка не будет так высока, как предложено этими методами и свойствами. К счастью, единственным методом, возвращающим объект PrintCapabilities, является GetPrintCapabilities, и нет свойств с типом PrintCapabilities.

Расширение определенных схемой возможностей

Полностью новые возможности не являются единственным случаем, в котором может потребоваться расширение Print Schema. Также возможно, что устройство предложит новые, не определенные параметры для известных, определенных возможностей. Поскольку частное пространство имен должно использоваться для новых неопределенных параметров так же, как оно должно использоваться для полностью новой возможности, то, возможно, проще обрабатывать такие расширенные возможности так же, как обрабатываются совершенно новые возможности (но используя определенные схемой имена для возможности и имена уже определенных параметров): разместив их в NewFeaturesPrintTicket и NewFeaturesPrintCapabilities. Обсуждение всех сведений, необходимых для реализации такого рода расширения схемы, выходит за пределы этой статьи, но следует обратить внимание на то, что работа по конкатенации, которая должна выполняться методами WholePrintTicket.GetXmlStream и WholePrintTicket.SaveAs, станет более сложной.

Расширение пространства имен System.Printing.IndexedProperties

Если есть необходимость воспользоваться преимуществами API-интерфейсы в пространстве имен System.Printing.IndexedProperties, может потребоваться создать новый класс, производный от PrintProperty. Это будет необходимо, если свойство, созданное для класса, производного от PrintQueue, имеет тип, не представленный ни одним из существующих классов в System.Printing.IndexedProperties. Примеры того, что можно сделать с пространством имен System.Printing.IndexedProperties, см. в разделах Практическое руководство. Клонирование принтера и Практическое руководство. Получение свойств объекта системы печати без отражения

Это необязательно в приведенном выше примере, поскольку единственным свойством, добавленным в класс BrailleEmbosser, является IsBraile3Enabled типа Boolean. Класс System.Printing.IndexedProperties.PrintBooleanProperty уже существует.

См. также

Задачи

Практическое руководство. Клонирование принтера

Практическое руководство. Получение свойств объекта системы печати без отражения

Основные понятия

Режимы обработки XML в .NET Framework

Документы в Windows Presentation Foundation

Общие сведения о печати

Ссылки

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

Параметры конфигурации MXDW

Другие ресурсы

Схема печати

Платформа схемы печати

Создание класса PrintTicket для конкретных устройств

Технологии, связанные со схемой печати

Схема PrintTicket и построение документов

Пример PrintTicket

Пример документа PrintCapabilities

Схема PrintCapabilities и построение документов

Общие ключевые слова схемы печати

Примеры печати

Средство для записи XPS-документов (Майкрософт)