Esecuzione di comandi contestuali per le raccolte e gli elenchiContextual commanding for collections and lists

Numerose app contengono raccolte di contenuti sotto forma di elenchi, griglie e alberi che gli utenti possono modificare.Many apps contain collections of content in the form of lists, grids, and trees that users can manipulate. Ad esempio, gli utenti potrebbero essere in grado di eliminare, rinominare, contrassegnare o aggiornare elementi.For example, users might be able to delete, rename, flag, or refresh items. L'articolo illustra come usare i comandi contestuali per implementare queste tipologie di azioni in un modo che consenta la migliore esperienza possibile per tutti i tipi di input.This article shows you how to use contextual commands to implement these sorts of actions in a way that provides the best possible experience for all input types.

API importanti: Interfaccia ICommand, Proprietà UIElement.ContextFlyout, Interfaccia INotifyPropertyChangedImportant APIs: ICommand interface, UIElement.ContextFlyout property, INotifyPropertyChanged interface

Usare una varietà di input per eseguire il comando preferito

Creazione di comandi per tutti i tipi di inputCreating commands for all input types

Visto che gli utenti possono interagire con un'app di Windows usando un'ampia gamma di dispositivi e input, l'app dovrebbe esporre i comandi attraverso menu di scelta rapida indipendenti dall'input e acceleratori specifici dell'input.Because users can interact with a Windows app using a broad range of devices and inputs, your app should expose commands though both input-agnostic context menus and input-specific accelerators. L'inclusione di entrambi consentirà all'utente di richiamare velocemente i comandi sul contenuto indipendentemente dal tipo di input o dal tipo di dispositivo.Including both lets the user quickly invoke commands on content, regardless of input or device type.

La tabella mostra alcuni comandi tipici di raccolta e le modalità per la loro esposizione.This table shows some typical collection commands and ways to expose those commands.

ComandoCommand Indipendente dall'inputInput-agnostic Acceleratore tramite mouseMouse accelerator Acceleratore tramite tastieraKeyboard accelerator Acceleratore tramite toccoTouch accelerator
Elimina elementoDelete item Menu di scelta rapidaContext menu Pulsante attivato al passaggio del mouseHover button Tasto CANCDEL key Scorri rapidamente per eliminareSwipe to delete
Contrassegna elementoFlag item Menu di scelta rapidaContext menu Pulsante attivato al passaggio del mouseHover button CTRL+MAIUSC+GCtrl+Shift+G Scorri rapidamente per contrassegnareSwipe to flag
Aggiorna datiRefresh data Menu di scelta rapidaContext menu N/DN/A Tasto F5F5 key Aggiornamento tramite trascinamento verso il bassoPull to refresh
Segna un elemento come preferitoFavorite an item Menu di scelta rapidaContext menu Pulsante attivato al passaggio del mouseHover button F, CTRL+SF, Ctrl+S Scorri rapidamente per contrassegnare l'elemento come preferitoSwipe to favorite
  • In generale, dovresti rendere tutti i comandi di un elemento disponibili nel menu di scelta rapida dell'elemento stesso.In general, you should make all commands for an item available in the item's context menu. I menu di scelta rapida devono essere resi accessibili agli utenti indipendentemente dal tipo di input e devono contenere tutti i comandi contestuali che l'utente può eseguire.Context menus are accessible to users regardless of input type, and should contain all of the contextual commands that user can perform.

  • Per i comandi a cui si accede con frequenza, considera l'uso degli acceleratori per input.For frequently accessed commands, consider using input accelerators. Gli acceleratori per input permettono all'utente di eseguire azioni rapidamente, in base al dispositivo di input.Input accelerators let the user perform actions quickly, based on their input device. Gli acceleratori per input includono:Input accelerators include:

    • Scorrere rapidamente per eseguire l'azione (acceleratore tramite tocco)Swipe-to-action (touch accelerator)
    • Trascinare verso il basso per aggiornare i dati (acceleratore tramite tocco)Pull to refresh data (touch accelerator)
    • Tasti di scelta rapida (acceleratore tramite tastiera)Keyboard shortcuts (keyboard accelerator)
    • Tasti di scelta (acceleratore tramite tastiera)Access keys (keyboard accelerator)
    • Pulsanti attivati al passaggio del mouse e della penna (acceleratore tramite puntatore)Mouse & Pen hover buttons (pointer accelerator)

