Condividi tramite


Come personalizzare le impostazioni di stampa (app per dispositivi UWP)

In Windows 8.1, le app per dispositivi UWP consentono ai produttori di stampanti di personalizzare il riquadro a comparsa che visualizza le impostazioni di stampa avanzate. Questo argomento presenta il riquadro a comparsa delle impostazioni di stampa avanzate e mostra come la versione C# delle impostazioni di stampa e dell'esempio di notifiche di stampa sostituisce il riquadro a comparsa predefinito con un riquadro a comparsa personalizzato. Per altre informazioni sulle app per dispositivi UWP in generale, vedi Soddisfare le app per dispositivi UWP.

La versione C# delle impostazioni di stampa e dell'esempio di notifiche di stampa usa la pagina Preferences.xaml per illustrare l'interfaccia utente di un riquadro a comparsa personalizzato per le impostazioni di stampa avanzate. Una classe helper di stampa viene usata per creare un contesto di dispositivo (IPrinterExtensionContext) ed eseguire le query del dispositivo. Il file PrinterHelperClass.cs si trova nel progetto DeviceAppForPrintersLibrary e usa le API definite nel progetto PrinterExtensionLibrary . La libreria di estensioni della stampante offre un modo pratico per accedere alle interfacce di estensione della stampante del driver di stampa v4. Per altre info, vedi Panoramica della libreria di estensioni della stampante.

Nota

Gli esempi di codice illustrati in questo argomento si basano sulla versione C# delle impostazioni di stampa e sull'esempio di notifiche di stampa. Questo esempio è disponibile anche in JavaScript e C++. Si noti che poiché C++ può accedere direttamente a COM, la versione C++ dell'esempio non include progetti di libreria di codice. Scaricare gli esempi per visualizzare le versioni più recenti del codice.

Impostazioni avanzate di stampa

L'esperienza avanzata delle impostazioni di stampa è la funzionalità offerta da una stampante quando un utente desidera selezionare le impostazioni di stampa non disponibili nella finestra Stampa. È accessibile tramite il collegamento Altre impostazioni nella finestra Stampa. Non è un'esperienza a schermo intero, ma viene visualizzata all'interno di un riquadro a comparsa, ovvero un controllo per la visualizzazione di un'interfaccia utente contestuale leggera che viene ignorata quando un utente fa clic o tocca all'esterno di esso.

Questa esperienza può essere usata per evidenziare funzionalità differenziate per la stampante, ad esempio la possibilità di applicare filigrane a una pagina del documento, offrire opzioni di stampa sicure o opzioni di miglioramento delle immagini.

Quando un'app per dispositivi UWP non è installata per una stampante, Windows offre un'esperienza predefinita per le impostazioni di stampa. Se Windows rileva che un'app per dispositivi UWP è installata per la stampante e che l'app ha acconsentito esplicitamente all'estensione windows.printTaskSettings , l'app sostituisce l'esperienza predefinita fornita da Windows.

Per richiamare il riquadro a comparsa per le impostazioni di stampa avanzate:

  1. Aprire un'app UWP che supporti la stampa

  2. Accedere agli accessi scorrendo sul lato destro dello schermo (o usando il tasto logo Windows + C)

  3. Toccare l'accesso ai dispositivi

  4. Toccare Stampa

  5. Toccare una stampante

  6. Verrà visualizzata la finestra Stampa

  7. Fare clic sul collegamento Altre impostazioni nella finestra Stampa

  8. Verrà aperto il riquadro a comparsa impostazioni di stampa avanzate

    • Il riquadro a comparsa predefinito viene visualizzato quando non è installata alcuna app per dispositivi UWP per la stampante

    • Viene visualizzato un riquadro a comparsa personalizzato quando viene installata un'app per dispositivi UWP per la stampante

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

Prerequisiti

