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


Настройка параметров печати (приложения устройств UWP)

В Windows 8.1 приложения устройств UWP позволяют производителям принтеров настраивать всплывающие элементы, отображающие расширенные параметры печати. В этом разделе представлен всплывающий элемент расширенных параметров печати и показано, как версия C# параметров печати и пример уведомлений о печати заменяет всплывающий элемент по умолчанию пользовательским всплывающий элемент. Дополнительные сведения о приложениях устройств UWP см. в статье "Знакомство с приложениями устройств UWP".

Версия C# параметров печати и пример уведомлений печати использует страницу Preferences.xaml для демонстрации пользовательского всплывающего элемента для расширенных параметров печати. Вспомогательный класс печати используется для создания контекста устройства (IPrinterExtensionContext) и выполнения запросов устройства. Файл PrinterHelperClass.cs находится в проекте DeviceAppForPrintersLibrary и использует API, определенные в проекте PrinterExtensionLibrary. Библиотека расширений принтера предоставляет удобный способ доступа к интерфейсам расширения принтера драйвера печати версии 4. Дополнительные сведения см. в обзоре библиотеки расширений принтера.

Примечание.

Примеры кода, показанные в этом разделе, основаны на версии C# параметров печати и образца уведомлений о печати. Этот пример также доступен в JavaScript и C++. Обратите внимание, что поскольку C++ может напрямую получить доступ к COM, версия C++ примера не включает проекты библиотеки кода. Скачайте примеры, чтобы просмотреть последние версии кода.

Дополнительные параметры печати

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

Этот интерфейс можно использовать для выделения отличительных функций принтера, таких как возможность применения подложек на страницу документа, предложения безопасных параметров печати или улучшения изображения.

Если приложение устройства UWP не установлено для принтера, Windows предоставляет параметры печати по умолчанию. Если Windows обнаруживает, что приложение устройства UWP установлено для принтера и что приложение согласилось на windows.printTaskSettings расширение, ваше приложение заменяет интерфейс по умолчанию, предоставляемый Windows.

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

  1. Открытие приложения UWP, поддерживающее печать

  2. Доступ к шармам, прокрутив в правой части экрана (или с помощью клавиши с логотипом Windows + C)

  3. Коснитесь кнопки "Устройства"

  4. Коснитесь кнопки " Печать"

  5. Коснитесь принтера

  6. Откроется окно "Печать"

  7. Щелкните ссылку "Дополнительные параметры" в окне "Печать"

  8. Откроется всплывающее меню расширенных параметров печати

    • Всплывающее меню по умолчанию отображается при отсутствии приложения устройства UWP для принтера

    • Настраиваемый всплывающий элемент отображается при установке приложения устройства UWP для принтера

examples of the default and custom flyouts for advanced print settings.

Необходимые компоненты

Необходимые условия:

  1. Убедитесь, что принтер установлен с помощью драйвера печати версии 4. Дополнительные сведения см. в статье "Разработка драйверов печати версии 4".

  2. Настройте компьютер разработки. Сведения о скачивании средств и создании учетной записи разработчика см. в статье "Начало работы ".

  3. Свяжите приложение с магазином. Сведения об этом см. в статье "Создание приложения устройства UWP".

  4. Создайте метаданные устройства для принтера, который связывает его с приложением. Дополнительные сведения см. в статье "Создание метаданных устройства".

  5. Создайте пользовательский интерфейс для главной страницы приложения. Все приложения устройств UWP можно запустить с начального экрана, где они будут отображаться в полноэкранном режиме. Используйте интерфейс "Пуск", чтобы выделить продукт или службы таким образом, чтобы соответствовать определенным фирменной символике и функциям ваших устройств. Существуют специальные ограничения на тип элементов управления пользовательским интерфейсом, которые он может использовать. Чтобы приступить к разработке полноэкранного интерфейса, ознакомьтесь с принципами проектирования в Microsoft Store.

  6. Если вы пишете приложение с помощью C# или JavaScript, добавьте проекты PrinterExtensionLibrary и DeviceAppForPrintersLibrary в решение приложения устройства UWP. Вы можете найти каждый из этих проектов в параметрах печати и образце уведомлений о печати.

