Casting multimedialeMedia casting

In questo articolo viene illustrato come eseguire il cast di contenuti multimediali in dispositivi remoti da un’app di Windows universale.This article shows you how to cast media to remote devices from a Universal Windows app.

Casting multimediale incorporato con MediaPlayerElementBuilt-in media casting with MediaPlayerElement

Il modo più semplice per eseguire il cast di contenuti multimediali da un'app di Windows universale consiste nell'usare la funzionalità di casting predefinita del controllo MediaPlayerElement.The simplest way to cast media from a Universal Windows app is to use the built-in casting capability of the MediaPlayerElement control.

Per permettere all'utente di aprire un file video da riprodurre nel controllo MediaPlayerElement, aggiungi gli spazi dei nomi seguenti al tuo progetto.To allow the user to open a video file to be played in the MediaPlayerElement control, add the following namespaces to your project.

using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.Media.Core;

Nel file XAML dell'app aggiungi un controllo MediaPlayerElement e imposta AreTransportControlsEnabled su true.In your app's XAML file, add a MediaPlayerElement and set AreTransportControlsEnabled to true.

<MediaPlayerElement Name="mediaPlayerElement"  MinHeight="100" MaxWidth="600" HorizontalAlignment="Stretch" AreTransportControlsEnabled="True"/>

Aggiungi un pulsante per permettere all'utente di avviare la selezione di un file.Add a button to let the user initiate picking a file.

<Button x:Name="openButton" Click="openButton_Click" Content="Open"/>

Nel gestore eventi Click per il pulsante, creare una nuova istanza di FileOpenPicker, aggiungere i tipi di file video alla raccolta fileTypeFilter e impostare il percorso iniziale sulla raccolta video dell'utente.In the Click event handler for the button, create a new instance of the FileOpenPicker, add video file types to the FileTypeFilter collection, and set the starting location to the user's videos library.

Chiamare pickSingleFileAsync per avviare la finestra di dialogo di selezione file.Call PickSingleFileAsync to launch the file picker dialog. Il valore restituito da questo metodo è un oggetto StorageFile che rappresenta il file video.When this method returns, the result is a StorageFile object representing the video file. Verifica che il file non sia null (potrebbe esserlo se l'utente annulla l'operazione di selezione).Check to make sure the file isn't null, which it will be if the user cancels the picking operation. Chiamare il metodo OpenAsync del file per ottenere un IRandomAccessStream per il file.Call the file's OpenAsync method to get an IRandomAccessStream for the file. Infine, crea un nuovo oggetto MediaSource dal file selezionato chiamando CreateFromStorageFile e assegnalo alla proprietà Source dell'oggetto MediaPlayerElement per rendere il file video l'origine video per il controllo.Finally, create a new MediaSource object from the selected file by calling CreateFromStorageFile and assign it to the MediaPlayerElement object's Source property to make the video file the video source for the control.

private async void openButton_Click(object sender, RoutedEventArgs e)
{
    //Create a new picker
    FileOpenPicker filePicker = new FileOpenPicker();

    //Add filetype filters.  In this case wmv and mp4.
    filePicker.FileTypeFilter.Add(".wmv");
    filePicker.FileTypeFilter.Add(".mp4");

    //Set picker start location to the video library
    filePicker.SuggestedStartLocation = PickerLocationId.VideosLibrary;

    //Retrieve file from picker
    StorageFile file = await filePicker.PickSingleFileAsync();

    //If we got a file, load it into the media lement
    if (file != null)
    {
        mediaPlayerElement.Source = MediaSource.CreateFromStorageFile(file);
        mediaPlayerElement.MediaPlayer.Play();
    }
}

Dopo che il video è stato caricato in MediaPlayerElement, l'utente può semplicemente premere il pulsante di cast nei controlli del trasporto per avviare una finestra di dialogo predefinita che permette di scegliere un dispositivo in cui verrà eseguito il cast dei contenuti multimediali caricati.Once the video is loaded in the MediaPlayerElement, the user can simply press the casting button on the transport controls to launch a built-in dialog that allows them to choose a device to which the loaded media will be cast.

Pulsante di casting MediaElement

Nota

