Condividere contenuto dall'app Windows

Il contratto di condivisione Windows consente agli utenti di condividere rapidamente contenuti, ad esempio testo, collegamenti, foto e video, dall'app ad altre app. Ad esempio, un utente potrebbe voler condividere una pagina Web con i propri amici usando un'app di social networking o salvare un collegamento in un'app note per farvi riferimento in un secondo momento.

Questo articolo illustra come implementare il lato origine del contratto Condividi: il codice che prepara il contenuto e apre il riquadro Condividi di Windows dalla tua app. Per informazioni sulla ricezione di contenuto condiviso, vedere Ricevere dati condivisi nell'app Windows.

Le Windows.ApplicationModel.DataTransfer API usate in questo articolo funzionano per le app con identità del pacchetto, incluse le app UWP e le app desktop WinUI 3 in pacchetto. Le app Win32 non in pacchetto possono partecipare concedendo l'identità del pacchetto e quindi usando IDataTransferManagerInterop.

Note

Le app desktop WinUI 3 non hanno un CoreWindow, quindi non puoi chiamare DataTransferManager.GetForCurrentView() o DataTransferManager.ShowShareUI() direttamente. Usare invece l'interfaccia di interoperabilità COM IDataTransferManagerInterop per associare l'oggetto all'handle DataTransferManager della finestra e per visualizzare l'interfaccia utente di condivisione. Per esempi di codice, vedere Visualizzare oggetti dell'interfaccia utente WinRT che dipendono da CoreWindow. Per un'implementazione completa, è anche possibile fare riferimento all'esempio di app di origine del contenuto di condivisione macchine virtuali Windows.

Configurare un gestore eventi

Registrare un gestore eventi DataRequested nell'istanza DataTransferManager . Questo evento viene generato quando l'utente richiama Condivisione, ad esempio quando tocca un pulsante Condividi nell'app o quando l'app determina che il contenuto è pronto per la condivisione.

Per le applicazioni desktop WinUI 3, ottenere l'elemento DataTransferManager per la propria finestra usando IDataTransferManagerInterop, come descritto in Visualizzare oggetti dell'interfaccia utente WinRT che dipendono da CoreWindow.

Fornire contenuto nel gestore DataRequested

Quando si verifica un evento DataRequested , l'app riceve un oggetto DataRequest contenente un DataPackage popolato con il contenuto da condividere. È necessario impostare un titolo e almeno un formato di dati. Una descrizione è facoltativa ma consigliata.

private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
    DataRequest request = args.Request;
    request.Data.Properties.Title = "Contoso article";
    request.Data.Properties.Description = "An interesting article from Contoso.";
    request.Data.SetText("Read this article at Contoso.com.");
    request.Data.SetWebLink(new Uri("https://contoso.com/articles/1234"));
}

Avviso

La Title proprietà è obbligatoria. Se non si imposta un titolo, l'operazione di condivisione non riesce.

Scegliere i formati di dati

DataPackage supporta più formati di dati predefiniti. Puoi fornire più di un formato nello stesso pacchetto, ovvero l'app ricevente usa qualsiasi formato che supporti al meglio.

Formato Method
Testo normale SetText
Collegamenti Web SetWebLink
Collegamenti dell'applicazione SetApplicationLink
HTML SetHtmlFormat
Testo formattato (RTF) SetRtf
Immagini bitmap SetBitmap
File e cartelle SetStorageItems
Dati personalizzati definiti dallo sviluppatore SetData

Impostare le proprietà

DataPackagePropertySet consente di allegare metadati aggiuntivi al contenuto condiviso. L'aggiunta di un'anteprima offre al foglio di condivisione un'anteprima visiva più completa. Per altre informazioni, vedere DataPackagePropertySet.

private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
    DataRequest request = args.Request; // The DataRequested event provides the request via args.Request.
    request.Data.Properties.Title = "Sunset photo";
    request.Data.Properties.Description = "Taken at Lake Tahoe.";
    // Providing a thumbnail is optional but improves the share sheet preview.
    // request.Data.Properties.Thumbnail = RandomAccessStreamReference.CreateFromFile(thumbnailFile);
}

Avviare l'interfaccia utente di condivisione

Dopo la registrazione per l'eventoDataRequested, aprire il foglio di condivisione Windows quando l'utente richiama Share. Per le applicazioni desktop WinUI 3, chiama ShowShareUIForWindow sull'interfaccia IDataTransferManagerInterop, passando l'HWND della finestra. Per esempi di codice, vedere Visualizzare oggetti dell'interfaccia utente WinRT che dipendono da CoreWindow.

Gestire gli errori

Se l'app non può fornire contenuto condivisibile, ad esempio perché l'utente non ha selezionato nulla, chiama FailWithDisplayText per visualizzare un messaggio informativo nell'interfaccia utente della condivisione:

private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
    if (string.IsNullOrEmpty(selectedText))
    {
        args.Request.FailWithDisplayText("Select some text in the app before sharing.");
        return;
    }

    args.Request.Data.Properties.Title = "Selected text";
    args.Request.Data.SetText(selectedText);
}

Ritarda la condivisione con i delegati

Se la produzione dei dati di condivisione è a elevato utilizzo di risorse, ad esempio la codifica di un'immagine di grandi dimensioni in più risoluzioni, usare un delegato in modo che i dati vengano generati solo quando l'app ricevente lo richiede. In questo modo si evita il lavoro non necessario quando l'utente non ha ancora scelto una destinazione.

private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
    args.Request.Data.Properties.Title = "High-res photo";
    args.Request.Data.SetDataProvider(StandardDataFormats.Bitmap, OnDeferredImageRequested);
}

// Note: DataProviderHandler requires async void. The try/finally ensures the
// deferral completes even if an exception occurs.
private async void OnDeferredImageRequested(DataProviderRequest request)
{
    DataProviderDeferral deferral = request.GetDeferral();
    try
    {
        if (this.imageStream == null)
        {
            return;
        }

        InMemoryRandomAccessStream inMemoryStream = new InMemoryRandomAccessStream();

        // Decode the source image and re-encode at 50% size.
        BitmapDecoder imageDecoder = await BitmapDecoder.CreateAsync(this.imageStream);
        BitmapEncoder imageEncoder = await BitmapEncoder.CreateForTranscodingAsync(
            inMemoryStream, imageDecoder);

        imageEncoder.BitmapTransform.ScaledWidth =
            (uint)(imageDecoder.OrientedPixelWidth * 0.5);
        imageEncoder.BitmapTransform.ScaledHeight =
            (uint)(imageDecoder.OrientedPixelHeight * 0.5);
        await imageEncoder.FlushAsync();

        request.SetData(RandomAccessStreamReference.CreateFromStream(inMemoryStream));
    }
    finally
    {
        deferral.Complete();
    }
}

Vedere anche