Freigeben über


Anpassen von Druckeinstellungen (UWP-Geräte-Apps)

In Windows 8.1 können Druckerhersteller mit UWP-Geräte-Apps das Flyout anpassen, das erweiterte Druckeinstellungen anzeigt. In diesem Thema wird das Flyout für erweiterte Druckeinstellungen vorgestellt und gezeigt, wie die C#-Version des Beispiels Druckeinstellungen und Druckbenachrichtigungen das Standard-Flyout durch ein benutzerdefiniertes Flyout ersetzt. Weitere Informationen zu UWP-Geräte-Apps im Allgemeinen finden Sie unter UWP-Geräte-Apps kennenlernen.

In der C#-Version der Druckeinstellungen und des Druckbenachrichtigungsbeispiels wird die Seite Preferences.xaml verwendet, um die Benutzeroberfläche eines benutzerdefinierten Flyouts für erweiterte Druckeinstellungen zu veranschaulichen. Eine Druckhilfsklasse wird verwendet, um einen Gerätekontext (IPrinterExtensionContext) zu erstellen und die Geräteabfragen durchzuführen. Die PrinterHelperClass.cs-Datei befindet sich im DeviceAppForPrintersLibrary-Projekt und verwendet APIs, die im PrinterExtensionLibrary-Projekt definiert sind. Die Druckererweiterungsbibliothek bietet eine bequeme Möglichkeit, auf die Druckererweiterungsschnittstellen des v4-Drucktreibers zuzugreifen. Weitere Informationen finden Sie in der Übersicht über die Druckererweiterungsbibliothek.

Hinweis

Die in diesem Thema gezeigten Codebeispiele basieren auf der C#-Version der Druckeinstellungen und des Druckbenachrichtigungsbeispiels . Dieses Beispiel ist auch in JavaScript und C++ verfügbar. Da C++ direkt auf COM zugreifen kann, enthält die C++-Version des Beispiels keine Codebibliotheksprojekte. Laden Sie die Beispiele herunter, um die neuesten Versionen des Codes anzuzeigen.

Erweiterte Druckeinstellungen

Bei den erweiterten Druckeinstellungen handelt es sich um die Funktionalität, die ein Drucker bietet, wenn ein Benutzer Druckeinstellungen auswählen möchte, die im Fenster „Drucken“ nicht angeboten werden. Der Zugriff erfolgt über den Link Weitere Einstellungen im Fenster "Drucken". Es handelt sich nicht um ein Vollbild-Erlebnis, sondern um die Anzeige in einem Flyout, einem Steuerelement zum Anzeigen einer kompakten, kontextbezogenen Benutzeroberfläche, das geschlossen wird, wenn ein Benutzer außerhalb davon klickt oder tippt.

Diese Oberfläche kann verwendet werden, um differenzierte Features für Ihren Drucker hervorzuheben, z. B. die Möglichkeit, Wasserzeichen auf eine Dokumentseite anzuwenden, sichere Druckoptionen oder Optionen zur Bilderweiterung anzubieten.

Wenn für einen Drucker keine UWP-Geräte-App installiert ist, stellt Windows standardmäßige Druckeinstellungen bereit. Wenn Windows erkennt, dass eine UWP-Geräte-App für Ihren Drucker installiert ist und dass die App die windows.printTaskSettings-Erweiterung aktiviert hat, ersetzt Ihre App die von Windows bereitgestellte Standarderfahrung.

So rufen Sie das Flyout für erweiterte Druckeinstellungen auf:

  1. Öffnen einer UWP-App, die das Drucken unterstützt

  2. Greifen Sie auf die Charms zu, indem Sie auf der rechten Seite des Bildschirms wischen (oder mithilfe der Windows-Logo-Taste + C)

  3. Tippen Sie auf den Charm Geräte

  4. Tippen Sie auf Drucken

  5. Tippen Sie auf einen Drucker

  6. Das Fenster Drucken wird geöffnet.

  7. Klicken Sie auf dem Weitere Einstellungen-Link im Fenster Drucken

  8. Das Flyout für erweiterte Druckeinstellungen wird geöffnet.

    • Das Standard-Flyout wird angezeigt, wenn keine UWP-Geräte-App für den Drucker installiert ist.

    • Ein benutzerdefiniertes Flyout wird angezeigt, wenn eine UWP-Geräte-App für den Drucker installiert wird.

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