A partire da Windows 10 versione 1607, è consigliabile usare la classe MediaPlayer per la riproduzione di elementi multimediali.Starting with Windows 10, version 1607, it is recommended that you use the MediaPlayer class to play media items. MediaPlayerElement è un controllo XAML leggero usato per il rendering del contenuto di un MediaPlayer in una pagina XAML.The MediaPlayerElement is a lightweight XAML control that is used to render the content of a MediaPlayer in a XAML page. Il controllo MediaElement continua a essere supportato per la compatibilità con le versioni precedenti.The MediaElement control continues to be supported for backwards compatibility. Per altre informazioni sull'uso di MediaPlayer e MediaPlayerElement per riprodurre contenuto multimediale, vedi Riprodurre audio e video con MediaPlayer.For more information on using MediaPlayer and MediaPlayerElement to play media content, see Play audio and video with MediaPlayer. Per informazioni sull'uso di MediaSource e delle API correlate per la gestione di contenuto multimediale, vedi Elementi multimediali, playlist e tracce.For information on using MediaSource and related APIs to work with media content, see Media items, playlists, and tracks.

Casting multimediale con CastingDevicePickerMedia casting with the CastingDevicePicker

Un secondo modo per eseguire il cast dei file multimediali in un dispositivo consiste nell'usare CastingDevicePicker.A second way to cast media to a device is to use the CastingDevicePicker. Per usare questa classe, includere lo spazio dei nomi Windows. Media. Cast nel progetto.To use this class, include the Windows.Media.Casting namespace in your project.

using Windows.Media.Casting;

Dichiara una variabile membro per l'oggetto CastingDevicePicker.Declare a member variable for the CastingDevicePicker object.

CastingDevicePicker castingPicker;

Quando si inizializza la pagina, creare una nuova istanza della selezione del cast e impostare la proprietà Filter to SupportsVideo per indicare che i dispositivi di cast elencati dal selettore dovrebbero supportare il video.When you page is initialized, create a new instance of the casting picker and set the Filter to SupportsVideo property to indicate that the casting devices listed by the picker should support video. Registrare un gestore per l'evento CastingDeviceSelected , che viene generato quando l'utente seleziona un dispositivo per il cast.Register a handler for the CastingDeviceSelected event, which is raised when the user picks a device for casting.

//Initialize our picker object
castingPicker = new CastingDevicePicker();

//Set the picker to filter to video capable casting devices
castingPicker.Filter.SupportsVideo = true;

//Hook up device selected event
castingPicker.CastingDeviceSelected += CastingPicker_CastingDeviceSelected;

Nel file XAML aggiungi un pulsante per permettere all'utente di avviare la selezione.In your XAML file, add a button to allow the user to launch the picker.

<Button x:Name="castPickerButton" Content="Cast Button" Click="castPickerButton_Click"/>

Nel gestore dell'evento Click per il pulsante chiama TransformToVisual per ottenere la trasformazione di un elemento dell'interfaccia utente rispetto a un altro elemento.In the Click event handler for the button, call TransformToVisual to get the transform of a UI element relative to another element. In questo esempio, la trasformazione è la posizione del pulsante di selezione del cast relativamente alla radice visiva della finestra dell'applicazione.In this example, the transform is the position of the cast picker button relative to the visual root of the application window. Chiama il metodo Show dell’oggetto CastingDevicePicker per avviare la finestra di dialogo di selezione del cast.Call the Show method of the CastingDevicePicker object to launch the casting picker dialog. Specifica la posizione e le dimensioni del pulsante di selezione del cast, in modo che il sistema possa far comparire la finestra di dialogo dal pulsante che è stato premuto dall'utente.Specify the location and dimensions of the cast picker button so that the system can make the dialog fly out from the button that the user pressed.

private void castPickerButton_Click(object sender, RoutedEventArgs e)
{
    //Retrieve the location of the casting button
    GeneralTransform transform = castPickerButton.TransformToVisual(Window.Current.Content as UIElement);
    Point pt = transform.TransformPoint(new Point(0, 0));

    //Show the picker above our casting button
    castingPicker.Show(new Rect(pt.X, pt.Y, castPickerButton.ActualWidth, castPickerButton.ActualHeight),
        Windows.UI.Popups.Placement.Above);
}

