Comandos contextuais para coleções e listasContextual commanding for collections and lists

Muitos aplicativos contêm coleções de conteúdo na forma de listas, grades e árvores que os usuários podem manipular.Many apps contain collections of content in the form of lists, grids, and trees that users can manipulate. Por exemplo, os usuários podem excluir, renomear, sinalizar ou atualizar os itens.For example, users might be able to delete, rename, flag, or refresh items. Este artigo mostra como usar os comandos contextuais para implementar esses tipos de ações de maneira que proporcione a melhor experiência possível para todos os tipos de entrada.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.

APIs importantes: interface ICommand, propriedade UIElement.ContextFlyout, interface INotifyPropertyChangedImportant APIs: ICommand interface, UIElement.ContextFlyout property, INotifyPropertyChanged interface

Usar uma variedade de entradas para executar o comando de favorito

Criar comandos para todos os tipos de entradaCreating commands for all input types

Como os usuários podem interagir com um aplicativo do Windows usando uma ampla variedade de dispositivos e entradas, o aplicativo deve expor comandos por meio de menus de contexto independentes do tipo de entrada e aceleradores de entrada específicos.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. A inclusão de ambos permite que o usuário invoque rapidamente comandos no conteúdo, independentemente do tipo de entrada ou dispositivo.Including both lets the user quickly invoke commands on content, regardless of input or device type.

Esta tabela mostra alguns comandos típicos de coleção e os modos de expô-los.This table shows some typical collection commands and ways to expose those commands.

ComandoCommand Independentes do tipo de entradaInput-agnostic Acelerador de mouseMouse accelerator Acelerador de tecladoKeyboard accelerator Acelerador de toqueTouch accelerator
Excluir itemDelete item Menu de contextoContext menu Botão FocalizarHover button Tecla DELDEL key Deslizar o dedo para excluirSwipe to delete
Sinalizar itemFlag item Menu de contextoContext menu Botão FocalizarHover button Ctrl+Shift+GCtrl+Shift+G Deslizar o dedo para sinalizarSwipe to flag
Atualizar dadosRefresh data Menu de contextoContext menu N/DN/A Tecla F5F5 key Puxar para atualizarPull to refresh
Adicionar item a FavoritosFavorite an item Menu de contextoContext menu Botão FocalizarHover button F, Ctrl+SF, Ctrl+S Deslizar o dedo para adicionar a FavoritosSwipe to favorite
  • Em geral, você deve disponibilizar todos os comandos de um item no menu de contexto do item.In general, you should make all commands for an item available in the item's context menu. Os menus de contexto são acessíveis aos usuários independentemente do tipo de entrada e devem conter todos os comandos contextuais que o usuário pode executar.Context menus are accessible to users regardless of input type, and should contain all of the contextual commands that user can perform.

  • Para comandos acessados com frequência, considere o uso de aceleradores de entrada.For frequently accessed commands, consider using input accelerators. Os aceleradores de entrada permitem que o usuário execute ações rapidamente com base nos dispositivos de entrada.Input accelerators let the user perform actions quickly, based on their input device. Os aceleradores de entrada incluem:Input accelerators include:

    • Ação de deslizar o dedo (acelerador de toque)Swipe-to-action (touch accelerator)
    • Deslizar para atualizar dados (acelerador de toque)Pull to refresh data (touch accelerator)
    • Atalhos de teclado (acelerador de teclado)Keyboard shortcuts (keyboard accelerator)
    • Teclas de acesso (acelerador de teclado)Access keys (keyboard accelerator)
    • Botões de foco de mouse e caneta (acelerador de ponteiro)Mouse & Pen hover buttons (pointer accelerator)

Observação

Os usuários devem ser capazes de acessar todos os comandos de qualquer tipo de dispositivo.Users should be able to access all commands from any type of device. Por exemplo, se os comandos do aplicativo forem expostos somente por meio de aceleradores de ponteiro do botão de foco, os usuários de toque não poderão acessá-los.For example, if your app’s commands are only exposed through hover button pointer accelerators, touch users won't be able to access them. No mínimo, use um menu de contexto para fornecer acesso a todos os comandos.At a minimum, use a context menu to provide access to all commands.

Exemplo: o modelo de dados PodcastObjectExample: The PodcastObject data model

Para demonstrar nossas recomendações de comandos, este artigo cria uma lista de podcasts para um aplicativo de podcast.To demonstrate our commanding recommendations, this article creates a list of podcasts for a podcast app. O exemplo de código demonstra como permitir que o usuário salve como "favorito" um podcast específico de uma lista.The example code demonstrate how to enable the user to "favorite" a particular podcast from a list.

Esta é a definição do objeto de podcast com a qual trabalharemos: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));
    }
}