Voraussetzungen

Bevor Sie beginnen:

  1. Stellen Sie sicher, dass Ihr Drucker mit einem v4-Drucktreiber installiert ist. Weitere Informationen finden Sie unter Entwickeln von v4-Druckertreibern.

  2. Richten Sie Ihren Entwicklungs-PC ein. Informationen zum Herunterladen der Tools und zum Erstellen eines Entwicklerkontos finden Sie unter Erste Schritte.

  3. Verknüpfen Sie Ihre App mit dem Store. Weitere Informationen hierzu finden Sie unter Erstellen einer UWP-Geräte-App .

  4. Erstellen Sie Gerätemetadaten für Ihren Drucker, der sie Ihrer App zuordnet. Weitere Informationen hierzu finden Sie in Erstellen von Gerätemetadaten .

  5. Erstellen Sie die Benutzeroberfläche für die Standard Seite Ihrer App. Alle UWP-Geräte-Apps können von "Start" gestartet werden, wo sie im Vollbildmodus angezeigt werden. Verwenden Sie die Startoberfläche, um Ihr Produkt oder Ihre Dienste auf eine Weise hervorzuheben, die den spezifischen Branding- und Features Ihrer Geräte entspricht. Es gibt keine besonderen Einschränkungen für den Typ der UI-Steuerelemente, die sie verwenden können. Informationen zu den ersten Schritten mit dem Design der Vollbildoberfläche finden Sie in den Microsoft Store-Designprinzipien.

  6. Wenn Sie Ihre App mit C# oder JavaScript schreiben, fügen Sie ihrer UWP-Geräte-App-Lösung die Projekte PrinterExtensionLibrary und DeviceAppForPrintersLibrary hinzu. Sie finden jedes dieser Projekte im Beispiel Druckeinstellungen und Druckbenachrichtigungen .

Hinweis

Da C++ direkt auf COM zugreifen kann, benötigen C++-Apps keine separate Bibliothek, um mit dem COM-basierten Druckergerätekontext zu arbeiten.

Schritt1: Die Erweiterung registrieren

Damit Windows erkennt, dass die App ein benutzerdefiniertes Flyout für erweiterte Druckeinstellungen bereitstellen kann, muss sie die Erweiterung für die Druckaufgabeneinstellungen registrieren. Diese Erweiterung wird in einem Extension Element deklariert, wobei ein Category Attribut auf einen Wert von windows.printTaskSettingsfestgelegt ist. In den C#- und C++-Beispielen wird das Executable Attribut festgelegt $targetnametoken$.exe , und das EntryPoint Attribut wird auf DeviceAppForPrinters.App.

Sie können die Erweiterung für Druckaufgabeneinstellungen auf der Registerkarte Deklarationen des Manifest-Designers in Microsoft Visual Studio hinzufügen. Sie können den XML-Code des App-Paketmanifests auch manuell mit dem XML-Editor (Text) bearbeiten. Klicken Sie mit der rechten Maustaste auf die Datei Package.appxmanifest im Solution Explorer, um Bearbeitungsoptionen anzuzeigen.

In diesem Beispiel wird die Erweiterung der Druckaufgabeneinstellungen im Extension Element dargestellt, wie sie in der App-Paketmanifestdatei Package.appxmanifest angezeigt wird.

<?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>

Schritt 2: Erstellen Sie die Benutzeroberfläche

Bevor Sie Ihre App erstellen, sollten Sie mit Ihren Designern und Ihrem Marketingteam zusammenarbeiten, um die Benutzererfahrung zu gestalten. Die Benutzererfahrung sollte die Markenaspekte Ihres Unternehmens widerspiegeln und Ihnen helfen, eine Verbindung zu Ihren Benutzern aufzubauen.

Entwurfsrichtlinien