Nota

Gli utenti dovrebbero essere in grado di accedere a tutti i comandi da qualsiasi tipo di dispositivo.Users should be able to access all commands from any type of device. Ad esempio, se i comandi dell'app sono esposti unicamente attraverso gli acceleratori tramite puntatore (pulsanti attivati al passaggio del mouse), gli utenti che usano il tocco non saranno in grado di accedervi.For example, if your app’s commands are only exposed through hover button pointer accelerators, touch users won't be able to access them. Usa almeno un menu di scelta rapida per rendere possibile l'accesso a tutti i comandi.At a minimum, use a context menu to provide access to all commands.

Esempio: modello di dati PodcastObjectExample: The PodcastObject data model

Al fine di illustrare i nostri consigli relativi all'esecuzione dei comandi, in questo articolo viene creato un elenco di podcast per un'app Podcast.To demonstrate our commanding recommendations, this article creates a list of podcasts for a podcast app. Il codice di esempio illustra come permettere all'utente di segnare un particolare podcast come "preferito" all'interno di un elenco.The example code demonstrate how to enable the user to "favorite" a particular podcast from a list.

Questa è la definizione dell'oggetto podcast che verrà usato:Here's the definition for the podcast object we'll be working with:

public class PodcastObject : INotifyPropertyChanged
{
    // The title of the podcast
    public String Title { get; set; }

    // The podcast's description
    public String Description { get; set; }

    // Describes if the user has set this podcast as a favorite
    public bool IsFavorite
    {
        get
        {
            return _isFavorite;
        }
        set
        {
            _isFavorite = value;
            OnPropertyChanged("IsFavorite");
        }
    }
    private bool _isFavorite = false;

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(String property)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
}

Tieni presente che PodcastObject implementa INotifyPropertyChanged per rispondere alle modifiche di proprietà quando l'utente attiva o disattiva la proprietà IsFavorite.Notice that the PodcastObject implements INotifyPropertyChanged to respond to property changes when the user toggles the IsFavorite property.

Definizione dei comandi con l'interfaccia ICommandDefining commands with the ICommand interface

L'interfaccia ICommand è utile per definire un comando che sia disponibile per diversi tipi di input.The ICommand interface helps you to define a command that's available for multiple input types. Ad esempio, piuttosto che scrivere lo stesso codice per un comando di eliminazione in due gestori di eventi diversi, uno per quando l'utente preme il tasto CANC e uno per quando fa clic con il pulsante destro del mouse su "Elimina" in un menu di scelta rapida, puoi implementare la logica di eliminazione una sola volta, sotto forma di ICommand, e quindi renderla disponibile per diversi tipi di input.For example, instead of writing the same code for a delete command in two different event handlers, one for when the user presses the Delete key and one for when the user right clicks "Delete" in a context menu, you can implement your delete logic once, as an ICommand, and then make it available to different input types.

Dobbiamo definire l'interfaccia ICommand che rappresenta l'azione "Segna come preferito".We need to define the ICommand that represents the "Favorite" action. Useremo il metodo del comando Execute per contrassegnare un podcast come preferito.We will use the command's Execute method to favorite a podcast. Questo particolare podcast sarà reso disponibile per il metodo di esecuzione attraverso il parametro del comando, che può essere associato tramite la proprietà CommandParameter.The particular podcast will be provided to the execute method via the command's parameter, which can be bound using the CommandParameter property.

public class FavoriteCommand: ICommand
{
    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }
    public void Execute(object parameter)
    {
        // Perform the logic to "favorite" an item.
        (parameter as PodcastObject).IsFavorite = true;
    }
}

Per usare lo stesso comando con diverse raccolte ed elementi, puoi archiviarlo come una risorsa nella pagina o nell'app.To use the same command with multiple collections and elements, you can store the command as a resource on the page or on the app.

<Application.Resources>
    <local:FavoriteCommand x:Key="favoriteCommand" />
</Application.Resources>

Per eseguire il comando, devi chiamare il metodo Execute correlato.To execute the command, you call its Execute method.