Примечание.

Так как C++ может получить доступ к COM напрямую, приложения C++ не требуют отдельной библиотеки для работы с контекстом устройства принтера на основе COM.

Шаг 1. Регистрация расширения

Чтобы Windows распознала, что приложение может предоставить настраиваемый всплывающий элемент для расширенных параметров печати, он должен зарегистрировать расширение параметров задачи печати. Это расширение объявляется в элементе Extension с атрибутом Category , равным значению windows.printTaskSettings. В примерах Executable C# и C++ для атрибута задано $targetnametoken$.exe значение, а EntryPoint атрибут имеет значение DeviceAppForPrinters.App.

Вы можете добавить расширение параметров задачи печати на вкладке "Объявления" конструктора манифестов в Microsoft Visual Studio. Можно также вручную изменить XML-код манифеста пакета приложения с помощью редактора XML (текста). Щелкните правой кнопкой мыши файл Package.appxmanifest в Обозреватель решений для параметров редактирования.

В этом примере показано расширение параметров задачи печати в элементе, как оно отображается в Extension файле манифеста пакета приложения Package.appxmanifest.

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
  <Identity Name="Microsoft.SDKSamples.DeviceAppForPrinters.CS" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="1.0.0.0" />
  <Properties>
    <DisplayName>Device App For Printers C# sample</DisplayName>
    <PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
    <Logo>Assets\storeLogo-sdk.png</Logo>
  </Properties>
  <Prerequisites>
    <OSMinVersion>6.3.0</OSMinVersion>
    <OSMaxVersionTested>6.3.0</OSMaxVersionTested>
  </Prerequisites>
  <Resources>
    <Resource Language="x-generate" />
  </Resources>
  <Applications>
    <Application Id="DeviceAppForPrinters" Executable="$targetnametoken$.exe" EntryPoint="DeviceAppForPrinters.App">
      <VisualElements DisplayName="Device App For Printers C# sample" Logo="Assets\squareTile-sdk.png" SmallLogo="Assets\smallTile-sdk.png" Description="DeviceAppForPrinters C# sample" ForegroundText="light" BackgroundColor="#00b2f0" ToastCapable="true">
<DefaultTile ShowName="allLogos" ShortName="App4PrinterCS" WideLogo="Assets\tile-sdk.png" />
<SplashScreen Image="Assets\splash-sdk.png" BackgroundColor="#00b2f0" />
      </VisualElements>
      <Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="BackgroundTask.PrintBackgroundTask">
  <BackgroundTasks>
    <Task Type="systemEvent" />
  </BackgroundTasks>
</Extension>
<Extension Category="windows.printTaskSettings" Executable="$targetnametoken$.exe" EntryPoint="DeviceAppForPrinters.App" />
      </Extensions>
    </Application>
  </Applications>
</Package>

Шаг 2. Создание пользовательского интерфейса

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

Рекомендации по проектированию

Важно ознакомиться с рекомендациями по всплывающему элементу приложения UWP перед созданием пользовательского всплывающего элемента. Рекомендации помогут убедиться, что всплывающее меню обеспечивает интуитивно понятный интерфейс, совместимый с другими приложениями UWP.

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

Всплывающие измерения

Всплывающий элемент, отображающий расширенные параметры печати, имеет ширину 646 пикселей и не менее 768 пикселей (фактическая высота зависит от разрешения экрана пользователя). Кнопка "Назад" в области заголовка всплывающего окна предоставляется Windows. Текст "Название приложения" — это название приложения из манифеста приложения. Область заголовка составляет 80 пикселей высокой, оставляя 688 пикселей для просматриваемой области пользовательского всплывающего элемента.

flyout dimensions for advanced printer settings.

Примечание.

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

Определение цвета заголовка приложения и значка

Заголовок, цвет фона, цвет текста и небольшой логотип пользовательского всплывающего элемента берется из VisualElements элемента в файле манифеста пакета приложения.