Observe que PodcastObject implementa INotifyPropertyChanged para responder às alterações de propriedade quando o usuário alterna a propriedade IsFavorite.Notice that the PodcastObject implements INotifyPropertyChanged to respond to property changes when the user toggles the IsFavorite property.

Definição de comandos com a interface ICommandDefining commands with the ICommand interface

A interface ICommand ajuda você a definir um comando que está disponível para vários tipos de entrada.The ICommand interface helps you to define a command that's available for multiple input types. Por exemplo, em vez de escrever o mesmo código para um comando de exclusão nos dois manipuladores de eventos diferentes, um para quando o usuário pressiona a tecla Delete e outro para quando o usuário clica com o botão direito do mouse em "Excluir" em um menu de contexto, você pode implementar a lógica de exclusão uma vez como um ICommande, em seguida, torná-lo disponível para diferentes tipos de entrada.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.

É necessário definir o ICommand que representa a ação "Favoritos".We need to define the ICommand that represents the "Favorite" action. Vamos usar o método Execute do comando para incluir o podcast nos favoritos.We will use the command's Execute method to favorite a podcast. O podcast específico será fornecido para o método Execute por meio do parâmetro do comando, que pode ser associado usando a propriedade 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;
    }
}

Para usar o mesmo comando com vários elementos e coleções, você pode armazená-lo como um recurso na página ou no aplicativo.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>

Para executar o comando, chame o método Execute.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);

Criar um UserControl para responder a diversas entradasCreating a UserControl to respond to a variety of inputs

Quando você tiver uma lista de itens e cada um deve responder a várias entradas, é possível simplificar o código ao definir um UserControl para o item e usá-lo para definir manipuladores de eventos e o menu de contexto dos itens.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.

Para criar um UserControl no Visual Studio:To create a UserControl in Visual Studio:

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto.In the Solution Explorer, right click the project. Um menu de contexto aparecerá.A context menu appears.
  2. Selecione Adicionar > Novo Item...Select Add > New Item...
    A caixa de diálogo Adicionar Novo Item aparecerá.The Add New Item dialog appears.
  3. Selecione UserControl na lista de itens.Select UserControl from the list of items. Dê o nome que você deseja e clique em Adicionar.Give it the name you want and click Add. O Visual Studio gerará um stub UserControl para você.Visual Studio will generate a stub UserControl for you.

No exemplo do podcast, cada um será exibido em uma lista, o que expõe diversas maneiras de incluir um podcast nos "Favoritos".In our podcast example, each podcast will be displayed in a list, which will expose a variety of ways to "Favorite" a podcast. O usuário poderá executar as seguintes ações para incluir o podcast nos "Favoritos":The user will be able to perform the following actions to "Favorite" the podcast:

  • Invocar um menu de contextoInvoke a context menu
  • Executar atalhos de tecladoPerform keyboard shortcuts
  • Mostrar um botão de focoShow a hover button
  • Executar um gesto de deslizar o dedoPerform a swipe gesture

Para encapsular esses comportamentos e usar o FavoriteCommand, vamos criar um novo UserControl chamado "PodcastUserControl" para representar um podcast na lista.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.

O PodcastUserControl exibe os campos do PodcastObject como TextBlocks e responde a diversas interações do usuário.The PodcastUserControl displays the fields of the PodcastObject as TextBlocks, and responds to various user interactions. Abordaremos a referência e explicaremos melhor o PodcastUserControl neste artigo.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.
    }
}

Observe que o PodcastUserControl mantém uma referência ao PodcastObject como uma DependencyProperty.Notice that the PodcastUserControl maintains a reference to the PodcastObject as a DependencyProperty. Isso nos permite associar PodcastObjects ao PodcastUserControl.This enables us to bind PodcastObjects to the PodcastUserControl.

Depois de gerar alguns PodcastObjects, você pode criar uma lista de podcasts ao associar PodcastObjects a um ListView.After you have generated some PodcastObjects, you can create a list of podcasts by binding the PodcastObjects to a ListView. Os objetos PodcastUserControl descrevem a visualização do PodcastObjects e, portanto, são definidos usando o ItemTemplate do 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>

Criar menus de contextoCreating context menus

Os menus de contexto exibem uma lista de comandos ou opções quando o usuário as solicita.Context menus display a list of commands or options when the user requests them. Os menus de contexto fornecem comandos contextuais relacionados ao elemento anexado e, em geral, são reservados para ações secundárias específicas desse item.Context menus provide contextual commands related to their attached element, and are generally reserved for secondary actions specific to that item.

Mostrar um menu de contexto no item

O usuário pode invocar os menus de contexto usando essas "ações de contexto":The user can invoke context menus using these "context actions":