Prima di iniziare:

  1. Assicurarsi che la stampante sia installata usando un driver di stampa v4. Per altre informazioni, vedi Sviluppo di driver di stampa v4.

  2. Configurare il PC di sviluppo. Vedi Introduzione per informazioni sul download degli strumenti e sulla creazione di un account per sviluppatore.

  3. Associare l'app allo Store. Per informazioni su questo, vedi Creare un'app per dispositivi UWP.

  4. Creare i metadati del dispositivo per la stampante che la associa all'app. Per altre informazioni, vedere Creare metadati del dispositivo.

  5. Compilare l'interfaccia utente per la pagina principale dell'app. Tutte le app per dispositivi UWP possono essere avviate dalla schermata Start, in cui verranno visualizzate a schermo intero. Usa l'esperienza Start per evidenziare il tuo prodotto o i tuoi servizi in modo che corrisponda alla personalizzazione e alle funzionalità specifiche dei tuoi dispositivi. Non esistono restrizioni speciali per il tipo di controlli dell'interfaccia utente che può usare. Per iniziare a usare la progettazione dell'esperienza a schermo intero, vedere i principi di progettazione di Microsoft Store.

  6. Se stai scrivendo la tua app con C# o JavaScript, aggiungi i progetti PrinterExtensionLibrary e DeviceAppForPrintersLibrary alla soluzione di app per dispositivi UWP. È possibile trovare ognuno di questi progetti nell'esempio Di impostazioni di stampa e notifiche di stampa.

Nota

Poiché C++ può accedere direttamente a COM, le app C++ non richiedono una libreria separata per funzionare con il contesto di dispositivo della stampante basato su COM.

Passaggio 1: Registrare l'estensione

Affinché Windows riconosca che l'app può fornire un riquadro a comparsa personalizzato per le impostazioni di stampa avanzate, deve registrare l'estensione delle impostazioni dell'attività di stampa. Questa estensione viene dichiarata in un Extension elemento, con un Category attributo impostato su un valore di windows.printTaskSettings. Negli esempi C# e C++ l'attributo Executable è impostato su $targetnametoken$.exe e l'attributo EntryPoint è impostato su DeviceAppForPrinters.App.

È possibile aggiungere l'estensione delle impostazioni dell'attività di stampa nella scheda Dichiarazioni di Progettazione manifesto in Microsoft Visual Studio. È anche possibile modificare manualmente il file XML del manifesto del pacchetto dell'app usando l'editor XML (testo). Fare clic con il pulsante destro del mouse sul file Package.appxmanifest in Esplora soluzioni per le opzioni di modifica.

Questo esempio mostra l'estensione delle impostazioni dell'attività di stampa nell'elemento Extension , come viene visualizzato nel file manifesto del pacchetto dell'app, 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>

Passaggio 2: Compilare l'interfaccia utente

Prima di creare l'app, è necessario collaborare con i progettisti e il team di marketing per progettare l'esperienza utente. L'esperienza utente deve proiettare gli aspetti di personalizzazione dell'azienda e contribuire a creare una connessione con gli utenti.

Linee guida di progettazione

È importante esaminare le linee guida per il riquadro a comparsa dell'app UWP prima di progettare il riquadro a comparsa personalizzato. Le linee guida garantiscono che il riquadro a comparsa fornisca un'esperienza intuitiva coerente con altre app UWP.

Per la pagina principale della tua app, tieni presente che Windows 8.1 può visualizzare più app in varie dimensioni in un singolo monitor. Vedere le linee guida seguenti per altre informazioni su come l'app può rielaborare correttamente le dimensioni dello schermo, le dimensioni della finestra e gli orientamenti.

Dimensioni riquadro a comparsa

Il riquadro a comparsa che visualizza impostazioni di stampa avanzate è largo 646 pixel e almeno 768 pixel di altezza (l'altezza effettiva dipende dalla risoluzione dello schermo dell'utente). Il pulsante Indietro nell'area del titolo del riquadro a comparsa viene fornito da Windows. Il testo "Titolo app" è il titolo dell'app dal manifesto dell'app. L'area del titolo è alta 80 pixel, lasciando 688 pixel per l'area visualizzabile del riquadro a comparsa personalizzato.

flyout dimensions for advanced printer settings.

Nota