В этом примере показан заголовок и значок, как определено в элементе VisualElements , в файле манифеста пакета приложения (Package.appxmanifest).

      <VisualElements DisplayName="Device App For Printers C# sample" Logo="Assets\squareTile-sdk.png" SmallLogo="Assets\smallTile-sdk.png" Description="DeviceAppForPrinters C# sample" ForegroundText="light" BackgroundColor="#00b2f0" ToastCapable="true">
        <DefaultTile ShowName="allLogos" ShortName="App4PrinterCS" WideLogo="Assets\tile-sdk.png" />
        <SplashScreen Image="Assets\splash-sdk.png" BackgroundColor="#00b2f0" />
      </VisualElements>

Рекомендации

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

  • Оставайтесь простыми в взаимодействии. Избегайте много времени или сложных взаимодействий. В большинстве случаев действия, такие как настройка принтера, просмотр состояния, упорядочение рукописного ввода и устранение неполадок, лучше всего выполняются в интерфейсе "Пуск".

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

  • Не используйте световые всплывающие элементы. В интерфейсе печати уже используется светлое всплывающее меню увольнения. Включение другого элемента закрытия света в пользовательском всплывающем элементе может запутать пользователей.

  • Отключите ссылки, которые приводят пользователей к выводу из интерфейса печати. Когда пользователь печатает содержимое, необходимо выполнить действия, чтобы убедиться, что они остаются в контексте печати. Например, если у вашего приложения есть ссылки, которые приводят к другим областям приложения (например, на домашнюю страницу или страницу для приобретения рукописного ввода), их следует отключить, чтобы пользователь не оставил расширенные параметры печати случайно.

Шаг 3. Обработка активации

Если приложение объявило расширение параметров задачи печати, оно должно реализовать OnActivated метод для обработки события активации приложения. Активация приложения — это когда приложение может выбрать, какая страница запустится при запуске приложения. Для приложений, объявленных расширением параметров задачи печати, Windows передает контекст расширения задачи печати в аргументах события Активации: Windows.ApplicationModel.Activation.IActivatedEventArgs.

Приложение устройства UWP может определить, что активация предназначена для расширенных параметров печати (что кто-то просто коснулся дополнительных параметров в диалоговом окне параметров печати), когда свойство аргумента kind события равно Windows.ApplicationModel.Activation.ActivationKind.printTask Параметры.

Примечание.

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

В этом примере показан обработчик событий активации в методе OnActivated , как он отображается в файле Constants.cs . Затем аргументы события будут приведены как Windows.ApplicationModel.Activation.PrintTask Параметры ActivatedEventArgs. Хотя пример включает этот код в файл Constants.cs, он фактически является частью класса App, который также определен в файле App.xaml.cs.

partial class App : Application
{
    protected override void OnActivated(IActivatedEventArgs args)
    {
        if (args.Kind == ActivationKind.PrintTaskSettings)
        {
            Frame rootFrame = new Frame();
            if (null == Window.Current.Content)
            {
                rootFrame.Navigate(typeof(MainPage));
                Window.Current.Content = rootFrame;
            }
            Window.Current.Activate();

            MainPage mainPage = (MainPage)rootFrame.Content;

            // Load advanced printer preferences scenario
            mainPage.LoadAdvancedPrintSettingsContext((PrintTaskSettingsActivatedEventArgs)args);
        }
    }
}

Шаг 4. Параметры отображения

LoadAdvancedPrintSettingsContext При вызове метода контекст конфигурации задачи печати назначается переменным класса MainPage. Это позволит пользовательскому всплывающему элементу получить доступ к параметрам печати при запуске.

Аргументы событий, передаваемые методу LoadAdvancedPrintSettingsContext , предоставляют свойства для доступа к принтеру и управления ими:

  • Свойство args.configuration предоставляет объект типа Windows.Devices.Printers.Extensions.PrintTaskConfiguration. Этот объект предоставляет доступ к контексту расширения задачи печати, а также позволяет добавить обработчик событий для обновления билета на печать.
  • Свойство args.configuration.printerExtensionContext предоставляет объект типа Windows.Devices.Printers.Extensions.PrinterExtensionContext . Этот объект является указателем на интерфейсы PrinterExtensionLibrary для схемы печати, PrintTicket и сведений о очереди печати. Он будет иметь значение NULL, если интерфейсы не предоставляются. Дополнительные сведения см. в разделе "Библиотека расширений принтера".