Es ist wichtig, die Richtlinien für das UWP-App-Flyout zu überprüfen, bevor Sie Ihr benutzerdefiniertes Flyout entwerfen. Die Richtlinien tragen dazu bei, dass Ihr Flyout eine intuitive Benutzeroberfläche bietet, die mit anderen UWP-Apps konsistent ist.

Beachten Sie für die Standard Seite Ihrer App, dass Windows 8.1 mehrere Apps in verschiedenen Größen auf einem einzigen Monitor anzeigen kann. Weitere Informationen dazu, wie Ihre App zwischen Bildschirmgrößen, Fenstergrößen und Ausrichtungen ordnungsgemäß umbrechen kann, finden Sie in den folgenden Richtlinien.

Flyout-Abmessungen

Das Flyout, das erweiterte Druckeinstellungen anzeigt, ist 646 Pixel breit und mindestens 768 Pixel hoch (die tatsächliche Höhe hängt von der Auflösung des Bildschirms des Benutzers ab). Die Schaltfläche Zurück im Titelbereich des Flyouts wird von Windows bereitgestellt. Der Text App-Titel ist der App-Titel aus dem App-Manifest. Der Titelbereich ist 80 Pixel hoch und belässt 688 Pixel für den sichtbaren Bereich des benutzerdefinierten Flyouts.

flyout dimensions for advanced printer settings.

Hinweis

Wenn Ihr benutzerdefiniertes Flyout mehr als 688 Pixel hoch ist, kann der Benutzer wischen oder scrollen, um Teile des Flyouts anzuzeigen, die über oder unter dem sichtbaren Bereich liegen.

Definieren der App-Titelfarbe und des Symbols

Titel, Hintergrundfarbe, Textfarbe und das kleine Logo im benutzerdefinierten Flyout stammen aus dem VisualElements Element in der App-Paketmanifestdatei.