Se il riquadro a comparsa personalizzato è maggiore di 688 pixel in altezza, l'utente può scorrere o scorrere per visualizzare parti del riquadro a comparsa che si trovano sopra o sotto l'area visualizzabile.

Definizione del colore e dell'icona del titolo dell'app

Titolo, colore di sfondo, colore del testo e piccolo logo nel riquadro a comparsa personalizzato viene ricavato dall'elemento VisualElements nel file manifesto del pacchetto dell'app.

Questo esempio mostra il titolo e l'icona, come definito nell'elemento , nel file manifesto del pacchetto dell'app 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>

Procedure consigliate

  • Mantieni lo stesso aspetto. Allineare il riquadro a comparsa personalizzato con la progettazione per l'esperienza start (la pagina principale dell'app), inclusi elementi come tipi di carattere, colori e controlli. L'app deve avere familiarità con le persone indipendentemente dalla posizione da cui lo richiamano.

  • Mantenere semplici le interazioni. Evitare interazioni complesse o dispendiose in termini di tempo. Nella maggior parte dei casi, le azioni come la configurazione di una stampante, lo stato di visualizzazione, l'input penna e la risoluzione dei problemi sono ottimali all'interno dell'esperienza start.

  • Mantenere almeno lo spostamento. Evitare di fare in modo che gli utenti passino avanti e indietro tra più pagine nel riquadro a comparsa personalizzato. Usare invece controlli di scorrimento verticale o inline, ad esempio controlli di divulgazione progressiva, elenchi a discesa e messaggi di errore inline.

  • Non usare i riquadri a comparsa di chiusura della luce. L'esperienza di stampa usa già un riquadro a comparsa di chiusura chiaro. L'inclusione di un altro elemento di chiusura chiaro nel riquadro a comparsa personalizzato può confondere gli utenti.

  • Disabilitare i collegamenti che impediscono agli utenti di accedere all'esperienza di stampa. Quando un utente stampa il contenuto, è necessario eseguire le operazioni necessarie per assicurarsi che rimangano nel contesto di stampa. Ad esempio, se l'app include collegamenti che portano ad altre aree della tua app (ad esempio a una home page o a una pagina per l'acquisto dell'input penna), devi disabilitarle in modo che l'utente non lasci accidentalmente l'esperienza delle impostazioni di stampa avanzate.

Passaggio 3: Gestire l'attivazione

Se l'app ha dichiarato l'estensione delle impostazioni dell'attività di stampa, deve implementare un OnActivated metodo per gestire l'evento di attivazione dell'app. L'attivazione dell'app è quando l'app può scegliere quale pagina verrà avviata all'avvio dell'app. Per le app che hanno dichiarato l'estensione delle impostazioni dell'attività di stampa, Windows passa il contesto dell'estensione dell'attività di stampa negli argomenti evento Activated: Windows.ApplicationModel.Activation.IActivatedEventArgs.

Un'app per dispositivi UWP può determinare che l'attivazione è destinata alle impostazioni di stampa avanzate (che un utente ha appena toccato Altre opzioni nella finestra di dialogo delle impostazioni di stampa) quando la proprietà dell'argomento kind evento è uguale a Windows.ApplicationModel.Activation.ActivationKind.printTask Impostazioni.

Nota

In alcuni casi, se l'utente ignora l'app subito dopo l'avvio, potrebbe essere generata un'eccezione all'interno del gestore di attivazione. Per evitare questo problema, assicurarsi che il gestore di attivazione venga completato in modo efficiente e non eselabori le risorse a elevato utilizzo di risorse.

In questo esempio viene illustrato il gestore eventi di attivazione nel OnActivated metodo , come viene visualizzato nel file Constants.cs . Viene quindi eseguito il cast degli argomenti dell'evento come Windows.ApplicationModel.Activation.PrintTask Impostazioni ActivatedEventArgs. Anche se l'esempio include questo codice nel file Constants.cs , fa effettivamente parte della classe App definita anche nel file 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);
        }
    }
}

Passaggio 4: Visualizzare le impostazioni