// Favorite the item using the defined command
var favoriteCommand = Application.Current.Resources["favoriteCommand"] as ICommand;
favoriteCommand.Execute(PodcastObject);

Creazione di un elemento UserControl per rispondere a una varietà di inputCreating a UserControl to respond to a variety of inputs

Quando hai un elenco di elementi, ognuno dei quali deve rispondere a più input, puoi semplificare il codice definendo un UserControl per l'elemento e usandolo per definire il menu di scelta rapida degli elementi e i gestori di eventi.When you have a list of items and each of those items should respond to multiple inputs, you can simplify your code by defining a UserControl for the item and using it to define your items' context menu and event handlers.

Per creare un elemento UserControl in Visual Studio:To create a UserControl in Visual Studio:

  1. In Esplora soluzioni fai clic con il pulsante destro del mouse sul progetto.In the Solution Explorer, right click the project. Viene visualizzato un menu di scelta rapida.A context menu appears.
  2. Seleziona Aggiungi > Nuovo elemento.Select Add > New Item...
    Viene visualizzata la finestra di dialogo Aggiungi nuovo elemento.The Add New Item dialog appears.
  3. Seleziona UserControl dall'elenco di elementi.Select UserControl from the list of items. Assegnagli il nome che vuoi e fai clic su Aggiungi.Give it the name you want and click Add. Visual Studio genererà automaticamente uno stub UserControl.Visual Studio will generate a stub UserControl for you.

Nel podcast di esempio ogni podcast sarà visualizzato all'interno di un elenco che esporrà un'ampia varietà di modi per contrassegnare un podcast come "Preferito".In our podcast example, each podcast will be displayed in a list, which will expose a variety of ways to "Favorite" a podcast. L'utente potrà eseguire le azioni seguenti per contrassegnare il podcast come "Preferito":The user will be able to perform the following actions to "Favorite" the podcast:

  • Richiamare un menu di scelta rapidaInvoke a context menu
  • Usare i tasti di scelta rapidaPerform keyboard shortcuts
  • Mostrare un pulsante che si attiva al passaggio del mouseShow a hover button
  • Eseguire un movimento di scorrimento rapidoPerform a swipe gesture

Per incapsulare questi comportamenti e usare il FavoriteCommand, creeremo un UserControl denominato "PodcastUserControl" per rappresentare un podcast nell'elenco.In order to encapsulate these behaviors and use the FavoriteCommand, let's create a new UserControl named "PodcastUserControl" to represent a podcast in the list.

Il PodcastUserControl visualizza i campi del PodcastObject come oggetti TextBlock e risponde a diverse interazioni da parte dell'utente.The PodcastUserControl displays the fields of the PodcastObject as TextBlocks, and responds to various user interactions. In questo articolo faremo riferimento e amplieremo l'argomento del PodcastUserControl.We will reference and expand upon the PodcastUserControl throughout this article.

PodcastUserControl.xamlPodcastUserControl.xaml

<UserControl
    x:Class="ContextCommanding.PodcastUserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    IsTabStop="True" UseSystemFocusVisuals="True"
    >
    <Grid Margin="12,0,12,0">
        <StackPanel>
            <TextBlock Text="{x:Bind PodcastObject.Title, Mode=OneWay}" Style="{StaticResource TitleTextBlockStyle}" />
            <TextBlock Text="{x:Bind PodcastObject.Description, Mode=OneWay}" Style="{StaticResource SubtitleTextBlockStyle}" />
            <TextBlock Text="{x:Bind PodcastObject.IsFavorite, Mode=OneWay}" Style="{StaticResource SubtitleTextBlockStyle}"/>
        </StackPanel>
    </Grid>
</UserControl>

PodcastUserControl.xaml.csPodcastUserControl.xaml.cs

public sealed partial class PodcastUserControl : UserControl
{
    public static readonly DependencyProperty PodcastObjectProperty =
        DependencyProperty.Register(
            "PodcastObject",
            typeof(PodcastObject),
            typeof(PodcastUserControl),
            new PropertyMetadata(null));

    public PodcastObject PodcastObject
    {
        get { return (PodcastObject)GetValue(PodcastObjectProperty); }
        set { SetValue(PodcastObjectProperty, value); }
    }

