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

Important

Метаданные устройства являются устаревшими и будут удалены в будущем выпуске Windows. Сведения о замене этой функции см. в разделе Метаданные контейнера пакетов драйверов.

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

Версия C# параметров печати и пример уведомлений печати использует страницу Preferences.xaml для демонстрации пользовательского всплывающего элемента для расширенных параметров печати. Вспомогательный класс для печати используется для создания контекста устройства (IPrinterExtensionContext) и выполнения запросов к устройству. The PrinterHelperClass.cs file is in the DeviceAppForPrintersLibrary project and uses APIs defined in the PrinterExtensionLibrary project. Библиотека расширений принтера предоставляет удобный способ доступа к интерфейсам расширения принтера драйвера печати версии 4. Дополнительные сведения см. в обзоре библиотеки расширений принтера.

Note

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

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

Расширенные параметры печати — это функциональные возможности, предоставляемые принтером, когда пользователь хочет выбрать параметры печати, которые не предлагаются в окне печати. It is accessible through the More settings link in the Print window. Это не полноэкранный интерфейс, но отображается в всплывающем элементе управления, который является элементом управления для отображения упрощенного контекстного пользовательского интерфейса, который закрывается, когда пользователь щелкает или нажимает вне него.

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

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

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

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

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

  3. Tap the Devices charm

  4. Tap Print

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

  6. The Print window opens

  7. Click the More settings link on the Print window

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

    • The default flyout appears when no UWP device app for the printer is installed

    • A custom flyout appears when a UWP device app for the printer is installed

Примеры стандартных и настраиваемых всплывающих элементов для расширенных параметров печати.

Prerequisites

Прежде чем начать:

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

  2. Настройте компьютер разработки. See Getting started for info about downloading the tools and creating a developer account.

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

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

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

  6. If you're writing your app with C# or JavaScript, add the PrinterExtensionLibrary and DeviceAppForPrintersLibrary projects to your UWP device app solution. Вы можете найти каждый из этих проектов в параметрах печати и образце уведомлений о печати .

Note

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

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

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

You can add the print task settings extension on the Declarations tab of the Manifest Designer in Microsoft Visual Studio. Можно также вручную изменить XML-код манифеста пакета приложения с помощью редактора XML (текста). Right-click the Package.appxmanifest file in Solution Explorer for editing options.

This example shows the print task settings extension in the Extension element, as it appears in the app package manifest file, 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. Создание пользовательского интерфейса

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

Design guidelines

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

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

Flyout dimensions

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

Всплывающие измерения для расширенных параметров принтера.

Note

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

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

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

This example shows the title and icon, as defined in the VisualElements element, in the app package manifest file (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>

Best practices

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

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

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

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

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

Шаг 3: Выполнение активации

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

A UWP device app can determine that the activation is intended for advanced print settings (that someone just tapped More options on the print settings dialog) when the event argument's kind property is equal to Windows.ApplicationModel.Activation.ActivationKind.printTaskSettings.

Note

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

This example shows the activation event handler in the OnActivated method, as it appears in the Constants.cs file. Затем аргументы события будут приведены как Windows.ApplicationModel.Activation.PrintTaskSettingsActivatedEventArgs. Although the sample includes this code in the Constants.cs file, it's actually part of the App class that is also defined in the App.xaml.cs file.

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 , предоставляют свойства для доступа к принтеру и управления ими:

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

This example shows the LoadAdvancedPrintSettingsContext method, as it appears in the Constants.cs file.

public PrintTaskConfiguration Config;
public Object Context;

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

On the custom flyout page, Preferences.xaml.cs, a class named rootPage acts as a pointer to the MainPage class so that the print task extension context and the printer device context can be accessed from the flyout.

This example shows the pointer in a portion of Preferences class, from the Preferences.xaml.cs file. Скачайте пример параметров печати и уведомлений о печати , чтобы просмотреть полный код.

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

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

When the page constructor for Preferences.xaml.cs is called, objects are created for the print task extension context (a PrintTaskConfiguration object named configuration) and the printer device context (a PrintHelperClass object named printHelper).

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

This example shows the custom flyout page constructor, DisplaySettings, and other helper methods in the Preferences.xaml.cs file.

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. Сохранение параметров

When the user has finished setting advanced print settings, the Microsoft Store device app needs to save the changes before the user goes back to the Print window. To do that, the app needs to listen for when the user taps the Back button (from the custom flyout page). В этом случае SaveRequested активируется событие контекста расширения задачи печати ( configuration объект).

This example shows the event listener for SaveRequested, being added in the OnNavigatedTo event handler of the custom flyout, in the Preferences.xaml.cs file. When the SaveRequested event is triggered, the OnSaveRequested method will be invoked (that method is also in the Preferences.xaml.cs file).

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 использует контекст расширения принтера для проверки билета печати и сохранения конфигурации задачи печати.

Important

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

This example shows the OnSaveRequested method in the Preferences.xaml.cs file. 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);
       }
    }
    

Testing

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

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

    Note

    Чтобы использовать мастер разработки метаданных устройств, необходимо установить 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. From the Tools menu, select Enable Test Signing.

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

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

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

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

    Note

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

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

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

    3. In the Open dialog box, locate the device metadata package associated with your UWP device app. (It has a devicemetadata-ms file extension.)

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

    5. If your app is registering for printer notifications, fill out the Notification handlers box. In Event ID, enter the name of the print event handler. In Event Asset, enter the name of the file where that code resides.

    6. When you're done, click Next until you get to the Finish page.

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

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

Troubleshooting

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

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

  • Possible cause: Test signing is not turned on. Подробнее о включении см. в разделе "Отладка" этой темы.

  • Possible cause: The app is not querying for the right Package Family Name. Проверьте имя семейства пакетов в вашем коде. Open up package.appxmanifest in Visual Studio and make sure that the package family name you are querying for matches the one in the Packaging tab, in the Package Family Name field.

  • Possible cause: The device metadata is not associated with the Package Family Name. Используйте мастер создания метаданных устройства, чтобы открыть метаданные устройства и проверить имя семейства пакетов. Start the wizard from %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, by double-clicking DeviceMetadataWizard.exe.

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

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

  • Possible cause: In Windows 8, there is a known issue that within a flyout, UWP apps will be dismissed under the debugger. Отключите отладку после того, как вы знаете, что активация работает. Если необходимо выполнить отладку сохранения билета печати, подключите отладчик после активации.