Quando viene chiamato il LoadAdvancedPrintSettingsContext metodo , il contesto di configurazione dell'attività di stampa viene assegnato alle variabili della classe MainPage. In questo modo il riquadro a comparsa personalizzato potrà accedere alle impostazioni di stampa all'avvio.

Gli argomenti dell'evento passati al LoadAdvancedPrintSettingsContext metodo espongono proprietà per l'accesso e il controllo della stampante:

  • La proprietà args.configuration fornisce un oggetto di tipo Windows.Devices.Printers.Extensions.PrintTaskConfiguration. Questo oggetto fornisce l'accesso al contesto dell'estensione dell'attività di stampa e consente anche di aggiungere un gestore eventi per aggiornare il ticket di stampa.
  • La proprietà args.configuration.printerExtensionContext fornisce un oggetto di tipo Windows.Devices.Printers.Extensions.PrinterExtensionContext. Questo oggetto è un puntatore alle interfacce PrinterExtensionLibrary per le informazioni sulla coda di stampa, printticket e stampa. Sarà Null se non vengono esposte interfacce. Per altre info, vedi Panoramica della libreria di estensioni della stampante.

In questo esempio viene illustrato il LoadAdvancedPrintSettingsContext metodo , come viene visualizzato nel file Constants.cs .

public PrintTaskConfiguration Config;
public Object Context;

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

Nella pagina a comparsa personalizzata, Preferences.xaml.cs, una classe denominata rootPage funge da puntatore alla classe MainPage in modo che sia possibile accedere al contesto dell'estensione dell'attività di stampa e al contesto del dispositivo della stampante dal riquadro a comparsa.

Questo esempio mostra il puntatore in una parte della Preferences classe , dal file Preferences.xaml.cs . Scaricare l'esempio di impostazioni di stampa e notifiche di stampa per visualizzare il codice completo.

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

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

Quando viene chiamato il costruttore di pagina per Preferences.xaml.cs , gli oggetti vengono creati per il contesto dell'estensione dell'attività di stampa (un PrintTaskConfiguration oggetto denominato configuration) e il contesto del dispositivo della stampante (un PrintHelperClass oggetto denominato printHelper).

Dopo aver creato questi oggetti, il contesto del dispositivo della stampante viene usato nel DisplaySettings metodo per caricare TextBlocks e ComboBoxes. A differenza di JavaScript, le modifiche apportate alla selezione non vengono attivate nello stesso thread del resto dell'app. È necessario mantenere una cache locale delle selezioni utente da usare per un secondo momento.

Questo esempio mostra il costruttore personalizzato della pagina a comparsa, DisplaySettingse altri metodi helper nel file 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;
        }
    }
}

Passaggio 5: Salvare le impostazioni

Al termine dell'impostazione delle impostazioni di stampa avanzate, l'app per dispositivi di Microsoft Store deve salvare le modifiche prima che l'utente torni alla finestra Stampa . A tale scopo, l'app deve essere in ascolto quando l'utente tocca il pulsante Indietro (dalla pagina a comparsa personalizzata). In questo caso, viene attivato l'evento SaveRequested del contesto dell'estensione dell'attività di stampa (oggetto configuration ).

In questo esempio viene illustrato il listener di eventi per SaveRequested, aggiunto nel OnNavigatedTo gestore eventi del riquadro a comparsa personalizzato, nel file Preferences.xaml.cs . Quando viene attivato l'evento SaveRequested , il OnSaveRequested metodo verrà richiamato (tale metodo si trova anche nel file 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 Nel metodo l'app usa innanzitutto l'oggetto printHelper per impostare le opzioni attualmente selezionate per ogni funzionalità nel contesto dell'estensione della stampante. Chiama quindi il Save metodo sull'oggetto request passato come argomento al OnSaveRequested metodo . Il Save metodo, dalla classe Windows.Devices.Printers.Extensions.PrintTaskConfigurationSaveRequest, usa il contesto dell'estensione della stampante per convalidare il ticket di stampa e salvare la configurazione dell'attività di stampa.

Importante