    public PodcastUserControl()
    {
        this.InitializeComponent();

        // TODO: We will add event handlers here.
    }
}

Il PodcastUserControl conserva un riferimento al PodcastObject come DependencyProperty.Notice that the PodcastUserControl maintains a reference to the PodcastObject as a DependencyProperty. Ciò consente di eseguire il binding di PodcastObject al PodcastUserControl.This enables us to bind PodcastObjects to the PodcastUserControl.

Dopo aver generato alcuni PodcastObject, puoi creare un elenco di podcast eseguendo il binding dei PodcastObject a una ListView.After you have generated some PodcastObjects, you can create a list of podcasts by binding the PodcastObjects to a ListView. Gli oggetti PodcastUserControl descrivono la visualizzazione dei PodcastObject e sono pertanto impostati mediante la proprietà ItemTemplate di ListView.The PodcastUserControl objects describe the visualization of the PodcastObjects, and are therefore set using the ListView's ItemTemplate.

MainPage.xamlMainPage.xaml

<ListView x:Name="ListOfPodcasts"
            ItemsSource="{x:Bind podcasts}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local:PodcastObject">
            <local:PodcastUserControl PodcastObject="{x:Bind Mode=OneWay}" />
        </DataTemplate>
    </ListView.ItemTemplate>
    <ListView.ItemContainerStyle>
        <!-- The PodcastUserControl will entirely fill the ListView item and handle tabbing within itself. -->
        <Style TargetType="ListViewItem" BasedOn="{StaticResource ListViewItemRevealStyle}">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
            <Setter Property="Padding" Value="0"/>
            <Setter Property="IsTabStop" Value="False"/>
        </Style>
    </ListView.ItemContainerStyle>
</ListView>

Creazione di menu di scelta rapidaCreating context menus

I menu di scelta rapida mostrano un elenco di comandi o opzioni quando l'utente li richiede.Context menus display a list of commands or options when the user requests them. I menu di scelta rapida forniscono i comandi contestuali correlati all'elemento associato e sono solitamente riservati per azioni secondarie specifiche di quel determinato elemento.Context menus provide contextual commands related to their attached element, and are generally reserved for secondary actions specific to that item.

Visualizzare un menu di scelta rapida sull'elemento

L'utente può richiamare i menu di scelta rapida usando queste "azioni contestuali":The user can invoke context menus using these "context actions":

InputInput Azione contestualeContext action
MouseMouse Fare clicRight click
TastieraKeyboard MAIUSC+F10, pulsante MenuShift+F10, Menu button
ToccoTouch Pressione prolungata sull'elementoLong press on item
PennaPen Pressione sul pulsante della penna, pressione prolungata sull'elementoBarrel button press, long press on item
Game padGamepad Pulsante MenuMenu button

Dal momento che l'utente può aprire un menu di scelta rapida indipendentemente dal tipo di input, il menu di scelta rapida dovrebbe contenere tutti i comandi contestuali disponibili per l'elemento di elenco.Since the user can open a context menu regardless of input type, your context menu should contain all of the contextual commands available for the list item.

ContextFlyoutContextFlyout

La proprietà ContextFlyout, definita dalla classe UIElement, rende più agevole la creazione di un menu di scelta rapida che funzioni con tutti i tipi di input.The ContextFlyout property, defined by the UIElement class, makes it easy to create a context menu that works with all input types. Devi fornire un riquadro a comparsa che rappresenti il menu di scelta rapida usando MenuFlyout. Quando l'utente esegue un'azione contestuale, come da descrizione predente, viene visualizzato il MenuFlyout corrispondente all'elemento in questione.You provide a flyout representing your context menu using MenuFlyout, and when the user performs a “context action” as defined above, the MenuFlyout corresponding to the item will be displayed.

Aggiungeremo un ContextFlyout al PodcastUserControl.We will add a ContextFlyout to the PodcastUserControl. Il MenuFlyout specificato come ContextFlyout contiene un singolo elemento per segnare un podcast come preferito.The MenuFlyout specified as the ContextFlyout contains a single item to favorite a podcast. Questo MenuFlyoutItem usa il favoriteCommand definito in precedenza, con il CommandParamter associato al PodcastObject.Notice that this MenuFlyoutItem uses the favoriteCommand defined above, with the CommandParamter bound to the PodcastObject.