Nel gestore dell'evento CastingDeviceSelected chiama il metodo CreateCastingConnection della proprietà SelectedCastingDevice degli argomenti dell'evento, che rappresenta il dispositivo di cast selezionato dall'utente.In the CastingDeviceSelected event handler, call the CreateCastingConnection method of the SelectedCastingDevice property of the event args, which represents the casting device selected by the user. Registra i gestori per gli eventi ErrorOccurred e StateChanged.Register handlers for the ErrorOccurred and StateChanged events. Infine, chiama RequestStartCastingAsync per avviare il cast, passando il risultato al metodo GetAsCastingSource dell'oggetto MediaPlayer del controllo MediaPlayerElement per specificare che l'elemento multimediale di cui eseguire il cast è il contenuto del MediaPlayer associato a MediaPlayerElement.Finally, call RequestStartCastingAsync to begin casting, passing in the result to the MediaPlayerElement control's MediaPlayer object's GetAsCastingSource method to specify that the media to be cast is the content of the MediaPlayer associated with the MediaPlayerElement.

Nota

La connessione di cast deve essere avviata nel thread dell'interfaccia utente.The casting connection must be initiated on the UI thread. Poiché CastingDeviceSelected non viene chiamato nel thread dell'interfaccia utente, devi inserire queste chiamate all'interno di una chiamata a CoreDispatcher.RunAsync, per fare in modo che vengano chiamate nel thread dell'interfaccia utente.Since the CastingDeviceSelected is not called on the UI thread, you must place these calls inside a call to CoreDispatcher.RunAsync which causes them to be called on the UI thread.

private async void CastingPicker_CastingDeviceSelected(CastingDevicePicker sender, CastingDeviceSelectedEventArgs args)
{
    //Casting must occur from the UI thread.  This dispatches the casting calls to the UI thread.
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
    {
        //Create a casting conneciton from our selected casting device
        CastingConnection connection = args.SelectedCastingDevice.CreateCastingConnection();

        //Hook up the casting events
        connection.ErrorOccurred += Connection_ErrorOccurred;
        connection.StateChanged += Connection_StateChanged;

        //Cast the content loaded in the media element to the selected casting device
        await connection.RequestStartCastingAsync(mediaPlayerElement.MediaPlayer.GetAsCastingSource());
    });
}

Nei gestori degli eventi ErrorOccurred e StateChanged devi aggiornare l'interfaccia utente per informare l'utente dello stato corrente del cast.In the ErrorOccurred and StateChanged event handlers, you should update your UI to inform the user of the current casting status. Questi eventi sono descritti in dettaglio nella sezione seguente sulla creazione di una selezione personalizzata del dispositivo di cast.These events are discussed in detail in the following section on creating a custom casting device picker.

private async void Connection_StateChanged(CastingConnection sender, object args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        ShowMessageToUser("Casting Connection State Changed: " + sender.State);
    });
}

private async void Connection_ErrorOccurred(CastingConnection sender, CastingConnectionErrorOccurredEventArgs args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        ShowMessageToUser("Casting Connection State Changed: " + sender.State);
    });
}

Cast multimediale con una selezione personalizzata del dispositivoMedia casting with a custom device picker

Nella sezione seguente viene descritto come creare una propria interfaccia utente di selezione del dispositivo di cast, enumerando i dispositivi di cast e avviando la connessione dal codice.The following section describes how to create your own casting device picker UI by enumerating the casting devices and initiating the connection from your code.

Per enumerare i dispositivi di cast disponibili, includere lo spazio dei nomi Windows. Devices. Enumeration nel progetto.To enumerate the available casting devices, include the Windows.Devices.Enumeration namespace in your project.

using Windows.Devices.Enumeration;

Aggiungi i controlli seguenti alla pagina XAML per implementare l'interfaccia utente di base per questo esempio:Add the following controls to your XAML page to implement the rudimentary UI for this example:

  • Un pulsante per avviare il watcher del dispositivo che cerca i dispositivi di cast disponibili.A button to start the device watcher that looks for available casting devices.
  • Un controllo ProgressRing per fornire feedback all’utente, segnalando che l’enumerazione di cast è in corso.A ProgressRing control to provide feedback to the user that casting enumeration is ongoing.
  • Un ListBox per elencare i dispositivi di cast individuati.A ListBox to list the discovered casting devices. Definire un ItemTemplate per il controllo in modo che sia possibile assegnare gli oggetti dispositivo di cast direttamente al controllo e visualizzare comunque la proprietà FriendlyName .Define an ItemTemplate for the control so that we can assign the casting device objects directly to the control and still display the FriendlyName property.
  • Un pulsante per permettere all'utente di disconnettere il dispositivo di cast.A button to allow the user to disconnect the casting device.