Se il ticket di stampa non è valido in alcun modo, il Save metodo genera un'eccezione che l'app deve gestire. Se l'app non gestisce l'eccezione, il flusso viene arrestato, forzando l'utente a chiudere il riquadro a comparsa e riavviare il flusso di stampa.

In questo esempio viene illustrato il OnSaveRequested metodo nel file Preferences.xaml.cs . Poiché l'evento SaveRequested non viene generato nel thread dell'interfaccia utente, deve usare windows.UI.Core.CoreDispatcher per inviare messaggi al thread dell'interfaccia utente per visualizzare i messaggi appropriati durante la convalida e il salvataggio del ticket.

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

Salvataggio delle opzioni che richiedono l'input dell'utente

L'esempio Relativo alle impostazioni di stampa e alle notifiche di stampa illustra come impostare le funzionalità definite, che illustra la maggior parte delle opzioni di stampa. Tuttavia, alcune opzioni richiedono un'interfaccia utente personalizzata per ottenere un valore specificato dall'utente. Ad esempio, se un'app usa le impostazioni di stampa avanzate per specificare una dimensione di pagina personalizzata, eseguire questi passaggi per salvare il valore specificato dall'utente:

  1. Recuperare il ticket di stampa durante l'attivazione dell'app. L'attivazione delle app per le impostazioni di stampa è descritta in precedenza nel passaggio 3: Gestire l'attivazione.

  2. Controllare se è specificata l'opzione dimensioni pagina. In un'app C# o JS la classe helper di stampa può verificare la presenza di questa opzione. In un'app C++ chiamare QueryInterface in IPrintSchemaOption per recuperare IPrintSchemaPageMediaSizeOption.

    In questo esempio viene illustrato un metodo in una classe helper di stampa che controlla se è specificata l'opzione dimensioni pagina.

    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. Nel riquadro a comparsa personalizzato visualizzare un'interfaccia utente personalizzata che chiede all'utente l'altezza e la larghezza della pagina e recuperare l'altezza e la larghezza specificati dall'utente da IPrintSchemaPageMediaSizeOption.

    Questo esempio mostra un metodo per un riquadro a comparsa personalizzato che chiede all'utente l'altezza e la larghezza della pagina.

    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. Aggiornare l'oggetto IPrintSchemaPageMediaSizeOption con i valori specificati dall'utente e verificare che l'altezza e la larghezza corrispondano ai valori specificati dall'utente.

    Questo esempio è un metodo helper per aggiornare l'oggetto IPrintSchemaPageMediaSizeOption in una classe helper della stampante. Il OnSaveRequested gestore nel riquadro a comparsa personalizzato chiamerebbe questa funzione se determina che è stata richiesta un'opzione personalizzata per le dimensioni della pagina.

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

Test in corso

Prima di poter testare l'app per dispositivi UWP, deve essere collegata alla stampante usando i metadati del dispositivo.

  • È necessaria una copia del pacchetto di metadati del dispositivo per la stampante per aggiungere le informazioni sull'app del dispositivo. Se non hai metadati del dispositivo, puoi compilarlo usando la Creazione guidata metadati dispositivo come descritto nell'argomento Creare metadati del dispositivo per l'app per dispositivi UWP.

    Nota

    Per usare la Creazione guidata metadati dispositivo, è necessario installare Microsoft Visual Studio Professional, Microsoft Visual Studio Ultimate o l'SDK autonomo per Windows 8.1, prima di completare i passaggi descritti in questo argomento. L'installazione di Microsoft Visual Studio Express per Windows installa una versione dell'SDK che non include la procedura guidata.