В этом примере показан LoadAdvancedPrintSettingsContext метод, как он отображается в файле Constants.cs .

public PrintTaskConfiguration Config;
public Object Context;

public void LoadAdvancedPrintSettingsContext(PrintTaskSettingsActivatedEventArgs args)
{
    Config = args.Configuration;
    Context = Config.PrinterExtensionContext;
    LoadScenario(typeof(DeviceAppForPrinters.Preferences));
}

На пользовательской странице всплывающего элемента Preferences.xaml.cs класс, который называется rootPage указателем на класс MainPage, чтобы контекст расширения задачи печати и контекст устройства принтера можно получить из всплывающего меню.

В этом примере показан указатель на часть Preferences класса из файла Preferences.xaml.cs . Скачайте пример параметров печати и уведомлений о печати, чтобы просмотреть полный код.

public sealed partial class Preferences : SDKTemplate.Common.LayoutAwarePage
{
    // A pointer back to the main page.  
    MainPage rootPage = MainPage.Current;

    // To listen for save requests.
    PrintTaskConfiguration configuration;

    // To create the printer device context.
    Object printerExtensionContext;
    PrintHelperClass printHelper;

    // The features in this sample were chosen because they're available on a wide range of printer drivers.
    private string[] features = { "PageOrientation", "PageOutputColor", "PageMediaSize", "PageMediaType" };
    private string[] selections = { null, null, null, null };

    // . . .
    // . . .
    // . . .

При вызове конструктора страницы для Preferences.xaml.cs объекты создаются для контекста расширения задачи печати ( PrintTaskConfiguration объект с именем configurationобъекта) и контекста устройства принтера ( PrintHelperClass объект с именем printHelper).

После создания этих объектов контекст устройства принтера используется в методе DisplaySettings для загрузки TextBlocks и ComboBoxes. Обратите внимание, что в отличие от JavaScript изменения в выборе не запускаются в том же потоке, что и остальная часть приложения. Для последующего использования необходимо сохранить локальный кэш выбранных пользователей.

В этом примере показан пользовательский конструктор DisplaySettingsстраницы всплывающих элементов и другие вспомогательные методы в файле Preferences.xaml.cs .

public Preferences()
{
    this.InitializeComponent();

    configuration = rootPage.Config;
    printerExtensionContext = rootPage.Context;
    printHelper = new PrintHelperClass(printerExtensionContext);

    // Disable scenario navigation by hiding the scenario list UI elements
    ((UIElement)rootPage.FindName("Scenarios")).Visibility = Windows.UI.Xaml.Visibility.Collapsed;
    ((UIElement)rootPage.FindName("ScenarioListLabel")).Visibility = Windows.UI.Xaml.Visibility.Collapsed;
    ((UIElement)rootPage.FindName("DescriptionText")).Visibility = Windows.UI.Xaml.Visibility.Collapsed;

    DisplaySettings();
}


private void DisplaySettings(bool constraints=false)
{
    PrintOptions.Visibility = Windows.UI.Xaml.Visibility.Visible;
    WaitPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed;

    // Fill in the drop-down select controls for some common printing features.
    TextBlock[] featureLabels = { PageOrientationLabel, PageOutputColorLabel, PageMediaSizeLabel, PageMediaTypeLabel };
    ComboBox[] featureBoxes = { PageOrientationBox, PageOutputColorBox, PageMediaSizeBox, PageMediaTypeBox };

    for (int i = 0; i < features.Length; i++)
    {
        // Only display a feature if it exists
        featureLabels[i].Visibility = Windows.UI.Xaml.Visibility.Collapsed;
        featureBoxes[i].Visibility = Windows.UI.Xaml.Visibility.Collapsed;

        string feature = features[i];

        // Check whether the currently selected printer's capabilities include this feature.
        if (!printHelper.FeatureExists(feature))
        {
            continue;
        }

        // Fill in the labels so that they display the display name of each feature.
        featureLabels[i].Text = printHelper.GetFeatureDisplayName(feature);
        string[] index = printHelper.GetOptionInfo(feature, "Index");
        string[] displayName = printHelper.GetOptionInfo(feature, "DisplayName");
        string selectedOption = printHelper.GetSelectedOptionIndex(feature);

        // Unless specified, do not get constraints
        bool[] constrainedList = constraints ? printHelper.GetOptionConstraints(feature) : new bool[index.Length];

        // Populate the combo box with the options for the current feature.
        PopulateBox(featureBoxes[i], index, displayName, selectedOption, constrainedList);
        selections[i] = selectedOption;

        // Every time the selection for a feature changes, we update our local cached set of selections.
        featureBoxes[i].SelectionChanged += OnFeatureOptionsChanged;

        // Show existing features
        featureLabels[i].Visibility = Windows.UI.Xaml.Visibility.Visible;
        featureBoxes[i].Visibility = Windows.UI.Xaml.Visibility.Visible;
    }
}

void PopulateBox(ComboBox box, string[] index, string[] displayName, string selectedOption, bool[] constrainedList)
{
    // Clear the combobox of any options from previous UI refresh before repopulating it.
    box.SelectionChanged -= OnFeatureOptionsChanged;
    box.Items.Clear();
    // There should be only one displayName for each possible option.
    if (index.Length == displayName.Length)
    {
        for (int i = 0; i < index.Length; i++)
        {
            // Create a new DisplayItem so the user will see the friendly displayName instead of the index.
            ComboBoxItem newItem = new ComboBoxItem();
            newItem.Content = displayName[i];
            newItem.DataContext = index[i];
            newItem.Foreground = constrainedList[i] ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.Black);
            box.Items.Add(newItem);

            // Display current selected option as selected in the combo box.
            if (selectedOption == index[i])
            {
                box.SelectedIndex = i;
                box.Foreground = newItem.Foreground;
            }
        }
    }
}