PodcastUserControl.xamlPodcastUserControl.xaml

<UserControl>
    <UserControl.ContextFlyout>
        <MenuFlyout>
            <MenuFlyoutItem Text="Favorite" Command="{StaticResource favoriteCommand}" CommandParameter="{x:Bind PodcastObject, Mode=OneWay}" />
        </MenuFlyout>
    </UserControl.ContextFlyout>
    <Grid Margin="12,0,12,0">
        <!-- ... -->
    </Grid>
</UserControl>

Puoi anche usare l'evento ContextRequested per rispondere alle azioni contestuali.Note that you can also use the ContextRequested event to respond to context actions. L'evento ContextRequested non viene generato se è stato specificato un ContextFlyout.The ContextRequested event will not fire if a ContextFlyout has been specified.

Creazione di acceleratori per inputCreating input accelerators

Sebbene ogni elemento nella raccolta debba avere un menu di scelta rapida contenente tutti i comandi contestuali, puoi consentire agli utenti di eseguire rapidamente un insieme più limitato di comandi usati di frequente.Although each item in the collection should have a context menu containing all contextual commands, you might want to enable users to quickly perform a smaller set of frequently performed commands. Ad esempio, un'app di posta elettronica potrebbe avere comandi secondari, come Rispondi, Archivia, Sposta nella cartella, Imposta contrassegno ed Elimina, che sono visualizzati nel menu di scelta rapida, ma i comandi più comuni sono Elimina e Contrassegna.For example, a mailing app may have secondary commands like Reply, Archive, Move to Folder, Set Flag, and Delete which appear in a context menu, but the most common commands are Delete and Flag. Una volta identificati i comandi più comuni, puoi usare gli acceleratori basati su input per rendere più semplice agli utenti l'esecuzione di tali comandi.After you have identified which commands are most common, you can use input-based accelerators to make these commands easier for a user to perform.

Nell'app Podcast, il comando eseguito più di frequente è quello che contrassegna un elemento come"Preferito".In the podcast app, the frequently performed command is the "Favorite" command.

Acceleratori tramite tastieraKeyboard accelerators

Gestione dei tasti di scelta rapida e dei tasti direttiShortcuts and direct key handling

Premere CTRL+F per eseguire un'azione

A seconda del tipo di contenuto, puoi identificare determinate combinazioni di tasti che consentono di eseguire un'azione.Depending on the type of content, you may identify certain key combinations that should perform an action. Ad esempio, in un'app di posta elettronica il tasto CANC potrebbe essere usato per eliminare il messaggio di posta elettronica selezionato.In an email app, for example, the DEL key may be used to delete the email that is selected. In un'app Podcast, i tasti CTRL+S o F potrebbero essere usati per segnare un podcast come preferito per un utilizzo successivo.In a podcast app, the Ctrl+S or F keys could favorite a podcast for later. Benché alcuni comandi abbiano tasti di scelta rapida comuni e ben noti, come CANC per eliminare, altri comandi hanno tasti di scelta rapida specifici dell'app o del dominio.Although some commands have common, well-known keyboard shortcuts like DEL to delete, other commands have app- or domain-specific shortcuts. Se possibile, usa collegamenti ben noti oppure specifica un testo di promemoria in una descrizione comando per spiegare all'utente cosa fa il comando di scelta rapida.Use well-known shortcuts if possible, or consider providing reminder text in a tooltip to teach the user about the shortcut command.

L'app può rispondere quando l'utente preme un tasto usando l'evento KeyDown.Your app can respond when the user presses a key using the KeyDown event. In generale, gli utenti si aspettano che l'app risponda appena premono il tasto, invece di aspettare che il tasto venga rilasciato.In general, users expect that the app will respond when they first press the key down, rather than waiting until they release the key.

Questo esempio illustra come aggiungere il gestore KeyDown al PodcastUserControl per contrassegnare un podcast come preferito quando l'utente preme CTRL+ S o F. Usa lo stesso comando usato in precedenza.This example walks through how to add the KeyDown handler to the PodcastUserControl to favorite a podcast when the user presses Ctrl+S or F. It uses the same command as before.