<Button x:Name="startWatcherButton" Content="Watcher Button" Click="startWatcherButton_Click"/>
<ProgressRing x:Name="watcherProgressRing" IsActive="False"/>
<ListBox x:Name="castingDevicesListBox" MaxWidth="300" HorizontalAlignment="Left" SelectionChanged="castingDevicesListBox_SelectionChanged">
    <!--Listbox content is bound to the FriendlyName field of our casting devices-->
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=FriendlyName}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
<Button x:Name="disconnectButton" Content="Disconnect" Click="disconnectButton_Click" Visibility="Collapsed"/>

Nel code-behind dichiara le variabili membro per DeviceWatcher e CastingConnection.In your code behind, declare member variables for the DeviceWatcher and the CastingConnection.

DeviceWatcher deviceWatcher;
CastingConnection castingConnection;

Nel gestore di Click per startWatcherButton aggiorna innanzitutto l'interfaccia utente disabilitando il pulsante e rendendo attivo l'anello di stato mentre è in corso l'enumerazione dei dispositivi.In the Click handler for the startWatcherButton, first update the UI by disabling the button and making the progress ring active while device enumeration is ongoing. Deseleziona la casella di riepilogo dei dispositivi di cast.Clear the list box of casting devices.

Crea quindi un watcher del dispositivo chiamando DeviceInformation.CreateWatcher.Next, create a device watcher by calling DeviceInformation.CreateWatcher. Questo metodo può essere usato per individuare molti tipi diversi di dispositivi.This method can be used to watch for many different types of devices. Specifica che vuoi individuare i dispositivi che supportano il cast video mediante la stringa del selettore del dispositivo restituita da CastingDevice.GetDeviceSelector.Specify that you want to watch for devices that support video casting by using the device selector string returned by CastingDevice.GetDeviceSelector.

Infine, registrare i gestori eventi per gli eventi added, removed, EnumerationCompletede Stopped .Finally, register event handlers for the Added, Removed, EnumerationCompleted, and Stopped events.

private void startWatcherButton_Click(object sender, RoutedEventArgs e)
{
    startWatcherButton.IsEnabled = false;
    watcherProgressRing.IsActive = true;

    castingDevicesListBox.Items.Clear();

    //Create our watcher and have it find casting devices capable of video casting
    deviceWatcher = DeviceInformation.CreateWatcher(CastingDevice.GetDeviceSelector(CastingPlaybackTypes.Video));

    //Register for watcher events
    deviceWatcher.Added += DeviceWatcher_Added;
    deviceWatcher.Removed += DeviceWatcher_Removed;
    deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted;
    deviceWatcher.Stopped += DeviceWatcher_Stopped;

    //Start the watcher
    deviceWatcher.Start();
}

L'evento Added viene generato quando viene individuato un nuovo dispositivo mediante il watcher.The Added event is raised when a new device is discovered by the watcher. Nel gestore per questo evento crea un nuovo oggetto CastingDevice chiamando CastingDevice.FromIdAsync e passando l’ID del dispositivo di cast individuato, contenuto nell’oggetto DeviceInformation passato al gestore.In the handler for this event, create a new CastingDevice object by calling CastingDevice.FromIdAsync and passing in the ID of the discovered casting device, which is contained in the DeviceInformation object passed into the handler.

Aggiungi il CastingDevice al ListBox del dispositivo di cast, in modo che l’utente possa selezionarlo.Add the CastingDevice to the casting device ListBox so that the user can select it. A causa dell' ItemTemplate definito in XAML, la proprietà FriendlyName verrà utilizzata come testo dell'elemento per nella casella di riepilogo.Because of the ItemTemplate defined in the XAML, the FriendlyName property will be used as the item text for in the list box. Poiché questo gestore eventi non viene chiamato sul thread dell'interfaccia utente, è necessario aggiornare l'interfaccia utente dall'interno di una chiamata a CoreDispatcher. RunAsync.Because this event handler is not called on the UI thread, you must update the UI from within a call to CoreDispatcher.RunAsync.