Dieses Beispiel zeigt den Titel und das Symbol, wie im VisualElements-Element definiert, in der Manifestdatei des App-Pakets (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>

Bewährte Methoden

  • Halten Sie das gleiche Aussehen und Verhalten. Richten Sie Ihr benutzerdefiniertes Flyout mit dem Design für Ihre Startseite (die Hauptseite Ihrer App) aus, einschließlich Elementen wie Schriftarten, Farben und Steuerelementen. Die App sollte den Benutzern vertraut sein, unabhängig davon, wo sie sie aufrufen.

  • Halten Sie Interaktionen einfach. Vermeiden Sie zeitaufwendige oder komplexe Interaktionen. In den meisten Fällen lassen sich Aktionen wie das Einrichten eines Druckers, das Anzeigen des Status, das Bestellen von Tinte und die Fehlerbehebung am besten im Start-Erlebnis durchführen.

  • Halten Sie die Navigation auf ein Minimum. Vermeiden Sie, dass Ihre Benutzer zwischen mehreren Seiten in Ihrem benutzerdefinierten Flyout hin und her navigieren. Verwenden Sie stattdessen vertikale Bildlauf- oder Inlinesteuerelemente, z. B. progressive Offenlegungssteuerelemente, Dropdowns und Inlinefehlermeldungen.

  • Verwenden Sie keine Flyouts zum einfachen Ausblenden. Das Druckerlebnis nutzt bereits ein leichtes Ausblenden-Flyout. Wenn Sie ein weiteres einfaches Schließen-Element in Ihr benutzerdefiniertes Flyout einschließen, können Sie Ihre Benutzer verwirren.

  • Deaktivieren Sie Links, die Benutzer von dem Druckerlebnis wegführen. Wenn ein Benutzer Inhalte druckt, sollten Sie Schritte ausführen, um sicherzustellen, dass er im Druckkontext wieder Standard wird. Wenn Ihre App beispielsweise über Links verfügt, die zu anderen Bereichen Ihrer App führen (z. B. zu einer Startseite oder zu einer Seite zum Kauf von Tinte), sollten Sie diese deaktivieren, damit der Benutzer die erweiterten Druckeinstellungen nicht versehentlich verlässt.

Schritt 3: Behandeln der Aktivierung

Wenn Ihre App die Erweiterung der Druckaufgabeneinstellungen deklariert hat, muss sie eine OnActivated Methode zum Behandeln des App-Aktivierungsereignisses implementieren. Die App-Aktivierung erfolgt, wenn Ihre App auswählen kann, welche Seite beim Starten der App gestartet wird. Für Apps, die die Erweiterung für die Druckaufgabeneinstellungen deklariert haben, übergibt Windows den Kontext der Druckaufgabenerweiterung in den Activated-Ereignisargumenten: Windows.ApplicationModel.Activation.IActivatedEventArgs.

Eine UWP-Geräte-App kann feststellen, dass die Aktivierung für erweiterte Druckeinstellungen gedacht ist (dass jemand gerade im Druckeinstellungsdialog auf Weitere Optionen getippt hat), wenn die Eigenschaft des Ereignisarguments gleich kind windows.ApplicationModel.Activation.ActivationKind.printTask ist.

Hinweis

Wenn der Benutzer die App sofort nach dem Start schließt, wird möglicherweise eine Ausnahme innerhalb des Aktivierungshandlers ausgelöst. Um dies zu vermeiden, stellen Sie sicher, dass der Aktivierungshandler effizient abgeschlossen ist und keine ressourcenintensive Verarbeitung erfolgt.

In diesem Beispiel wird der Aktivierungsereignishandler in der OnActivated Methode dargestellt, wie er in der Constants.cs-Datei angezeigt wird. Die Ereignisargumente werden dann als Windows.ApplicationModel.Activation.PrintTask Einstellungen ActivatedEventArgs umgeschaltet. Obwohl das Beispiel diesen Code in der Constants.cs-Datei enthält, ist es tatsächlich Teil der App-Klasse, die auch in der App.xaml.cs-Datei definiert ist.

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

Schritt 4: Anzeigeeinstellungen

Wenn die LoadAdvancedPrintSettingsContext Methode aufgerufen wird, wird der Konfigurationskontext der Druckaufgabe Variablen der MainPage-Klasse zugewiesen. Dadurch kann das benutzerdefinierte Flyout beim Starten auf die Druckeinstellungen zugreifen.

Die Ereignisargumente, die an die LoadAdvancedPrintSettingsContext Methode übergeben werden, machen Eigenschaften für den Zugriff und die Steuerung des Druckers verfügbar:

  • Die args.configuration-Eigenschaft stellt ein Objekt vom Typ Windows.Devices.Printers.Extensions.PrintTaskConfiguration bereit. Dieses Objekt bietet Zugriff auf den Kontext der Druckaufgabenerweiterung und ermöglicht es Ihnen, einen Ereignishandler hinzuzufügen, um das Druckticket zu aktualisieren.
  • Die args.configuration.printerExtensionContext-Eigenschaft stellt ein Objekt vom Typ Windows.Devices.Printers.Extensions.PrinterExtensionContext bereit. Dieses Objekt ist ein Zeiger auf die PrinterExtensionLibrary-Schnittstellen für Print Schema-, PrintTicket- und Druckwarteschlangeninformationen. Er ist NULL, wenn keine Schnittstellen verfügbar gemacht werden. Weitere Informationen finden Sie in der Übersicht über die Druckererweiterungsbibliothek.

In diesem Beispiel wird die LoadAdvancedPrintSettingsContext-Methode dargestellt, wie sie in der Datei Constants.cs angezeigt wird.

public PrintTaskConfiguration Config;
public Object Context;

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

Auf der benutzerdefinierten Flyoutseite Preferences.xaml.cs fungiert eine Klasse mit dem Namen rootPage als Zeiger auf die MainPage-Klasse, sodass über das Flyout auf den Kontext der Druckaufgabenerweiterung und den Druckergerätekontext zugegriffen werden kann.

Dieses Beispiel zeigt den Zeiger in einem Teil der Preferences Klasse aus der Preferences.xaml.cs Datei. Laden Sie das Beispiel für Druckeinstellungen und Druckbenachrichtigungen herunter, um den vollständigen Code anzuzeigen.

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

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

Wenn der Seitenkonstruktor für Preferences.xaml.cs aufgerufen wird, werden Objekte für den Kontext der Druckaufgabenerweiterung (ein PrintTaskConfiguration Objekt mit dem Namen configuration) und den Druckergerätekontext (ein PrintHelperClass Objekt mit dem Namen printHelper) erstellt.

Nachdem diese Objekte erstellt wurden, wird der Druckergerätekontext in der DisplaySettings-Methode verwendet, um TextBlocks und ComboBoxes zu laden. Beachten Sie, dass im Gegensatz zu JavaScript Änderungen an der Auswahl nicht auf demselben Thread wie die restliche App ausgelöst werden. Sie müssen Standard einen lokalen Cache von Benutzerauswahlen speichern, die für später verwendet werden sollen.

Dieses Beispiel zeigt den benutzerdefinierten Flyoutseitenkonstruktor und DisplaySettingsandere Hilfsmethoden in der Datei 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;
        }
    }
}