private void OnFeatureOptionsChanged(object sender, SelectionChangedEventArgs args)
{
    ComboBox comboBox = sender as ComboBox;

    for (int i = 0; i < features.Length; i++)
    {
        if (features[i] + "Box" == comboBox.Name)
        {
            selections[i] = (comboBox.SelectedItem as ComboBoxItem).DataContext as string;
        }
    }
}

Шаг 5. Сохранение параметров

Когда пользователь завершит настройку расширенных параметров печати, приложение устройства Microsoft Store должно сохранить изменения, прежде чем пользователь вернется в окно печати . Для этого приложение должно прослушивать, когда пользователь нажимает кнопку "Назад " (с пользовательской всплывающей страницы). В этом случае SaveRequested активируется событие контекста расширения задачи печати ( configuration объект).

В этом примере показан прослушиватель SaveRequestedсобытий, добавляемый в OnNavigatedTo обработчик событий пользовательского всплывающего элемента в файле Preferences.xaml.cs . SaveRequested При активации OnSaveRequested события метод будет вызван (этот метод также находится в файле Preferences.xaml.cs).

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    if (null == configuration)
    {
        rootPage.NotifyUser("Configuration arguments cannot be null", NotifyType.ErrorMessage);
        return;
    }

    // Add an event listener for saverequested (the back button of the flyout is pressed).
    configuration.SaveRequested += OnSaveRequested;
}

В методе OnSaveRequested приложение сначала использует printHelper объект для задания выбранных в данный момент параметров для каждой функции в контексте расширения принтера. Затем он вызывает Save метод объекта request , переданного в качестве аргумента OnSaveRequested в метод. Метод Save из класса Windows.Devices.Printers.Extensions.PrintTaskConfigurationSaveRequest использует контекст расширения принтера для проверки билета печати и сохранения конфигурации задачи печати.

Важно!

Если билет печати недействителен каким-либо образом, Save метод вызывает исключение, которое должно обрабатывать приложение. Если приложение не обрабатывает исключение, поток останавливается, заставляя пользователя опустить всплывающий элемент и перезапустить поток печати.

В этом примере показан OnSaveRequested метод в файле Preferences.xaml.cs . SaveRequested Так как событие не вызывается в потоке пользовательского интерфейса, оно должно использовать Windows.UI.Core.CoreDispatcher для отправки сообщений в поток пользовательского интерфейса для отображения соответствующих сообщений при проверке и сохранении билета.