private async void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
    {
        //Add each discovered device to our listbox
        CastingDevice addedDevice = await CastingDevice.FromIdAsync(args.Id);
        castingDevicesListBox.Items.Add(addedDevice);
    });
}

L'evento Removed viene generato quando il watcher rileva che un dispositivo di cast non è più presente.The Removed event is raised when the watcher detects that a casting device is no longer present. Confronta la proprietà ID dell’oggetto Added passato al gestore con l’ID di ogni Added nella raccolta Items della casella di riepilogo.Compare the ID property of the Added object passed into the handler to the ID of each Added in the list box's Items collection. Se gli ID corrispondono, rimuovi tale oggetto dalla raccolta.If the ID matches, remove that object from the collection. Anche in questo caso, poiché viene aggiornata l'interfaccia utente, questa chiamata deve essere effettuata all'interno di una chiamata RunAsync.Again, because the UI is being updated, this call must be made from within a RunAsync call.

private async void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformationUpdate args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        foreach (CastingDevice currentDevice in castingDevicesListBox.Items)
        {
            if (currentDevice.Id == args.Id)
            {
                castingDevicesListBox.Items.Remove(currentDevice);
            }
        }
    });
}

L'evento EnumerationCompletedviene generato quando il watcher ha terminato di rilevare i dispositivi.The EnumerationCompleted event is raised when the watcher has finished detecting devices. Nel gestore per questo evento aggiornare l'interfaccia utente per indicare all'utente che l'enumerazione del dispositivo è stata completata e arrestare il Watcher del dispositivo chiamando Stop.In the handler for this event, update the UI to let the user know that device enumeration has completed and stop the device watcher by calling Stop.

private async void DeviceWatcher_EnumerationCompleted(DeviceWatcher sender, object args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        //If enumeration completes, update UI and transition watcher to the stopped state
        ShowMessageToUser("Watcher completed enumeration of devices");
        deviceWatcher.Stop();
    });
}

L'evento Stopped viene generato quando il watcher del dispositivo ha terminato l'arresto.The Stopped event is raised when the device watcher has finished stopping. Nel gestore per questo evento arresta il controllo ProgressRing e abilita di nuovo startWatcherButton, in modo che l'utente possa riavviare il processo di enumerazione dei dispositivi.In the handler for this event, stop the ProgressRing control and reenable the startWatcherButton so that the user can restart the device enumeration process.

private async void DeviceWatcher_Stopped(DeviceWatcher sender, object args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        //Update UX when the watcher stops
        startWatcherButton.IsEnabled = true;
        watcherProgressRing.IsActive = false;
    });
}

Quando l'utente seleziona uno dei dispositivi di cast dalla casella di riepilogo, viene generato l'evento SelectionChanged.When the user selects one of the casting devices from the list box, the SelectionChanged event is raised. È all'interno di questo gestore che verrà creata la connessione di cast e verrà avviato il cast.It is within this handler that the casting connection will be created and casting will be started.

Innanzitutto, assicurati che il watcher del dispositivo sia arrestato, in modo che l'enumerazione dei dispositivi non interferisca con il casting multimediale.First, make sure the device watcher is stopped so that device enumeration doesn't interfere with media casting. Crea una connessione di cast chiamando CreateCastingConnection per l’oggetto CastingDevice selezionato dall’utente.Create a casting connection by calling CreateCastingConnection on the CastingDevice object selected by the user. Aggiungere gestori eventi per gli eventi StateChanged e ErrorOccurred .Add event handlers for the StateChanged and ErrorOccurred events.

Avvia il cast multimediale chiamando RequestStartCastingAsync e passando l'origine di cast restituita dalla chiamata del metodo GetAsCastingSource di MediaPlayer.Start media casting by calling RequestStartCastingAsync, passing in the casting source returned by calling the MediaPlayer method GetAsCastingSource. Infine, rendi visibile il pulsante di disconnessione per permettere all'utente di interrompere il cast multimediale.Finally, make the disconnect button visible to allow the user to stop media casting.