Schritt 5: Speichern von Einstellungen

Wenn der Benutzer die Einstellung erweiterter Druckeinstellungen abgeschlossen hat, muss die Microsoft Store-Geräte-App die Änderungen speichern, bevor der Benutzer zum Fenster Drucken zurückkehrt. Dazu muss die App darauf achten, wann der Benutzer auf die Schaltfläche Zurück tippt (auf der benutzerdefinierten Flyout-Seite). In diesem Fall wird das SaveRequested Ereignis des Kontexts der Druckaufgabenerweiterung (das Objekt configuration ) ausgelöst.

Dieses Beispiel zeigt den Ereignis-Listener für SaveRequested, der im Ereignishandler OnNavigatedTo des benutzerdefinierten Flyouts in der Datei Preferences.xaml.cs hinzugefügt wird Wenn das SaveRequested Ereignis ausgelöst wird, wird die OnSaveRequested Methode aufgerufen (diese Methode befindet sich auch in der Datei 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;
}

In der OnSaveRequested Methode verwendet die App zunächst das printHelper-Objekt, um die aktuell ausgewählten Optionen für jedes Feature im Druckererweiterungskontext festzulegen. Dann ruft es die Methode Save für das Objekt request auf, das als Argument an die Methode OnSaveRequested übergeben wird. Die Save Methode aus der Windows.Devices.Printers.Extensions.PrintTaskConfigurationSaveRequest-Klasse verwendet den Druckererweiterungskontext, um das Druckticket zu überprüfen und die Druckaufgabenkonfiguration zu speichern.

Wichtig

Wenn das Druckticket auf irgendeine Weise ungültig ist, löst die Save Methode eine Ausnahme aus, die die App verarbeiten muss. Wenn die App die Ausnahme nicht behandelt, wird der Fluss gestoppt, wodurch der Benutzer gezwungen wird, das Flyout leicht zu schließen und den Druckfluss neu zu starten.

Dieses Beispiel zeigt die OnSaveRequested Methode in der Datei Preferences.xaml.cs . Da das SaveRequested Ereignis nicht im UI-Thread ausgelöst wird, muss es einen Windows.UI.Core.CoreDispatcher verwenden, um Nachrichten im UI-Thread zu posten, um die entsprechenden Meldungen beim Überprüfen und Speichern des Tickets anzuzeigen.

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

Speichern von Optionen, die Benutzereingaben erfordern