EntradaInput Ação de contextoContext action
MouseMouse Clicar com o botão direito do mouseRight click
KeyboardKeyboard Shift+F10, botão de menuShift+F10, Menu button
TouchTouch Pressionamento longo em itemLong press on item
CanetaPen Pressionamento de botão da caneta, um pressionamento longo em itemBarrel button press, long press on item
GamepadGamepad Botão MenuMenu button

Como o usuário pode abrir um menu de contexto independentemente do tipo de entrada, o menu de contexto deve conter todos os comandos contextuais disponíveis para o item de lista.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

A propriedade ContextFlyout, definida pela classe UIElement, facilita a criação de um menu de contexto que funciona com todos os tipos de entrada.The ContextFlyout property, defined by the UIElement class, makes it easy to create a context menu that works with all input types. Você fornece um submenu que representa o menu de contexto que usa MenuFlyout e, quando o usuário executa uma "ação de contexto" conforme definido acima, o MenuFlyout correspondente ao item será exibido.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.

Adicionaremos um ContextFlyout ao PodcastUserControl.We will add a ContextFlyout to the PodcastUserControl. O MenuFlyout especificado como ContextFlyout contém um único item para incluir um podcast nos favoritos.The MenuFlyout specified as the ContextFlyout contains a single item to favorite a podcast. Observe que este MenuFlyoutItem usa o favoriteCommand definido acima, com o CommandParamter associado a 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>

Observe que você também pode usar o evento ContextRequested para responder às ações de contexto.Note that you can also use the ContextRequested event to respond to context actions. O evento ContextRequested não será acionado se um ContextFlyout tiver sido especificado.The ContextRequested event will not fire if a ContextFlyout has been specified.

Criar aceleradores de entradaCreating input accelerators

Embora cada item da coleção deva ter um menu de contexto com todos os comandos contextuais, convém permitir que os usuários realizem rapidamente um conjunto menor de comandos realizados com frequência.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. Por exemplo, um aplicativo de endereçamento pode ter comandos secundários como Responder, Arquivar, Mover para pasta, Definir sinalizador e Excluir que aparecem em um menu de contexto, mas os comandos mais comuns são Excluir e Sinalizar.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. Depois de identificar os comandos mais comuns, você pode usar aceleradores com base na entrada para facilitar a execução desses comandos por um usuário.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.

No aplicativo de podcast, o comando executado com frequência é o comando "Favorite".In the podcast app, the frequently performed command is the "Favorite" command.

Aceleradores de tecladoKeyboard accelerators

Atalhos e manipulação direta de teclaShortcuts and direct key handling

Pressione Ctrl e F para executar uma ação

Dependendo do tipo de conteúdo, você pode identificar determinadas combinações de teclas que devem realizar uma ação.Depending on the type of content, you may identify certain key combinations that should perform an action. Por exemplo, em um aplicativo de email, a tecla DEL pode ser usada para excluir o email selecionado.In an email app, for example, the DEL key may be used to delete the email that is selected. Em um aplicativo de podcast, as teclas Ctrl + S ou F poderiam incluir um podcast como favorito para uso posterior.In a podcast app, the Ctrl+S or F keys could favorite a podcast for later. Embora alguns comandos tenham atalhos de teclado comuns e conhecidos, como DEL para excluir, outros comandos têm atalhos de aplicativo ou domínio específico.Although some commands have common, well-known keyboard shortcuts like DEL to delete, other commands have app- or domain-specific shortcuts. Use atalhos conhecidos se possível ou considere o fornecer um texto de lembrete em uma dica de ferramenta para ensinar o usuário sobre o comando de atalho.Use well-known shortcuts if possible, or consider providing reminder text in a tooltip to teach the user about the shortcut command.

O aplicativo pode responder quando o usuário pressionar uma tecla usando o evento KeyDown.Your app can respond when the user presses a key using the KeyDown event. Em geral, os usuários esperam que o aplicativo responda ao pressionarem a tecla em vez de aguardar até que a soltem.In general, users expect that the app will respond when they first press the key down, rather than waiting until they release the key.

Este exemplo explica como adicionar o manipulador KeyDown a PodcastUserControl para incluir um podcast nos favoritos quando o usuário pressiona Ctrl + S ou F. Ele usa o mesmo comando de antes.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);
    }
}

Aceleradores de mouseMouse accelerators

Passar o mouse sobre um item para relevar um botão

Os usuários estão familiarizados com os menus de contexto ao clicar com o botão direito do mouse, mas você pode desejar capacitá-los para executar comandos comuns com apenas um único clique no 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. Para habilitar essa experiência, você pode incluir botões dedicados na tela do item da coleção.To enable this experience, you can include dedicated buttons on your collection item's canvas. Para permitir que os usuários atuem rapidamente usando o mouse e reduzir a poluição visual, você pode optar por exibir somente esses botões quando o usuário está com o ponteiro dentro de um item de lista específico.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.