PodcastUserControl.xaml.csPodcastUserControl.xaml.cs

// Respond to the F and Ctrl+S keys to favorite the focused item.
protected override void OnKeyDown(KeyRoutedEventArgs e)
{
    var ctrlState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Control);
    var isCtrlPressed = (ctrlState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down || (ctrlState & CoreVirtualKeyStates.Locked) == CoreVirtualKeyStates.Locked;

    if (e.Key == Windows.System.VirtualKey.F || (e.Key == Windows.System.VirtualKey.S && isCtrlPressed))
    {
        // Favorite the item using the defined command
        var favoriteCommand = Application.Current.Resources["favoriteCommand"] as ICommand;
        favoriteCommand.Execute(PodcastObject);
    }
}

Acceleratori tramite mouseMouse accelerators

Passare il puntatore del mouse su un elemento per visualizzare un pulsante

Gli utenti hanno familiarità con i menu di scelta rapida che compaiono facendo clic con il pulsante destro del mouse, tuttavia potresti voler consentire agli utenti di eseguire i comandi più comuni con un semplice clic del mouse.Users are familiar with right-click context menus, but you may wish to empower users to perform common commands using only a single click of the mouse. Per abilitare questa esperienza, puoi includere pulsanti dedicati nel canvas dell'elemento della raccolta.To enable this experience, you can include dedicated buttons on your collection item's canvas. Per consentire agli utenti di agire rapidamente mediante il mouse e per ridurre al minimo la confusione visiva, puoi scegliere di visualizzare questi pulsanti solo quando l'utente posiziona il puntatore all'interno di uno specifico elemento elenco.To both empower users to act quickly using mouse, and to minimize visual clutter, you can choose to only reveal these buttons when the user has their pointer within a particular list item.

In questo esempio, il comando Preferito è rappresentato da un pulsante definito direttamente nel PodcastUserControl.In this example, the Favorite command is represented by a button defined directly in the PodcastUserControl. Nota che il pulsante in questo esempio usa lo stesso comando, FavoriteCommand, usato in precedenza.Note that the button in this example uses the same command, FavoriteCommand, as before. Per attivare o disattivare la visibilità di questo pulsante, puoi usare VisualStateManager per spostarti tra gli stati di visualizzazione quando il puntatore entra ed esce dal controllo.To toggle visibility of this button, you can use the VisualStateManager to switch between visual states when the pointer enters and exits the control.

PodcastUserControl.xamlPodcastUserControl.xaml

<UserControl>
    <UserControl.ContextFlyout>
        <!-- ... -->
    </UserControl.ContextFlyout>
    <Grid Margin="12,0,12,0">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="HoveringStates">
                <VisualState x:Name="HoverButtonsShown">
                    <VisualState.Setters>
                        <Setter Target="hoverArea.Visibility" Value="Visible" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="HoverButtonsHidden" />
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <StackPanel>
            <TextBlock Text="{x:Bind PodcastObject.Title, Mode=OneWay}" Style="{StaticResource TitleTextBlockStyle}" />
            <TextBlock Text="{x:Bind PodcastObject.Description, Mode=OneWay}" Style="{StaticResource SubtitleTextBlockStyle}" />
            <TextBlock Text="{x:Bind PodcastObject.IsFavorite, Mode=OneWay}" Style="{StaticResource SubtitleTextBlockStyle}"/>
        </StackPanel>
        <Grid Grid.Column="1" x:Name="hoverArea" Visibility="Collapsed" VerticalAlignment="Stretch">
            <AppBarButton Icon="OutlineStar" Label="Favorite" Command="{StaticResource favoriteCommand}" CommandParameter="{x:Bind PodcastObject, Mode=OneWay}" IsTabStop="False" VerticalAlignment="Stretch"  />
        </Grid>
    </Grid>
</UserControl>

I pulsanti che si attivano al passaggio del mouse dovrebbero comparire e scomparire quando il mouse entra ed esce dall'elemento.The hover buttons should appear and disappear when the mouse enters and exits the item. Per rispondere agli eventi del mouse, puoi usare gli eventi PointerEntered e PointerExited nel PodcastUserControl.To respond to mouse events, you can use the PointerEntered and PointerExited events on the PodcastUserControl.