Im Beispiel Druckeinstellungen und Druckbenachrichtigungen wird veranschaulicht, wie definierte Features festgelegt werden, die die meisten Druckoptionen umfassen. Einige Optionen erfordern jedoch eine benutzerdefinierte Benutzeroberfläche, um einen vom Benutzer angegebenen Wert abzurufen. Wenn eine App beispielsweise die erweiterten Druckeinstellungen zum Angeben eines benutzerdefinierten Seitenformats verwendet hat, führen Sie die folgenden Schritte aus, um den vom Benutzer angegebenen Wert zu speichern:

  1. Rufen Sie das Druckticket während der App-Aktivierung ab. Die App-Aktivierung für Druckeinstellungen wird weiter oben in Schritt 3 beschrieben: Behandeln der Aktivierung.

  2. Überprüfen Sie, ob die Option "Seitengröße" angegeben ist. In einer C#- oder JS-App kann die Druckhilfsklasse nach dieser Option suchen. Rufen Sie in einer C++-App QueryInterface auf IPrintSchemaOption auf, um IPrintSchemaPageMediaSizeOption abzurufen.

    In diesem Beispiel wird eine Methode in einer Druckhilfsklasse gezeigt, die überprüft, ob die Option Seitengröße angegeben ist.

    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. Zeigen Sie im benutzerdefinierten Flyout eine benutzerdefinierte Benutzeroberfläche an, die den Benutzer nach der Seitenhöhe und -breite fragt, und rufen Sie die vom Benutzer angegebene Höhe und Breite von IPrintSchemaPageMediaSizeOption ab.

    Dieses Beispiel zeigt eine Methode für ein benutzerdefiniertes Flyout, das den Benutzer zur Seitenhöhe und -breite auffordern.

    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. Aktualisieren Sie das IPrintSchemaPageMediaSizeOption-Objekt mit den vom Benutzer angegebenen Werten, und überprüfen Sie, ob die Höhe und Breite den vom Benutzer angegebenen Werten entspricht.

    Dieses Beispiel ist eine Hilfsmethode zum Aktualisieren des IPrintSchemaPageMediaSizeOption-Objekts in einer Druckerhelferklasse. Der OnSaveRequested-Handler im benutzerdefinierten Flyout würde diese Funktion aufrufen, wenn festgestellt wird, dass eine benutzerdefinierte Seitengrößesoption angefordert wurde.

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

Testen

Bevor Sie Ihre UWP-Geräte-App testen können, muss sie mithilfe von Gerätemetadaten mit Ihrem Drucker verknüpft werden.

  • Sie benötigen eine Kopie des Gerätemetadatenpakets für Ihren Drucker, um die Geräte-App-Informationen hinzuzufügen. Wenn Sie keine Gerätemetadaten haben, können Sie diese mit dem Assistenten zum Erstellen von Gerätemetadaten erstellen, wie im Thema Gerätemetadaten für Ihre UWP-Geräte-App erstellen beschrieben.

    Hinweis

    Um den Assistenten zum Erstellen von Gerätemetadaten zu verwenden, müssen Sie Microsoft Visual Studio Professional, Microsoft Visual Studio Ultimate oder das eigenständige SDK für Windows 8.1 installieren, bevor Sie die Schritte in diesem Thema ausführen. Beim Installieren von Microsoft Visual Studio Express für Windows wird eine Version des SDK installiert, die den Assistenten nicht enthält.