private async void castingDevicesListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (castingDevicesListBox.SelectedItem != null)
    {
        //When a device is selected, first thing we do is stop the watcher so it's search doesn't conflict with streaming
        if (deviceWatcher.Status != DeviceWatcherStatus.Stopped)
        {
            deviceWatcher.Stop();
        }

        //Create a new casting connection to the device that's been selected
        castingConnection = ((CastingDevice)castingDevicesListBox.SelectedItem).CreateCastingConnection();

        //Register for events
        castingConnection.ErrorOccurred += Connection_ErrorOccurred;
        castingConnection.StateChanged += Connection_StateChanged;

        //Cast the loaded video to the selected casting device.
        await castingConnection.RequestStartCastingAsync(mediaPlayerElement.MediaPlayer.GetAsCastingSource());
        disconnectButton.Visibility = Visibility.Visible;
    }
}

Nel gestore di modifica dello stato l'azione che esegui dipende dal nuovo stato della connessione di cast:In the state changed handler, the action you take depends on the new state of the casting connection:

  • Se lo stato è Connected o Rendering, assicurati che il controllo ProgressRing sia inattivo e che il pulsante di disconnessione sia visibile.If the state is Connected or Rendering, make sure the ProgressRing control is inactive and the disconnect button is visible.
  • Se lo stato è Disconnected, deseleziona il dispositivo di cast corrente nella casella di riepilogo, rendi inattivo il controllo ProgressRing e nascondi il pulsante di disconnessione.If the state is Disconnected, unselect the current casting device in the list box, make the ProgressRing control inactive, and hide the disconnect button.
  • Se lo stato è Connecting, rendi attivo il controllo ProgressRing e nascondi il pulsante di disconnessione.If the state is Connecting, make the ProgressRing control active and hide the disconnect button.
  • Se lo stato è Disconnecting, rendi attivo il controllo ProgressRing e nascondi il pulsante di disconnessione.If the state is Disconnecting, make the ProgressRing control active and hide the disconnect button.
private async void Connection_StateChanged(CastingConnection sender, object args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        //Update the UX based on the casting state
        if (sender.State == CastingConnectionState.Connected || sender.State == CastingConnectionState.Rendering)
        {
            disconnectButton.Visibility = Visibility.Visible;
            watcherProgressRing.IsActive = false;
        }
        else if (sender.State == CastingConnectionState.Disconnected)
        {
            disconnectButton.Visibility = Visibility.Collapsed;
            castingDevicesListBox.SelectedItem = null;
            watcherProgressRing.IsActive = false;
        }
        else if (sender.State == CastingConnectionState.Connecting)
        {
            disconnectButton.Visibility = Visibility.Collapsed;
            ShowMessageToUser("Connecting");
            watcherProgressRing.IsActive = true;
        }
        else
        {
            //Disconnecting is the remaining state
            disconnectButton.Visibility = Visibility.Collapsed;
            watcherProgressRing.IsActive = true;
        }
    });
}

Nel gestore per l'evento ErrorOccurred aggiorna l'interfaccia utente per informare l'utente che si è verificato un errore di cast e deseleziona l'oggetto CastingDevice corrente nella casella di riepilogo.In the handler for the ErrorOccurred event, update your UI to let the user know that a casting error occurred and unselect the current CastingDevice object in the list box.

private async void Connection_ErrorOccurred(CastingConnection sender, CastingConnectionErrorOccurredEventArgs args)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        //Clear the selection in the listbox on an error
        ShowMessageToUser("Casting Error: " + args.Message);
        castingDevicesListBox.SelectedItem = null;
    });
}

Infine, implementa il gestore per il pulsante di disconnessione.Finally, implement the handler for the disconnect button. Interrompi il casting multimediale ed esegui la disconnessione dal dispositivo di cast chiamando il metodo DisconnectAsync dell’oggetto CastingConnection.Stop media casting and disconnect from the casting device by calling the CastingConnection object's DisconnectAsync method. Questa chiamata deve essere inviata al thread UI chiamando CoreDispatcher. RunAsync.This call must be dispatched to the UI thread by calling CoreDispatcher.RunAsync.

private async void disconnectButton_Click(object sender, RoutedEventArgs e)
{
    if (castingConnection != null)
    {
        //When disconnect is clicked, the casting conneciton is disconnected.  The video should return locally to the media element.
        await castingConnection.DisconnectAsync();
    }
}