async private void OnSaveRequested(object sender, PrintTaskConfigurationSaveRequestedEventArgs args)
{
    if (null == printHelper || null == printerExtensionContext || null == args)
    {
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
        {
            rootPage.NotifyUser("onSaveRequested: args, printHelper, and context cannot be null", NotifyType.ErrorMessage);
        });
        return;
    }

    // Get the request object, which has the save method that allows saving updated print settings.
    PrintTaskConfigurationSaveRequest request = args.Request;

    if (null == request)
    {
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
        {
            rootPage.NotifyUser("onSaveRequested: request cannot be null", NotifyType.ErrorMessage);
        });
        return;
    }

    PrintTaskConfigurationSaveRequestedDeferral deferral = request.GetDeferral();

    // Two separate messages are dispatched to:
    // 1) put up a popup panel,
    // 2) set the each options to the print ticket and attempt to save it,
    // 3) tear down the popup panel if the print ticket could not be saved.
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        PrintOptions.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
        WaitPanel.Visibility = Windows.UI.Xaml.Visibility.Visible;
    });

    // Go through all the feature select elements, look up the selected
    // option name, and update the context
    // for each feature
    for (var i = 0; i < features.Length; i++)
    {
        // Set the feature's selected option in the context's print ticket.
        // The printerExtensionContext object is updated with each iteration of this loop
        printHelper.SetFeatureOption(features[i], selections[i]);
    }

    bool ticketSaved;
    try
    {
        // This save request will throw an exception if ticket validation fails.
        // When the exception is thrown, the app flyout will remain.
        // If you want the flyout to remain regardless of outcome, you can call
        // request.Cancel(). This should be used sparingly, however, as it could
        // disrupt the entire the print flow and will force the user to
        // light dismiss to restart the entire experience.
        request.Save(printerExtensionContext);

        if (configuration != null)
        {
            configuration.SaveRequested -= OnSaveRequested;
        }
        ticketSaved = true;
    }
    catch (Exception exp)
    {
        // Check if the HResult from the exception is from an invalid ticket, otherwise rethrow the exception
        if (exp.HResult.Equals(unchecked((int)0x8007000D))) // E_INVALID_DATA
        {
            ticketSaved = false;
        }
        else
        {
            throw;
        }
    }

    // If ticket isn't saved, refresh UI and notify user
    if (!ticketSaved)
    {
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
        {
            rootPage.NotifyUser("Failed to save the print ticket", NotifyType.ErrorMessage);
            DisplaySettings(true);
        });
    }
    deferral.Complete();
}