PodcastUserControl.xaml.csPodcastUserControl.xaml.cs

protected override void OnPointerEntered(PointerRoutedEventArgs e)
{
    base.OnPointerEntered(e);

    // Only show hover buttons when the user is using mouse or pen.
    if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse || e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Pen)
    {
        VisualStateManager.GoToState(this, "HoverButtonsShown", true);
    }
}

protected override void OnPointerExited(PointerRoutedEventArgs e)
{
    base.OnPointerExited(e);

    VisualStateManager.GoToState(this, "HoverButtonsHidden", true);
}

I pulsanti visualizzati nello stato di passaggio del mouse saranno accessibili solo mediante il tipo di input del puntatore.The buttons displayed in the hover state will only be accessible via the pointer input type. Dato che questi pulsanti sono limitati all'input del puntatore, puoi scegliere di ridurre al minimo o rimuovere la spaziatura attorno all'icona del pulsante per ottimizzare l'input del puntatore.Because these buttons are limited to pointer input, you may choose to minimize or remove the padding around the icon of the button to optimize for pointer input. In tal caso, verifica che la superficie del pulsante sia di almeno 20x20 px in modo che resti utilizzabile con penna e mouse.If you choose to do so, ensure that the button footprint is at least 20x20px to remain usable with pen and mouse.

Acceleratori tramite toccoTouch accelerators

Scorrimento rapidoSwipe

Scorrere rapidamente su un elemento per visualizzare il comando

L'esecuzione del comando di scorrimento rapido è un acceleratore di tocco che consente agli utenti di dispositivi con touchscreen di eseguire comuni azioni secondarie mediante il tocco.Swipe commanding is a touch accelerator that enables users on touch devices to perform common secondary actions using touch. Lo scorrimento rapido permette agli utenti di touchscreen di interagire in modo rapido e naturale con il contenuto usando azioni comuni, come Scorrere per eliminare o Scorrere per richiamare.Swipe empowers touch users to quickly and naturally interact with content, using common actions like Swipe-to-Delete or Swipe-to-Invoke. Per altre informazioni, vedi l'articolo Swipe.See the swipe commanding article to learn more.

Per integrare lo scorrimento rapido nella raccolta sono necessari due componenti: SwipeItems, che ospita i comandi, e un SwipeControl, che esegue il wrapping dell'elemento e consente l'interazione mediante scorrimento rapido.In order to integrate swipe into your collection, you need two components: SwipeItems, which hosts the commands; and a SwipeControl, which wraps the item and allows for swipe interaction.

SwipeItems può essere definito come risorsa in PodcastUserControl.The SwipeItems can be defined as a Resource in the PodcastUserControl. In questo esempio, SwipeItems contiene un comando per contrassegnare un elemento come preferito.In this example, SwipeItems contains a command to Favorite an item.

<UserControl.Resources>
    <SymbolIconSource x:Key="FavoriteIcon" Symbol="Favorite"/>
    <SwipeItems x:Key="RevealOtherCommands" Mode="Reveal">
        <SwipeItem IconSource="{StaticResource FavoriteIcon}" Text="Favorite" Background="Yellow" Invoked="SwipeItem_Invoked"/>
    </SwipeItems>
</UserControl.Resources>

SwipeControl esegue il wrapping dell'elemento e consente all'utente di interagire con esso con il movimento di scorrimento rapido.The SwipeControl wraps the item and allows the user to interact with it using the swipe gesture. SwipeControl contiene un riferimento a SwipeItems come RightItems associato.Notice that the SwipeControl contains a reference to the SwipeItems as its RightItems. Quando l'utente scorre rapidamente da destra a sinistra, l'elemento impostato come preferito viene visualizzato.The Favorite item will show when the user swipes from right to left.