Neste exemplo, o comando Favorite é representado por um botão definido diretamente no PodcastUserControl.In this example, the Favorite command is represented by a button defined directly in the PodcastUserControl. Observe que o botão neste exemplo usa o mesmo comando, FavoriteCommand, como antes.Note that the button in this example uses the same command, FavoriteCommand, as before. Para alternar a visibilidade desse botão, você pode usar VisualStateManager para alternar entre os estados visuais quando o ponteiro entra e sai do controle.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>

Os botões de foco devem aparecer e desaparecer quando o mouse entra e sai do item.The hover buttons should appear and disappear when the mouse enters and exits the item. Para responder a eventos de mouse, use os eventos PointerEntered e PointerExited em 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);
}

Os botões exibidos no estado de foco podem ser acessados somente por meio do tipo de entrada de ponteiro.The buttons displayed in the hover state will only be accessible via the pointer input type. Como esses botões são limitados à entrada de ponteiro, você pode optar por minimizar ou remover o preenchimento ao redor do ícone do botão para otimizar a entrada de ponteiro.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. Se você optar por fazer isso, garanta que o volume do botão seja de pelo menos 20 x 20 px para ser utilizável com caneta e mouse.If you choose to do so, ensure that the button footprint is at least 20x20px to remain usable with pen and mouse.

Aceleradores de toqueTouch accelerators

SwipeSwipe

Deslizar o dedo sobre um item para revelar o comando

Os comandos efetuados ao deslizar o dedo são aceleradores de toque, que permitem aos usuários em dispositivos sensíveis ao toque executar ações comuns secundárias.Swipe commanding is a touch accelerator that enables users on touch devices to perform common secondary actions using touch. Ao deslizar o dedo, os usuários podem interagir com conteúdo de maneira rápida e natural, usando as ações comuns como passar o dedo para excluir ou passar o dedo para invocar.Swipe empowers touch users to quickly and naturally interact with content, using common actions like Swipe-to-Delete or Swipe-to-Invoke. Confira o artigo sobre comandos de deslizar o dedo para saber mais.See the swipe commanding article to learn more.

Para integrar os comandos de deslizar o dedo em sua coleção, você precisa de dois componentes: SwipeItems, que hospeda os comandos; e SwipeControl, que encapsula o item e permite a interação de deslizar o dedo.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.

Os SwipeItems podem ser definidos como um Recurso no PodcastUserControl.The SwipeItems can be defined as a Resource in the PodcastUserControl. Neste exemplo, o SwipeItems contém um comando para tornar um item Favorito.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>

O SwipeControl encapsula o item e permite que o usuário interaja com ele usando o gesto de deslizar o dedo.The SwipeControl wraps the item and allows the user to interact with it using the swipe gesture. Observe que o SwipeControl contém uma referência aos SwipeItems como seus RightItems.Notice that the SwipeControl contains a reference to the SwipeItems as its RightItems. O item Favoritos será exibido quando o usuário deslizar o dedo da direita para a esquerda.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 o usuário desliza o dedo para invocar o comando Favorite, o método Invoked é chamado.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);
}

Puxar para atualizarPull to refresh

A ação de Deslizar para atualizar permite a um usuário extrair uma coleção de dados com toque para recuperar mais dados.Pull to refresh lets a user pull down on a collection of data using touch in order to retrieve more data. Confira o artigo Deslizar para atualizar para saber mais.See the pull to refresh article to learn more.

Aceleradores de canetaPen accelerators

O tipo de entrada de caneta fornece a precisão de entrada de ponteiro.The pen input type provides the precision of pointer input. Os usuários podem realizar ações comuns, como abrir os menus de contexto com aceleradores baseados em caneta.Users can perform common actions such as opening context menus using pen-based accelerators. Para abrir um menu de contexto, os usuários podem tocar na tela com o botão da caneta pressionado ou manter o conteúdo pressionado.To open a context menu, users can tap the screen with the barrel button pressed, or long press on the content. Os usuários também podem usar a caneta para focalizar o conteúdo a fim de obter uma compreensão mais profunda da interface do usuário, como exibir dicas de ferramentas ou para revelar ações de foco secundário, semelhante ao 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.

Para otimizar o aplicativo para entrada de caneta, confira o artigo Interação com caneta.To optimize your app for pen input, see the pen and stylus interaction article.

O que fazer e o que não fazerDo's and don'ts

  • Verifique se os usuários podem acessar todos os comandos de todos os tipos de dispositivos Windows.Do make sure that users can access all commands from all types of Windows devices.
  • Inclua um menu de contexto que fornece acesso a todos os comandos disponíveis para um item da coleção.Do include a context menu that provides access to all the commands available for a collection item.
  • Forneça aceleradores de entradas para comandos usados com frequência.Do provide input accelerators for frequently-used commands.
  • Use a interface ICommand para implementar comandos.Do use the ICommand interface to implement commands.