Сохранение параметров, требующих ввода пользователем

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

  1. Получите билет печати во время активации приложения. Активация приложения для параметров печати описана ранее на шаге 3. Обработка активации.

  2. Проверьте, указан ли параметр размера страницы. В приложении C# или JS вспомогательный класс печати может проверка для этого параметра. В приложении C++ вызовите QueryInterface в IPrintSchemaOption, чтобы получить IPrintSchemaPageMediaSizeOption.

    В этом примере показан метод в вспомогательном классе печати, который проверка, если указан параметр размера страницы.

    public bool ShouldShowCustomUI(string index)
    {
        if (null != index)
        {
            string feature = "PageMediaSize";
            int i = int.Parse(index);
            IPrintSchemaOption selectedOption = GetCachedFeatureOptions(feature)[i];
            if (selectedOption.Name.Equals("CustomMediaSize", StringComparison.CurrentCulture)
                || selectedOption.Name.Equals("PSCustomMediaSize", StringComparison.CurrentCulture))
            {
                return true;
            }
        }
        return false;
    }
    
  3. В пользовательском всплывающем элементе отображается пользовательский интерфейс, который запрашивает у пользователя высоту страницы и ширину, а также извлекает указанную пользователем высоту и ширину из IPrintSchemaPageMediaSizeOption.

    В этом примере показан метод пользовательского всплывающего элемента, который запрашивает пользователю высоту страницы и ширину.

    private void ShowCustomPageMediaSizeUI(string index, bool keepValue)
    {
        //Hide custom media size UI unless needed
        if (IsCustomSizeSelected(index))
        {
           if (keepValue && (!customWidth.Equals("")) && (!customHeight.Equals("")))
           {
                        CustomWidthBox.Text = customWidth;
                        CustomHeightBox.Text = customHeight;
           }
           else
           {
              // Use a helper function from the WinRT helper component
              CustomWidthBox.Text = printHelper.GetCustomWidth(index);
              CustomHeightBox.Text = printHelper.GetCustomHeight(index);
           }
           CustomUIPanel.Visibility = Windows.UI.Xaml.Visibility.Visible;
           CustomWidthBox.KeyDown += OnCustomValueEntered;
           CustomHeightBox.KeyDown += OnCustomValueEntered;
        }
        else
        {
           CustomUIPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
           CustomWidthBox.KeyDown -= OnCustomValueEntered;
           CustomHeightBox.KeyDown -= OnCustomValueEntered;
        }
    }
    
  4. IPrintSchemaPageMediaSizeOption Обновите объект с заданными пользователем значениями и убедитесь, что высота и ширина соответствуют заданным пользователем значениям.

    В этом примере используется вспомогательный метод для обновления IPrintSchemaPageMediaSizeOption объекта в вспомогательном классе принтера. Обработчик OnSaveRequested в пользовательском всплывающем элементе вызовет эту функцию, если он определяет, что запрошен параметр размера пользовательской страницы.

    public void SetCustomMediaSizeDimensions(string width, string height)
    {
      if ((null == width) && (null == height) && (null == Capabilities))
      {
                    return;
      }
      try
      {
                    CheckSizeValidity(width, height);
      }
      catch (FormatException e)
      {
                    throw new ArgumentException(e.Message);
      }
      catch (OverflowException e)
      {
                    throw new ArgumentException(e.Message);
      }
    
      // The context is retrieved during app activation.
      IPrintSchemaTicket ticket = context.Ticket;
    
      //
      // Input XML as Stream
      //
      XElement ticketRootXElement = null;
      using (Stream ticketReadStream = ticket.GetReadStream())
      {
         ticketRootXElement = XElement.Load(ticketReadStream);
      }
    
      XNamespace psfNs = PrintSchemaConstants.FrameworkNamespaceUri;
      XNamespace pskNs = PrintSchemaConstants.KeywordsNamespaceUri;
      string pskPrefix = ticketRootXElement.GetPrefixOfNamespace(pskNs);
    
      // Modify the MediaSizeHeight and MediaSizeWidth
      IEnumerable<XElement> parameterInitCollection =
        from c in ticketRootXElement.Elements(psfNs + "ParameterInit")
    
      select c;
    
      foreach (XElement parameterInit in parameterInitCollection)
      {
        if (0 == String.Compare((string)parameterInit.Attribute("name"), pskPrefix + ":PageMediaSizePSWidth"))
        {
          IEnumerable<XElement> valueCollection = from c in parameterInit.Elements(psfNs + "Value")
          select c;
          valueCollection.ElementAt(0).Value = width;
        }
    
         else if (0 == String.Compare((string)parameterInit.Attribute("name"), pskPrefix + ":PageMediaSizePSHeight"))
        {
          IEnumerable<XElement> valueCollection = from c in parameterInit.Elements(psfNs + "Value")
          select c;
          valueCollection.ElementAt(0).Value = height;
         }
      }
    
      //
      // Write XLinq changes back to DOM
      //
       using (Stream ticketWriteStream = ticket.GetWriteStream())
       {
         ticketRootXElement.Save(ticketWriteStream);
       }
    }
    

Тестирование

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

  • Для добавления в него сведений о приложении устройства требуется копия пакета метаданных устройства. Если у вас нет метаданных устройства, его можно создать с помощью мастера создания метаданных устройств, как описано в разделе "Создание метаданных устройства для приложения устройства UWP".

    Примечание.

    Чтобы использовать мастер разработки метаданных устройств, необходимо установить Microsoft Visual Studio Professional, Microsoft Visual Studio Ultimate или автономный пакет SDK для Windows 8.1, прежде чем выполнить действия, описанные в этом разделе. Установка Microsoft Visual Studio Express для Windows устанавливает версию пакета SDK, которая не включает мастер.