<SwipeControl x:Name="swipeContainer" RightItems="{StaticResource RevealOtherCommands}">
   <!-- The visual state groups moved from the Grid to the SwipeControl, since the SwipeControl wraps the Grid. -->
   <VisualStateManager.VisualStateGroups>
       <VisualStateGroup x:Name="HoveringStates">
           <VisualState x:Name="HoverButtonsShown">
               <VisualState.Setters>
                   <Setter Target="hoverArea.Visibility" Value="Visible" />
               </VisualState.Setters>
           </VisualState>
           <VisualState x:Name="HoverButtonsHidden" />
       </VisualStateGroup>
   </VisualStateManager.VisualStateGroups>
   <Grid Margin="12,0,12,0">
       <Grid.ColumnDefinitions>
           <ColumnDefinition Width="*" />
           <ColumnDefinition Width="Auto" />
       </Grid.ColumnDefinitions>
       <StackPanel>
           <TextBlock Text="{x:Bind PodcastObject.Title, Mode=OneWay}" Style="{StaticResource TitleTextBlockStyle}" />
           <TextBlock Text="{x:Bind PodcastObject.Description, Mode=OneWay}" Style="{StaticResource SubtitleTextBlockStyle}" />
           <TextBlock Text="{x:Bind PodcastObject.IsFavorite, Mode=OneWay}" Style="{StaticResource SubtitleTextBlockStyle}"/>
       </StackPanel>
       <Grid Grid.Column="1" x:Name="hoverArea" Visibility="Collapsed" VerticalAlignment="Stretch">
           <AppBarButton Icon="OutlineStar" Command="{StaticResource favoriteCommand}" CommandParameter="{x:Bind PodcastObject, Mode=OneWay}" IsTabStop="False" LabelPosition="Collapsed" VerticalAlignment="Stretch"  />
       </Grid>
   </Grid>
</SwipeControl>

Quando l'utente scorre rapidamente per richiamare il comando Preferito, viene chiamato il metodo Invoked.When the user swipes to invoke the Favorite command, the Invoked method is called.

private void SwipeItem_Invoked(SwipeItem sender, SwipeItemInvokedEventArgs args)
{
    // Favorite the item using the defined command
    var favoriteCommand = Application.Current.Resources["favoriteCommand"] as ICommand;
    favoriteCommand.Execute(PodcastObject);
}

Aggiornamento tramite trascinamento verso il bassoPull to refresh

L'aggiornamento tramite trascinamento verso il basso consente a un utente di trascinare verso il basso una raccolta di dati tramite tocco per recuperare più dati.Pull to refresh lets a user pull down on a collection of data using touch in order to retrieve more data. Per altre informazioni, vedi l'articolo Aggiornamento tramite trascinamento verso il basso.See the pull to refresh article to learn more.

Acceleratori basati su pennaPen accelerators

Il tipo di input penna offre la precisione dell'input del puntatore.The pen input type provides the precision of pointer input. Gli utenti possono eseguire operazioni comuni, come l'apertura di menu di scelta rapida, usando acceleratori basati su penna.Users can perform common actions such as opening context menus using pen-based accelerators. Per aprire un menu di scelta rapida, gli utenti possono toccare lo schermo tenendo premuto il pulsante della penna o mediante una pressione prolungata sul contenuto.To open a context menu, users can tap the screen with the barrel button pressed, or long press on the content. Gli utenti possono anche usare la penna per passare su un contenuto per ottenere informazioni più approfondite dell'interfaccia utente, ad esempio mediante la visualizzazione di descrizioni comando, oppure per visualizzare azioni al passaggio del puntatore secondarie, simili a quelle eseguite con il mouse.Users can also use the pen to hover over content to get a deeper understanding of the UI like displaying tooltips, or to reveal secondary hover actions, similar to mouse.

Per ottimizzare l'app per l'input penna, vedi l'articolo Interazioni tramite penna e Windows Ink nelle app UWP.To optimize your app for pen input, see the pen and stylus interaction article.

Cosa fare e cosa non fareDo's and don'ts

  • Assicurati che gli utenti possano accedere a tutti i comandi da qualsiasi tipo di dispositivo di Windows.Do make sure that users can access all commands from all types of Windows devices.
  • Includi un menu di scelta rapida che fornisca accesso a tutti i comandi disponibili per un elemento della raccolta.Do include a context menu that provides access to all the commands available for a collection item.
  • Fornisci acceleratori di input per i comandi usati di frequente.Do provide input accelerators for frequently-used commands.
  • Usa l'interfaccia ICommand per implementare i comandi.Do use the ICommand interface to implement commands.