Die folgenden Schritte erstellen Ihre App und installieren die Gerätemetadaten.

  1. Aktivieren Sie die Testsignatur.

    1. Starten Sie den Assistenten für die Erstellung von Gerätedaten aus %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, indem Sie auf DeviceMetadataWizard.exe doppelklicken.

    2. Wählen Sie im Menü "Extras " die Option "Testsignatur aktivieren" aus.

  2. Starten Sie den Computer neu.

  3. Erstellen Sie die Lösung, indem Sie die Lösungsdatei (.sln) öffnen. Drücken Sie F7 oder gehen Sie im oberen Menü zu Build->Build Solution, nachdem das Beispiel geladen wurde.

  4. Trennen Sie den Drucker, und deinstallieren Sie den Drucker. Dieser Schritt ist erforderlich, damit Windows die aktualisierten Gerätemetadaten beim nächsten Erkennen des Geräts liest.

  5. Bearbeiten und Speichern von Gerätemetadaten Um die Geräte-App mit Ihrem Gerät zu verknüpfen, müssen Sie die Geräte-App Ihrem Gerät zuordnen.

    Hinweis

    Wenn Sie Ihre Gerätemetadaten noch nicht erstellt haben, lesen Sie Erstellen von Gerätemetadaten für Ihre UWP-Geräte-App.

    1. Wenn der Device Metadata Authoring Wizard noch nicht geöffnet ist, starten Sie ihn unter %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, indem Sie auf DeviceMetadataWizard.exe doppelklicken.

    2. Klicken Sie auf Gerätemetadaten bearbeiten. Dadurch können Sie Ihr vorhandenes Gerätemetadatenpaket bearbeiten.

    3. Suchen Sie im Dialogfeld Öffnen das Gerätemetadatenpaket, das Ihrer UWP-Geräte-App zugeordnet ist. (Es verfügt über die Dateierweiterung devicemetadata-ms.)

    4. Geben Sie auf der Seite "Informationen zur UWP-Geräte-App angeben" die Informationen zur Microsoft Store-App in das Feld " UWP-Geräte-App " ein. Klicken Sie auf UWP-App-Manifestdatei importieren, um automatisch den Paketnamen, Herausgebernamen und UWP app ID einzugeben.

    5. Wenn Ihre App für Druckerbenachrichtigungen registriert ist, füllen Sie das Benachrichtigungshandlerfeld aus. Geben Sie in der Ereignis-ID den Namen des Druckereignishandlers ein. Geben Sie in "Event Asset" den Namen der Datei ein, in der sich dieser Code befindet.

    6. Wenn Sie fertig sind, klicken Sie auf Weiter , bis Sie zur Seite Fertig stellen gelangen.

    7. Vergewissern Sie sich auf der Seite "Überprüfen des Gerätemetadatenpakets ", dass alle Einstellungen korrekt sind, und aktivieren Sie das Kontrollkästchen "Gerätemetadatenpaket in den Metadatenspeicher auf dem lokalen Computer kopieren". Klicken Sie anschließend auf Speichern.

  6. Verbinden Sie Ihre Drucker erneut, damit Windows die aktualisierten Gerätemetadaten liest, wenn das Gerät verbunden ist.

Problembehandlung

Problem: Erweiterte Druckeinstellungen zeigen standardmäßiges Flyout anstelle eines benutzerdefinierten Flyouts an

Wenn das Flyout für erweiterte Druckeinstellungen das Standard-Flyout anstelle des benutzerdefinierten Flyouts anzeigt, das Ihre App implementiert...

  • Mögliche Ursache: Die Testsignatur ist nicht aktiviert. Informationen zum Aktivieren finden Sie im Abschnitt Debuggen in diesem Thema.

  • Mögliche Ursache: Die App fragt nicht nach dem richtigen Paketfamiliennamen ab. Überprüfen Sie den Paketfamiliennamen in Ihrem Code. Öffnen Sie package.appxmanifest in Visual Studio und stellen Sie sicher, dass der Name der Paketfamilie, den Sie abfragen, mit dem Namen auf der Registerkarte Packaging im Feld Name der Paketfamilie übereinstimmt.

  • Mögliche Ursache: Die Gerätemetadaten sind nicht mit dem Paketfamiliennamen verknüpft. Verwenden Sie den Assistenten zum Erstellen von Gerätemetadaten, um die Gerätemetadaten zu öffnen und den Paketfamiliennamen zu überprüfen. Starten Sie den Assistenten von %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, indem Sie auf DeviceMetadataWizard.exe doppelklicken.

Problem: Die App wird im Flyout gestartet und wird dann sofort geschlossen.

Wenn Ihr benutzerdefiniertes Flyout für erweiterte Druckeinstellungen sofort nach dem Start verschwindet...

  • Mögliche Ursache: In Windows 8 gibt es ein bekanntes Problem, das in einem Flyout unter dem Debugger geschlossen wird. Deaktivieren Sie das Debuggen, sobald Sie wissen, dass die Aktivierung funktioniert. Wenn Sie das Speichern des Drucktickets debuggen müssen, fügen Sie den Debugger nach der Aktivierung an.

Entwickeln von v4-Drucktreibern

Druckererweiterungsschnittstellen (v4 Drucktreiber)

Bidirektionale Kommunikationen

Erste Schritte mit UWP-Apps

Erstellen einer UWP-Geräte-App (schrittweise Anleitung)

Erstellen von Gerätemetadaten für eine UWP-Geräte-App (schrittweise Anleitung)