Следующие шаги по созданию приложения и установке метаданных устройства.

  1. Включите тестовую подпись.

    1. Запустите мастер разработки метаданных устройства из %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, дважды щелкнув DeviceMetadataWizard.exe

    2. В меню "Сервис" выберите "Включить подписывание тестов".

  2. Перезагрузите компьютер.

  3. Создайте решение, открыв файл решения (.sln). Нажмите клавишу F7 или перейдите к решению сборки> из верхнего меню после загрузки примера.

  4. Отключите и удалите принтер. Этот шаг необходим, чтобы Windows считывала обновленные метаданные устройства при следующем обнаружении устройства.

  5. Изменение и сохранение метаданных устройства. Чтобы связать приложение устройства с устройством, необходимо связать приложение устройства с устройством.

    Примечание.

    Если вы еще не создали метаданные устройства, см. статью "Создание метаданных устройства" для приложения устройства UWP.

    1. Если мастер разработки метаданных устройства еще не открыт, запустите его с %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, дважды щелкнув DeviceMetadataWizard.exe.

    2. Нажмите кнопку "Изменить метаданные устройства". Это позволит изменить существующий пакет метаданных устройства.

    3. В диалоговом окне "Открыть" найдите пакет метаданных устройства, связанный с приложением устройства UWP. (Он имеет расширение файла devicemetadata-ms .)

    4. На странице сведений о приложении устройства UWP введите сведения о приложении Microsoft Store в поле приложения устройства UWP. Щелкните импорт файла манифеста приложения UWP, чтобы автоматически ввести имя пакета, имя издателя и идентификатор приложения UWP.

    5. Если приложение регистрируется для уведомлений принтера, заполните поле обработчиков уведомлений. Введите имя обработчика событий печати в идентификаторе события. В ресурсе событий введите имя файла, в котором находится этот код.

    6. По завершении нажмите кнопку "Далее ", пока не перейдете на страницу "Готово ".

    7. На странице "Проверка пакета метаданных устройства" убедитесь, что все параметры правильны и выберите пакет метаданных устройства в хранилище метаданных на локальном компьютере проверка. Нажмите кнопку Сохранить.

  6. Повторно подключите принтер, чтобы Windows считывала обновленные метаданные устройства при подключении устройства.

Устранение неполадок

Проблема. Дополнительные параметры печати отображают всплывающее меню по умолчанию вместо пользовательского всплывающего элемента

Если всплывающее меню расширенных параметров печати отображает всплывающее меню по умолчанию вместо пользовательского всплывающего элемента, реализуемого приложением...

  • Возможная причина. Проверка подписывания не включена. Дополнительные сведения о включении см. в разделе "Отладка".

  • Возможная причина: приложение не запрашивает правильное имя семейства пакетов. Проверьте имя семейства пакетов в коде. Откройте package.appxmanifest в Visual Studio и убедитесь, что имя семейства пакетов, которое запрашивается на вкладке "Упаковка", в поле "Имя семейства пакетов".

  • Возможная причина: метаданные устройства не связаны с именем семейства пакетов. Используйте мастер создания метаданных устройства, чтобы открыть метаданные устройства и проверка имя семейства пакетов. Запустите мастер из %ProgramFiles(x86)%\Комплекты Windows\8.1\bin\x86, дважды щелкнув DeviceMetadataWizard.exe.

Проблема. Приложение запускается во всплывающем меню, а затем немедленно закрывается

Если настраиваемый всплывающий элемент для расширенных параметров печати исчезнет сразу после запуска...

  • Возможная причина. В Windows 8 существует известная проблема, которая в всплывающем элементе приложений UWP будет отклонена в отладчике. Отключите отладку после того, как вы знаете, что активация работает. Если необходимо выполнить отладку сохранения билета печати, подключите отладчик после активации.

Разработка драйверов печати версии 4

Интерфейсы расширения принтера (драйвер печати версии 4)

Двунаправленная связь

Начало работы с приложениями UWP

Создание приложения устройства UWP (пошаговое руководство)

Создание метаданных устройства для приложения устройства UWP (пошаговое руководство)