La procedura seguente consente di compilare l'app e installare i metadati del dispositivo.

  1. Abilitare la firma di test.

    1. Avviare la Creazione guidata metadati dispositivo da %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86 facendo doppio clic su DeviceMetadataWizard.exe

    2. Scegliere Abilita firma test dal menu Strumenti.

  2. Riavviare il computer

  3. Compilare la soluzione aprendo il file della soluzione (.sln). Premere F7 o passare a Compila soluzione> dal menu in alto dopo il caricamento dell'esempio.

  4. Disconnettere e disinstallare la stampante. Questo passaggio è obbligatorio in modo che Windows leggerà i metadati aggiornati del dispositivo alla successiva individuazione del dispositivo.

  5. Modificare e salvare i metadati del dispositivo. Per collegare l'app del dispositivo al dispositivo, è necessario associare l'app del dispositivo al dispositivo

    Nota

    Se non hai ancora creato i metadati del dispositivo, vedi Creare metadati del dispositivo per l'app per dispositivi UWP.

    1. Se la Creazione guidata metadati dispositivo non è ancora aperta, avviarla da %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86 facendo doppio clic su DeviceMetadataWizard.exe.

    2. Fare clic su Modifica metadati dispositivo. In questo modo sarà possibile modificare il pacchetto di metadati del dispositivo esistente.

    3. Nella finestra di dialogo Apri individuare il pacchetto di metadati del dispositivo associato all'app per dispositivi UWP. Ha un'estensione di file devicemetadata-ms .

    4. Nella pagina Specificare le informazioni sull'app per dispositivi UWP immettere le informazioni sull'app di Microsoft Store nella casella app per dispositivi UWP. Fare clic su Importa file manifesto dell'app UWP per immettere automaticamente il nome del pacchetto, il nome dell'editore e l'ID app UWP.

    5. Se l'app sta registrando per le notifiche della stampante, compilare la casella Gestori di notifica. In ID evento immettere il nome del gestore eventi di stampa. In Asset evento immettere il nome del file in cui risiede il codice.

    6. Al termine, fare clic su Avanti finché non si arriva alla pagina Fine .

    7. Nella pagina Rivedi il pacchetto di metadati del dispositivo verificare che tutte le impostazioni siano corrette e selezionare la casella di controllo Copia il pacchetto di metadati del dispositivo nell'archivio metadati nel computer locale. Fare clic su Save (Salva).

  6. Riconnettere la stampante in modo che Windows legga i metadati aggiornati del dispositivo quando il dispositivo è connesso.

Risoluzione dei problemi

Problema: le impostazioni avanzate di stampa mostrano il riquadro a comparsa predefinito anziché il riquadro a comparsa personalizzato

Se il riquadro a comparsa impostazioni di stampa avanzate mostra il riquadro a comparsa predefinito anziché il riquadro a comparsa personalizzato implementato dall'app...

  • Possibile causa: la firma del test non è attivata. Per informazioni sull'attivazione, vedi la sezione Debug in questo argomento.

  • Possibile causa: l'app non esegue query sul nome della famiglia di pacchetti corretto. Controllare il nome della famiglia di pacchetti nel codice. Aprire package.appxmanifest in Visual Studio e assicurarsi che il nome della famiglia di pacchetti su cui si sta eseguendo una query corrisponda a quello nella scheda Creazione pacchetti nel campo Nome famiglia di pacchetti.

  • Possibile causa: i metadati del dispositivo non sono associati al nome della famiglia di pacchetti. Usare la Creazione guidata metadati dispositivo per aprire i metadati del dispositivo e controllare il nome della famiglia di pacchetti. Avviare la procedura guidata da %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86 facendo doppio clic su DeviceMetadataWizard.exe.

Problema: l'app viene avviata nel riquadro a comparsa e quindi viene immediatamente ignorata

Se il riquadro a comparsa personalizzato per le impostazioni di stampa avanzate scompare immediatamente dopo l'avvio...

  • Possibile causa: in Windows 8 si verifica un problema noto che all'interno di un riquadro a comparsa le app UWP verranno ignorate nel debugger. Disattivare il debug dopo aver appreso che l'attivazione funziona. Se è necessario eseguire il debug del salvataggio del ticket di stampa, collegare il debugger dopo l'attivazione.

Sviluppo di driver di stampa v4

Interfacce di estensione della stampante (driver di stampa v4)

Comunicazioni bidirezionali

Introduzione alle app UWP

Creare un'app per dispositivi UWP (guida dettagliata)

Creare metadati del dispositivo per un'app per dispositivi UWP (guida dettagliata)