Aplique comandos em aplicativos do Windows usando StandardUICommand, XamlUICommand e ICommandCommanding in Windows apps using StandardUICommand, XamlUICommand, and ICommand

Neste tópico, descreveremos como aplicar comandos nos aplicativos do Windows.In this topic, we describe commanding in Windows applications. Especificamente, discutiremos como usar as classes XamlUICommand e StandardUICommand (juntamente com a interface ICommand) para compartilhar e gerenciar os comandos entre vários tipos de controles, independentemente do tipo de entrada e do dispositivo que está sendo usado.Specifically, we discuss how you can use the XamlUICommand and StandardUICommand classes (along with the ICommand interface) to share and manage commands across various control types, regardless of the device and input type being used.

Um diagrama que representa um uso comum para um comando compartilhado: várias superfícies de IU com um comando 'favorito'

Compartilhe comandos entre vários controles, independentemente do tipo de entrada e do dispositivoShare commands across various controls, regardless of device and input type

APIs importantesImportant APIs

Visão geralOverview

Os comandos podem ser invocados diretamente por meio de interações de interface do usuário, como clicar em um botão ou selecionar um item de um menu de contexto.Commands can be invoked directly through UI interactions like clicking a button or selecting an item from a context menu. Eles também podem ser invocados indiretamente por meio de um dispositivo de entrada, como um acelerador de teclado, um gesto, reconhecimento de fala ou uma ferramenta de automação/acessibilidade.They can also be invoked indirectly through an input device such as a keyboard accelerator, gesture, speech recognition, or an automation/accessibility tool. Quando invocado, o comando pode ser processado por um controle (navegação de texto em um controle de edição), uma janela (navegação de retorno) ou pelo aplicativo (sair).Once invoked, the command can then be handled by a control (text navigation in an edit control), a window (back navigation), or the application (exit).

Os comandos podem ser operados em um contexto específico no aplicativo, como ao excluir texto ou desfazer uma ação, ou podem ter contexto livre, como desativar o áudio ou ajustar o brilho.Commands can operate on a specific context within your app, such as deleting text or undoing an action, or they can be context-free, such as muting audio or adjusting brightness.

A imagem a seguir mostra duas interfaces de comando (um CommandBar e um CommandBarFlyout contextual flutuante) que compartilham alguns dos mesmos comandos.The following image shows two command interfaces (a CommandBar and a floating contextual CommandBarFlyout) that share some of the same commands.

Barra de comandos expandidaExpanded Command bar
Barra de comandosCommand bar

Menu de contexto na galeria do Fotos do WindowsContext menu in the Microsoft Photos gallery
Menu de contexto na galeria do Fotos do WindowsContext menu in the Microsoft Photos gallery

Interações de comandoCommand interactions

Devido à variedade de dispositivos, tipos de entrada e superfícies de IU que podem afetar como um comando é invocado, é recomendável expor seus comandos pelo máximo de superfícies de comandos possível.Due to the variety of devices, input types, and UI surfaces that can affect how a command is invoked, we recommend exposing your commands through as many commanding surfaces as possible. Eles podem incluir uma combinação de Passar o dedo, MenuBar, CommandBar, CommandBarFlyout e o menu de contexto tradicional.These can include a combination of Swipe, MenuBar, CommandBar, CommandBarFlyout, and traditional context menu.

Para comandos críticos, use aceleradores de entrada específica.For critical commands, use input-specific accelerators. Aceleradores de entrada permitem que um usuário execute ações mais rapidamente dependendo do dispositivo de entrada usado.Input accelerators let a user perform actions more quickly depending on the input device they're using.

Aqui estão alguns aceleradores de entrada comuns para vários tipos de entrada:Here are some common input accelerators for various input types:

  • Ponteiro – botões de foco de mouse e canetaPointer - Mouse & Pen hover buttons
  • Teclado – atalhos (teclas de acesso e de aceleração)Keyboard - Shortcuts (access keys and accelerator keys)
  • Toque – passar o dedoTouch - Swipe
  • Toque – deslizar para atualizar os dadosTouch - Pull to refresh data

Você deve considerar as experiências de usuário e o tipo de entrada para tornar a funcionalidade do aplicativo universalmente acessível.You must consider the input type and user experiences to make your application's functionality universally accessible. Por exemplo, coleções (especialmente aquelas editáveis pelo usuário) normalmente incluem uma variedade de comandos específicos que são executados de modo bem diferente dependendo do dispositivo de entrada.For example, collections (especially user editable ones) typically include a variety of specific commands that are performed quite differently depending on the input device.

A tabela a seguir mostra alguns comandos típicos de coleção e os modos de expor esses comandos.The following 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

Sempre fornecer um menu de contexto Recomendamos incluir todos os comandos contextuais relevantes em um menu de contexto tradicional ou CommandBarFlyout, pois ambos são compatíveis com todos os tipos de entrada.Always provide a context menu We recommend including all relevant contextual commands in a traditional context menu or CommandBarFlyout, as both are supported for all input types. Por exemplo, se um comando é exposto somente durante um evento de focalização do ponteiro, ele não pode ser usado em um dispositivo somente de toque.For example, if a command is exposed only during a pointer hover event, it cannot be used on a touch-only device.

Comandos em aplicativos do WindowsCommands in Windows applications

Há algumas maneiras de compartilhar e gerenciar experiências de comandos em um aplicativo do Windows.There are a few ways you can share and manage commanding experiences in a Windows application. É possível definir manipuladores de eventos para interações padrão, como Click, em code-behind (isso pode ser ineficiente dependendo da complexidade de sua interface do usuário). É possível associar o ouvinte de eventos para interações padrão a um manipulador compartilhado ou você pode associar a propriedade Command do controle a uma implementação de ICommand que descreve a lógica de comando.You can define event handlers for standard interactions, such as Click, in code-behind (this can be quite inefficient, depending on the complexity of your UI), you can bind event listener for standard interactions to a shared handler, or you can bind the control's Command property to an ICommand implementation that describes the command logic.

Para fornecer experiências de usuário abrangentes e avançadas em superfícies de comando com eficiência e duplicação de código mínima, é recomendável usar os recursos de associação de comando descritos neste tópico (para manipulação de eventos padrão, confira os tópicos de eventos individuais).To provide rich and comprehensive user experiences across command surfaces efficiently and with minimal code duplication, we recommend using the command binding features described in this topic(for standard event handling, see the individual event topics).

Para associar um controle a um recurso de comando compartilhado, você mesmo pode implementar as interfaces ICommand ou pode criar seu comando usando uma classe base XamlUICommand ou um dos comandos de plataforma definidos pela classe derivada StandardUICommand.To bind a control to a shared command resource, you can implement the ICommand interfaces yourself, or you can build your command from either the XamlUICommand base class or one of the platform commands defined by the StandardUICommand derived class.

  • A interface ICommand (Windows.UI.Xaml.Input.ICommand ou System.Windows.Input.ICommand) permite criar comandos reutilizáveis e totalmente personalizados em seu aplicativo.The ICommand interface (Windows.UI.Xaml.Input.ICommand or System.Windows.Input.ICommand) lets you create fully customized, reusable commands across your app.
  • O XamlUICommand também fornece essa funcionalidade, mas simplifica o desenvolvimento expondo um conjunto de propriedades de comando internas, como comportamento do comando, atalhos de teclado (tecla de acesso e tecla de aceleração), ícone, rótulo e descrição.XamlUICommand also provides this capability but simplifies development by exposing a set of built-in command properties such as the command behavior, keyboard shortcuts (access key and accelerator key), icon, label, and description.
  • O StandardUICommand simplifica ainda mais as coisas, permitindo que você escolha de um conjunto de comandos de plataforma padrão com as propriedades predefinidas.StandardUICommand simplifies things further by letting you choose from a set of standard platform commands with predefined properties.

Importante

Em aplicativos da UWP, os comandos são implementações da interface Windows.UI.Xaml.Input.ICommand (C++) ou System.Windows.Input.ICommand (C#), dependendo da estrutura de linguagem escolhida.In UWP applications, commands are implementations of either the Windows.UI.Xaml.Input.ICommand (C++) or the System.Windows.Input.ICommand (C#) interface, depending on your chosen language framework.

Experiências de comando usando a classe StandardUICommandCommand experiences using the StandardUICommand class

Derivada de XamlUiCommand (derivada de Windows.UI.Xaml.Input.ICommand para C++ ou System.Windows.Input.ICommand para C#), a classe StandardUICommand expõe um conjunto de comandos de plataforma padrão com propriedades predefinidas, como ícone, acelerador de teclado e descrição.Derived from XamlUiCommand (derived from Windows.UI.Xaml.Input.ICommand for C++ or System.Windows.Input.ICommand for C#), the StandardUICommand class exposes a set of standard platform commands with pre-defined properties such as icon, keyboard accelerator, and description.

Um StandardUICommand fornece uma maneira rápida e consistente de definir comandos comuns, como Save ou Delete.A StandardUICommand provides a quick and consistent way to define common commands such as Save or Delete. Tudo o que você precisa fazer é fornecer as funções execute e canExecute.All you have to do is provide the execute and canExecute functions.

ExemploExample

Amostra de StandardUICommand

StandardUICommandSampleStandardUICommandSample

Baixe o código desse exemploDownload the code for this example
Amostra de comando da UWP (StandardUICommand)UWP commanding sample (StandardUICommand)

Neste exemplo, vamos mostrar como aprimorar um ListView básico com um comando de exclusão de item implementado pela classe StandardUICommand enquanto otimizamos a experiência do usuário para vários tipos de entrada usando um MenuBar, o controle Passar o dedo, os botões de focalizar e o menu de contexto.In this example, we show how to enhance a basic ListView with a Delete item command implemented through the StandardUICommand class, while optimizing the user experience for a variety of input types using a MenuBar, Swipe control, hover buttons, and context menu.

Observação

Esta amostra requer o pacote NuGet Microsoft.UI.Xaml.Controls, parte da Biblioteca de interfaces do usuário do Microsoft Windows.This sample requires the Microsoft.UI.Xaml.Controls NuGet package, a part of the Microsoft Windows UI Library.

Xaml:Xaml:

A interface do usuário de amostra inclui um ListView de cinco itens.The sample UI includes a ListView of five items. O StandardUICommand Delete está associado a um MenuBarItem, um SwipeItem, um AppBarButton e ao Menu ContextFlyout.The Delete StandardUICommand is bound to a MenuBarItem, a SwipeItem, an AppBarButton, and ContextFlyout menu.

<Page
    x:Class="StandardUICommandSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:StandardUICommandSample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:muxcontrols="using:Microsoft.UI.Xaml.Controls"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Page.Resources>
        <Style x:Key="HorizontalSwipe" 
               TargetType="ListViewItem" 
               BasedOn="{StaticResource ListViewItemRevealStyle}">
            <Setter Property="Height" Value="60"/>
            <Setter Property="Padding" Value="0"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="VerticalContentAlignment" Value="Stretch"/>
            <Setter Property="BorderThickness" Value="0"/>
        </Style>
    </Page.Resources>

    <Grid Loaded="ControlExample_Loaded">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <StackPanel Grid.Row="0" 
                    Padding="10" 
                    BorderThickness="0,0,0,1" 
                    BorderBrush="LightBlue"
                    Background="AliceBlue">
            <TextBlock Style="{StaticResource HeaderTextBlockStyle}">
                StandardUICommand sample
            </TextBlock>
            <TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Margin="0,0,0,10">
                This sample shows how to use the StandardUICommand class to 
                share a platform command and consistent user experiences 
                across various controls.
            </TextBlock>
            <TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Margin="0,0,0,0">
                Specifically, we define a standard delete command and add it 
                to a variety of command surfaces, all of which share a common 
                icon, label, keyboard accelerator, and description.
            </TextBlock>
        </StackPanel>

        <muxcontrols:MenuBar Grid.Row="1" Padding="10">
            <muxcontrols:MenuBarItem Title="File">
            </muxcontrols:MenuBarItem>
            <muxcontrols:MenuBarItem Title="Edit">
                <MenuFlyoutItem x:Name="DeleteFlyoutItem"/>
            </muxcontrols:MenuBarItem>
            <muxcontrols:MenuBarItem Title="Help">
            </muxcontrols:MenuBarItem>
        </muxcontrols:MenuBar>

        <ListView x:Name="ListViewRight" Grid.Row="2" 
                  Loaded="ListView_Loaded" 
                  IsItemClickEnabled="True" 
                  SelectionMode="Single" 
                  SelectionChanged="ListView_SelectionChanged" 
                  ItemContainerStyle="{StaticResource HorizontalSwipe}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:ListItemData">
                    <UserControl PointerEntered="ListViewSwipeContainer_PointerEntered" 
                                 PointerExited="ListViewSwipeContainer_PointerExited">
                        <UserControl.ContextFlyout>
                            <MenuFlyout>
                                <MenuFlyoutItem 
                                    Command="{x:Bind Command}" 
                                    CommandParameter="{x:Bind Text}" />
                            </MenuFlyout>
                        </UserControl.ContextFlyout>
                        <Grid AutomationProperties.Name="{x:Bind Text}">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="HoveringStates">
                                    <VisualState x:Name="HoverButtonsHidden" />
                                    <VisualState x:Name="HoverButtonsShown">
                                        <VisualState.Setters>
                                            <Setter Target="HoverButton.Visibility" 
                                                    Value="Visible" />
                                        </VisualState.Setters>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <SwipeControl x:Name="ListViewSwipeContainer" >
                                <SwipeControl.RightItems>
                                    <SwipeItems Mode="Execute">
                                        <SwipeItem x:Name="DeleteSwipeItem" 
                                                   Background="Red" 
                                                   Command="{x:Bind Command}" 
                                                   CommandParameter="{x:Bind Text}"/>
                                    </SwipeItems>
                                </SwipeControl.RightItems>
                                <Grid VerticalAlignment="Center">
                                    <TextBlock Text="{x:Bind Text}" 
                                               Margin="10" 
                                               FontSize="18" 
                                               HorizontalAlignment="Left" 
                                               VerticalAlignment="Center"/>
                                    <AppBarButton x:Name="HoverButton" 
                                                  IsTabStop="False" 
                                                  HorizontalAlignment="Right" 
                                                  Visibility="Collapsed" 
                                                  Command="{x:Bind Command}" 
                                                  CommandParameter="{x:Bind Text}"/>
                                </Grid>
                            </SwipeControl>
                        </Grid>
                    </UserControl>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>

Code-behindCode-behind

  1. Primeiro, definimos uma classe ListItemData, que contém uma cadeia de caracteres de texto e o ICommand para cada ListViewItem em nosso ListView.First, we define a ListItemData class that contains a text string and ICommand for each ListViewItem in our ListView.
public class ListItemData
{
    public String Text { get; set; }
    public ICommand Command { get; set; }
}
  1. Na classe MainPage, definimos uma coleção de objetos ListItemData para DataTemplate de ItemTemplate de ListView.In the MainPage class, we define a collection of ListItemData objects for the DataTemplate of the ListView ItemTemplate. Podemos, em seguida, populá-lo com uma coleção inicial de cinco itens (com o Delete do StandardUICommand associado e com texto).We then populate it with an initial collection of five items (with text and associated StandardUICommand Delete).
/// <summary>
/// ListView item collection.
/// </summary>
ObservableCollection<ListItemData> collection = 
    new ObservableCollection<ListItemData>();

/// <summary>
/// Handler for the layout Grid control load event.
/// </summary>
/// <param name="sender">Source of the control loaded event</param>
/// <param name="e">Event args for the loaded event</param>
private void ControlExample_Loaded(object sender, RoutedEventArgs e)
{
    // Create the standard Delete command.
    var deleteCommand = new StandardUICommand(StandardUICommandKind.Delete);
    deleteCommand.ExecuteRequested += DeleteCommand_ExecuteRequested;

    DeleteFlyoutItem.Command = deleteCommand;

    for (var i = 0; i < 5; i++)
    {
        collection.Add(
            new ListItemData {
                Text = "List item " + i.ToString(),
                Command = deleteCommand });
    }
}

/// <summary>
/// Handler for the ListView control load event.
/// </summary>
/// <param name="sender">Source of the control loaded event</param>
/// <param name="e">Event args for the loaded event</param>
private void ListView_Loaded(object sender, RoutedEventArgs e)
{
    var listView = (ListView)sender;
    // Populate the ListView with the item collection.
    listView.ItemsSource = collection;
}
  1. Em seguida, definimos o manipulador ExecuteRequested do ICommand no qual implementamos o comando de exclusão de item.Next, we define the ICommand ExecuteRequested handler where we implement the item delete command.
/// <summary>
/// Handler for the Delete command.
/// </summary>
/// <param name="sender">Source of the command event</param>
/// <param name="e">Event args for the command event</param>
private void DeleteCommand_ExecuteRequested(
    XamlUICommand sender, ExecuteRequestedEventArgs args)
{
    // If possible, remove specfied item from collection.
    if (args.Parameter != null)
    {
        foreach (var i in collection)
        {
            if (i.Text == (args.Parameter as string))
            {
                collection.Remove(i);
                return;
            }
        }
    }
    if (ListViewRight.SelectedIndex != -1)
    {
        collection.RemoveAt(ListViewRight.SelectedIndex);
    }
}
  1. Por fim, definimos manipuladores para vários eventos do ListView, incluindo os eventos PointerEntered, PointerExited e SelectionChanged.Finally, we define handlers for various ListView events, including PointerEntered, PointerExited, and SelectionChanged events. Os manipuladores de eventos de ponteiro são usados para mostrar ou ocultar o botão Excluir para cada item.The pointer event handlers are used to show or hide the Delete button for each item.
/// <summary>
/// Handler for the ListView selection changed event.
/// </summary>
/// <param name="sender">Source of the selection changed event</param>
/// <param name="e">Event args for the selection changed event</param>
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (ListViewRight.SelectedIndex != -1)
    {
        var item = collection[ListViewRight.SelectedIndex];
    }
}

/// <summary>
/// Handler for the pointer entered event.
/// Displays the delete item "hover" buttons.
/// </summary>
/// <param name="sender">Source of the pointer entered event</param>
/// <param name="e">Event args for the pointer entered event</param>
private void ListViewSwipeContainer_PointerEntered(
    object sender, PointerRoutedEventArgs e)
{
    if (e.Pointer.PointerDeviceType == 
        Windows.Devices.Input.PointerDeviceType.Mouse || 
        e.Pointer.PointerDeviceType == 
        Windows.Devices.Input.PointerDeviceType.Pen)
    {
        VisualStateManager.GoToState(
            sender as Control, "HoverButtonsShown", true);
    }
}

/// <summary>
/// Handler for the pointer exited event.
/// Hides the delete item "hover" buttons.
/// </summary>
/// <param name="sender">Source of the pointer exited event</param>
/// <param name="e">Event args for the pointer exited event</param>

private void ListViewSwipeContainer_PointerExited(
    object sender, PointerRoutedEventArgs e)
{
    VisualStateManager.GoToState(
        sender as Control, "HoverButtonsHidden", true);
}

Experiências de comando usando a classe XamlUICommandCommand experiences using the XamlUICommand class

Se precisar criar um comando não definido pela classe StandardUICommand ou se desejar obter mais controle sobre a aparência do comando, a classe XamlUiCommand será derivada da interface ICommand, adicionando várias propriedades de interface do usuário (como ícone, rótulo, descrição e atalhos de teclado), métodos e eventos para definir rapidamente a interface do usuário e o comportamento de um comando personalizado.If you need to create a command that isn't defined by the StandardUICommand class, or you'd like more control over the command appearance, the XamlUiCommand class derives from the ICommand interface, adding various UI properties (such as an icon, label, description, and keyboard shortcuts), methods, and events to quickly define the UI and behavior of a custom command.

O XamlUICommand permite especificar a interface do usuário por meio da associação de controle, como ícone, rótulo, descrição e atalhos de teclado (uma tecla de acesso e um acelerador de teclado), sem definir as propriedades individuais.XamlUICommand lets you specify UI through the control binding, such as an icon, label, description, and keyboard shortcuts (both an access key and a keyboard accelerator), without setting the individual properties.

ExemploExample

Amostra de XamlUICommand

XamlUICommandSampleXamlUICommandSample

Baixe o código desse exemploDownload the code for this example
Amostra de comando da UWP (XamlUICommand)UWP commanding sample (XamlUICommand)

Este exemplo compartilha a funcionalidade Delete do exemplo StandardUICommand anterior, mas mostra como a classe XamlUICommand permite definir um comando de exclusão personalizado com seu próprio ícone de fonte, rótulo, acelerador de teclado e descrição.This example shares the Delete functionality of the previous StandardUICommand example, but shows how the XamlUICommand class lets you define a custom delete command with your own font icon, label, keyboard accelerator, and description. Como no exemplo de StandardUICommand, aprimoramos um ListView básico com um comando de exclusão de item implementado pela classe XamlUICommand enquanto otimizamos a experiência do usuário para vários tipos de entrada usando um MenuBar, o controle Passar o dedo, os botões de focalizar e o menu de contexto.Like the StandardUICommand example, we enhance a basic ListView with a Delete item command implemented through the XamlUICommand class, while optimizing the user experience for a variety of input types using a MenuBar, Swipe control, hover buttons, and context menu.

Muitos controles de plataforma usam as propriedades XamlUICommand nos bastidores, assim como nosso exemplo de StandardUICommand na seção anterior.Many platform controls use the XamlUICommand properties under the covers, just like our StandardUICommand example in the previous section.

Observação

Esta amostra requer o pacote NuGet Microsoft.UI.Xaml.Controls, parte da Biblioteca de interfaces do usuário do Microsoft Windows.This sample requires the Microsoft.UI.Xaml.Controls NuGet package, a part of the Microsoft Windows UI Library.

Xaml:Xaml:

A interface do usuário de amostra inclui um ListView de cinco itens.The sample UI includes a ListView of five items. O Delete do XamlUICommand personalizado está associado a um MenuBarItem, um SwipeItem, um AppBarButton e ao Menu ContextFlyout.The custom XamlUICommand Delete is bound to a MenuBarItem, a SwipeItem, an AppBarButton, and ContextFlyout menu.

<Page
    x:Class="XamlUICommand_Sample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:XamlUICommand_Sample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:muxcontrols="using:Microsoft.UI.Xaml.Controls"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Page.Resources>
        <XamlUICommand x:Name="CustomXamlUICommand" 
                       ExecuteRequested="DeleteCommand_ExecuteRequested"
                       Description="Custom XamlUICommand" 
                       Label="Custom XamlUICommand">
            <XamlUICommand.IconSource>
                <FontIconSource FontFamily="Wingdings" Glyph="&#x4D;"/>
            </XamlUICommand.IconSource>
            <XamlUICommand.KeyboardAccelerators>
                <KeyboardAccelerator Key="D" Modifiers="Control"/>
            </XamlUICommand.KeyboardAccelerators>
        </XamlUICommand>

        <Style x:Key="HorizontalSwipe" 
               TargetType="ListViewItem" 
               BasedOn="{StaticResource ListViewItemRevealStyle}">
            <Setter Property="Height" Value="70"/>
            <Setter Property="Padding" Value="0"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="VerticalContentAlignment" Value="Stretch"/>
            <Setter Property="BorderThickness" Value="0"/>
        </Style>
        
    </Page.Resources>

    <Grid Loaded="ControlExample_Loaded" Name="MainGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        
        <StackPanel Grid.Row="0" 
                    Padding="10" 
                    BorderThickness="0,0,0,1" 
                    BorderBrush="LightBlue"
                    Background="AliceBlue">
            <TextBlock Style="{StaticResource HeaderTextBlockStyle}">
                XamlUICommand sample
            </TextBlock>
            <TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Margin="0,0,0,10">
                This sample shows how to use the XamlUICommand class to 
                share a custom command with consistent user experiences 
                across various controls.
            </TextBlock>
            <TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Margin="0,0,0,0">
                Specifically, we define a custom delete command and add it 
                to a variety of command surfaces, all of which share a common 
                icon, label, keyboard accelerator, and description.
            </TextBlock>
        </StackPanel>

        <muxcontrols:MenuBar Grid.Row="1">
            <muxcontrols:MenuBarItem Title="File">
            </muxcontrols:MenuBarItem>
            <muxcontrols:MenuBarItem Title="Edit">
                <MenuFlyoutItem x:Name="DeleteFlyoutItem" 
                                Command="{StaticResource CustomXamlUICommand}"/>
            </muxcontrols:MenuBarItem>
            <muxcontrols:MenuBarItem Title="Help">
            </muxcontrols:MenuBarItem>
        </muxcontrols:MenuBar>

        <ListView x:Name="ListViewRight" Grid.Row="2" 
                  Loaded="ListView_Loaded" 
                  IsItemClickEnabled="True"
                  SelectionMode="Single" 
                  SelectionChanged="ListView_SelectionChanged" 
                  ItemContainerStyle="{StaticResource HorizontalSwipe}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:ListItemData">
                    <UserControl PointerEntered="ListViewSwipeContainer_PointerEntered"
                                 PointerExited="ListViewSwipeContainer_PointerExited">
                        <UserControl.ContextFlyout>
                            <MenuFlyout>
                                <MenuFlyoutItem 
                                    Command="{x:Bind Command}" 
                                    CommandParameter="{x:Bind Text}" />
                            </MenuFlyout>
                        </UserControl.ContextFlyout>
                        <Grid AutomationProperties.Name="{x:Bind Text}">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="HoveringStates">
                                    <VisualState x:Name="HoverButtonsHidden" />
                                    <VisualState x:Name="HoverButtonsShown">
                                        <VisualState.Setters>
                                            <Setter Target="HoverButton.Visibility" 
                                                    Value="Visible" />
                                        </VisualState.Setters>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <SwipeControl x:Name="ListViewSwipeContainer">
                                <SwipeControl.RightItems>
                                    <SwipeItems Mode="Execute">
                                        <SwipeItem x:Name="DeleteSwipeItem"
                                                   Background="Red" 
                                                   Command="{x:Bind Command}" 
                                                   CommandParameter="{x:Bind Text}"/>
                                    </SwipeItems>
                                </SwipeControl.RightItems>
                                <Grid VerticalAlignment="Center">
                                    <TextBlock Text="{x:Bind Text}" 
                                               Margin="10" 
                                               FontSize="18" 
                                               HorizontalAlignment="Left"       
                                               VerticalAlignment="Center"/>
                                    <AppBarButton x:Name="HoverButton" 
                                                  IsTabStop="False" 
                                                  HorizontalAlignment="Right" 
                                                  Visibility="Collapsed" 
                                                  Command="{x:Bind Command}" 
                                                  CommandParameter="{x:Bind Text}"/>
                                </Grid>
                            </SwipeControl>
                        </Grid>
                    </UserControl>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>

Code-behindCode-behind

  1. Primeiro, definimos uma classe ListItemData, que contém uma cadeia de caracteres de texto e o ICommand para cada ListViewItem em nosso ListView.First, we define a ListItemData class that contains a text string and ICommand for each ListViewItem in our ListView.
public class ListItemData
{
    public String Text { get; set; }
    public ICommand Command { get; set; }
}
  1. Na classe MainPage, definimos uma coleção de objetos ListItemData para DataTemplate de ItemTemplate de ListView.In the MainPage class, we define a collection of ListItemData objects for the DataTemplate of the ListView ItemTemplate. Podemos, em seguida, populá-lo com uma coleção inicial de cinco itens (com o XamlUICommand associado e com texto).We then populate it with an initial collection of five items (with text and associated XamlUICommand).
ObservableCollection<ListItemData> collection = new ObservableCollection<ListItemData>();

private void ControlExample_Loaded(object sender, RoutedEventArgs e)
{
    for (var i = 0; i < 5; i++)
    {
        collection.Add(
           new ListItemData { Text = "List item " + i.ToString(), Command = CustomXamlUICommand });
    }
}

private void ListView_Loaded(object sender, RoutedEventArgs e)
{
    var listView = (ListView)sender;
    listView.ItemsSource = collection;
}
  1. Em seguida, definimos o manipulador ExecuteRequested do ICommand no qual implementamos o comando de exclusão de item.Next, we define the ICommand ExecuteRequested handler where we implement the item delete command.
private void DeleteCommand_ExecuteRequested(
   XamlUICommand sender, ExecuteRequestedEventArgs args)
{
    if (args.Parameter != null)
    {
        foreach (var i in collection)
        {
            if (i.Text == (args.Parameter as string))
            {
                collection.Remove(i);
                return;
            }
        }
    }
    if (ListViewRight.SelectedIndex != -1)
    {
        collection.RemoveAt(ListViewRight.SelectedIndex);
    }
}
  1. Por fim, definimos manipuladores para vários eventos do ListView, incluindo os eventos PointerEntered, PointerExited e SelectionChanged.Finally, we define handlers for various ListView events, including PointerEntered, PointerExited, and SelectionChanged events. Os manipuladores de eventos de ponteiro são usados para mostrar ou ocultar o botão Excluir para cada item.The pointer event handlers are used to show or hide the Delete button for each item.
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (ListViewRight.SelectedIndex != -1)
    {
        var item = collection[ListViewRight.SelectedIndex];
    }
}

private void ListViewSwipeContainer_PointerEntered(object sender, PointerRoutedEventArgs e)
{
    if (e.Pointer.PointerDeviceType == 
        Windows.Devices.Input.PointerDeviceType.Mouse || 
        e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Pen)
    {
        VisualStateManager.GoToState(sender as Control, "HoverButtonsShown", true);
    }
}

private void ListViewSwipeContainer_PointerExited(object sender, PointerRoutedEventArgs e)
{
    VisualStateManager.GoToState(sender as Control, "HoverButtonsHidden", true);
}

Experiências de comando usando a interface ICommandCommand experiences using the ICommand interface

Os controles padrão da UWP (botão, lista, seleção, calendário, texto preditivo) fornecem a base para muitas experiências de comando comuns.Standard UWP controls (button, list, selection, calendar, predictive text) provide the basis for many common command experiences. Para obter uma lista completa dos tipos de controle, confira Controles e padrões para aplicativos do Windows.For a complete list of control types, see Controls and patterns for Windows apps.

A maneira mais simples de dar suporte a uma experiência de comando estruturada é definir uma implementação da interface ICommand (Windows.UI.Xaml.Input.ICommand para C++ ou System.Windows.Input.ICommand para C#).The most basic way to support a structured commanding experience is to define an implementation of the ICommand interface (Windows.UI.Xaml.Input.ICommand for C++ or System.Windows.Input.ICommand for C#). Esta instância ICommand, em seguida, poderá ser associada a controles como botões.This ICommand instance can then be bound to controls such as buttons.

Observação

Em alguns casos, pode eficiente associar um método ao evento Click e uma propriedade à propriedade IsEnabled.In some cases, it might be just as efficient to bind a method to the Click event and a property to the IsEnabled property.

ExemploExample

Exemplo de interface de comando

Exemplo de ICommandICommand example

Baixe o código desse exemploDownload the code for this example
Amostra de comando da UWP (ICommand)UWP commanding sample (ICommand)

Neste exemplo básico, demonstraremos como um único comando pode ser invocado com o clique de um botão, com um acelerador de teclado e ao girar o botão de rolagem do mouse.In this basic example, we demonstrate how a single command can be invoked with a button click, a keyboard accelerator, and rotating a mouse wheel.

Usamos dois ListViews, um populado com cinco itens e outro vazio, bem como dois botões, um para mover os itens do ListView à esquerda para o ListView à direita, outro para mover os itens da direita para esquerda.We use two ListViews, one populated with five items and the other empty, and two buttons, one for moving items from the ListView on the left to the ListView on the right, and the other for moving items from the right to the left. Cada botão é associado a um comando correspondente (ViewModel.MoveRightCommand e ViewModel.MoveLeftCommand, respectivamente) e são habilitados e desabilitados automaticamente com base no número de itens no ListView associado.Each button is bound to a corresponding command (ViewModel.MoveRightCommand and ViewModel.MoveLeftCommand, respectively), and are enabled and disabled automatically based on the number of items in their associated ListView.

O código XAML a seguir define a interface do usuário para o nosso exemplo.The following XAML code defines the UI for our example.

<Page
    x:Class="UICommand1.View.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="using:UICommand1.ViewModel"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Page.Resources>
        <vm:OpacityConverter x:Key="opaque" />
    </Page.Resources>

    <Grid Name="ItemGrid"
          Background="AliceBlue"
          PointerWheelChanged="Page_PointerWheelChanged">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="2*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <ListView Grid.Column="0" VerticalAlignment="Center"
                  x:Name="CommandListView" 
                  ItemsSource="{x:Bind Path=ViewModel.ListItemLeft}" 
                  SelectionMode="None" IsItemClickEnabled="False" 
                  HorizontalAlignment="Right">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="vm:ListItemData">
                    <Grid VerticalAlignment="Center">
                        <AppBarButton Label="{x:Bind ListItemText}">
                            <AppBarButton.Icon>
                                <SymbolIcon Symbol="{x:Bind ListItemIcon}"/>
                            </AppBarButton.Icon>
                        </AppBarButton>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Grid Grid.Column="1" Margin="0,0,0,0"
              HorizontalAlignment="Center" 
              VerticalAlignment="Center">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="1">
                <FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" 
                          FontSize="40" Glyph="&#xE893;" 
                          Opacity="{x:Bind Path=ViewModel.ListItemLeft.Count, 
                                        Mode=OneWay, Converter={StaticResource opaque}}"/>
                <Button Name="MoveItemRightButton"
                        Margin="0,10,0,10" Width="120" HorizontalAlignment="Center"
                        Command="{x:Bind Path=ViewModel.MoveRightCommand}">
                    <Button.KeyboardAccelerators>
                        <KeyboardAccelerator 
                            Modifiers="Control" 
                            Key="Add" />
                    </Button.KeyboardAccelerators>
                    <StackPanel>
                        <SymbolIcon Symbol="Next"/>
                        <TextBlock>Move item right</TextBlock>
                    </StackPanel>
                </Button>
                <Button Name="MoveItemLeftButton" 
                            Margin="0,10,0,10" Width="120" HorizontalAlignment="Center"
                            Command="{x:Bind Path=ViewModel.MoveLeftCommand}">
                    <Button.KeyboardAccelerators>
                        <KeyboardAccelerator 
                            Modifiers="Control" 
                            Key="Subtract" />
                    </Button.KeyboardAccelerators>
                    <StackPanel>
                        <SymbolIcon Symbol="Previous"/>
                        <TextBlock>Move item left</TextBlock>
                    </StackPanel>
                </Button>
                <FontIcon FontFamily="{StaticResource SymbolThemeFontFamily}" 
                          FontSize="40" Glyph="&#xE892;"
                          Opacity="{x:Bind Path=ViewModel.ListItemRight.Count, 
                                        Mode=OneWay, Converter={StaticResource opaque}}"/>
            </StackPanel>
        </Grid>
        <ListView Grid.Column="2" 
                  x:Name="CommandListViewRight" 
                  VerticalAlignment="Center" 
                  IsItemClickEnabled="False" 
                  SelectionMode="None"
                  ItemsSource="{x:Bind Path=ViewModel.ListItemRight}" 
                  HorizontalAlignment="Left">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="vm:ListItemData">
                    <Grid VerticalAlignment="Center">
                        <AppBarButton Label="{x:Bind ListItemText}">
                            <AppBarButton.Icon>
                                <SymbolIcon Symbol="{x:Bind ListItemIcon}"/>
                            </AppBarButton.Icon>
                        </AppBarButton>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>

Aqui está o code-behind para a interface do usuário anterior.Here's the code-behind for the preceding UI.

No code-behind, nos conectamos ao nosso modelo de exibição que contém nosso código de comando.In code-behind, we connect to our view model that contains our command code. Além disso, definimos um manipulador para a entrada do botão de rolagem do mouse, que também conecta nosso código de comando.In addition, we define a handler for input from the mouse wheel, which also connects our command code.

using Windows.UI.Xaml;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Controls;
using UICommand1.ViewModel;
using Windows.System;
using Windows.UI.Core;

namespace UICommand1.View
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        // Reference to our view model.
        public UICommand1ViewModel ViewModel { get; set; }

        // Initialize our view and view model.
        public MainPage()
        {
            this.InitializeComponent();
            ViewModel = new UICommand1ViewModel();
        }

        /// <summary>
        /// Handle mouse wheel input and assign our
        /// commands to appropriate direction of rotation.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Page_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
        {
            var props = e.GetCurrentPoint(sender as UIElement).Properties;

            // Require CTRL key and accept only vertical mouse wheel movement 
            // to eliminate accidental wheel input.
            if ((Window.Current.CoreWindow.GetKeyState(VirtualKey.Control) != 
                CoreVirtualKeyStates.None) && !props.IsHorizontalMouseWheel)
            {
                bool delta = props.MouseWheelDelta < 0 ? true : false;

                switch (delta)
                {
                    case true:
                        ViewModel.MoveRight();
                        break;
                    case false:
                        ViewModel.MoveLeft();
                        break;
                    default:
                        break;
                }
            }
        }
    }
}

Aqui está o código de nosso modelo de exibiçãoHere's the code from our view model

Nosso modelo de exibição é onde definimos os detalhes de execução para os dois comandos em nosso aplicativo, populamos um ListView e fornecemos um conversor de valor de opacidade para ocultar ou exibir algumas interfaces do usuário adicionais com base na contagem de itens de cada ListView.Our view model is where we define the execution details for the two commands in our app, populate one ListView, and provide an opacity value converter for hiding or displaying some additional UI based on the item count of each ListView.

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;

namespace UICommand1.ViewModel
{
    /// <summary>
    /// UI properties for our list items.
    /// </summary>
    public class ListItemData
    {
        /// <summary>
        /// Gets and sets the list item content string.
        /// </summary>
        public string ListItemText { get; set; }
        /// <summary>
        /// Gets and sets the list item icon.
        /// </summary>
        public Symbol ListItemIcon { get; set; }
    }

    /// <summary>
    /// View Model that sets up a command to handle invoking the move item buttons.
    /// </summary>
    public class UICommand1ViewModel
    {
        /// <summary>
        /// The command to invoke when the Move item left button is pressed.
        /// </summary>
        public RelayCommand MoveLeftCommand { get; private set; }

        /// <summary>
        /// The command to invoke when the Move item right button is pressed.
        /// </summary>
        public RelayCommand MoveRightCommand { get; private set; }

        // Item collections
        public ObservableCollection<ListItemData> ListItemLeft { get; } = 
           new ObservableCollection<ListItemData>();
        public ObservableCollection<ListItemData> ListItemRight { get; } = 
           new ObservableCollection<ListItemData>();

        public ListItemData listItem;

        /// <summary>
        /// Sets up a command to handle invoking the move item buttons.
        /// </summary>
        public UICommand1ViewModel()
        {
            MoveLeftCommand = 
               new RelayCommand(new Action(MoveLeft), CanExecuteMoveLeftCommand);
            MoveRightCommand = 
               new RelayCommand(new Action(MoveRight), CanExecuteMoveRightCommand);

            LoadItems();
        }

        /// <summary>
        ///  Populate our list of items.
        /// </summary>
        public void LoadItems()
        {
            for (var x = 0; x <= 4; x++)
            {
                listItem = new ListItemData();
                listItem.ListItemText = "Item " + (ListItemLeft.Count + 1).ToString();
                listItem.ListItemIcon = Symbol.Emoji;
                ListItemLeft.Add(listItem);
            }
        }

        /// <summary>
        /// Move left command valid when items present in the list on right.
        /// </summary>
        /// <returns>True, if count is greater than 0.</returns>
        private bool CanExecuteMoveLeftCommand()
        {
            return ListItemRight.Count > 0;
        }

        /// <summary>
        /// Move right command valid when items present in the list on left.
        /// </summary>
        /// <returns>True, if count is greater than 0.</returns>
        private bool CanExecuteMoveRightCommand()
        {
            return ListItemLeft.Count > 0;
        }

        /// <summary>
        /// The command implementation to execute when the Move item right button is pressed.
        /// </summary>
        public void MoveRight()
        {
            if (ListItemLeft.Count > 0)
            {
                listItem = new ListItemData();
                ListItemRight.Add(listItem);
                listItem.ListItemText = "Item " + ListItemRight.Count.ToString();
                listItem.ListItemIcon = Symbol.Emoji;
                ListItemLeft.RemoveAt(ListItemLeft.Count - 1);
                MoveRightCommand.RaiseCanExecuteChanged();
                MoveLeftCommand.RaiseCanExecuteChanged();
            }
        }

        /// <summary>
        /// The command implementation to execute when the Move item left button is pressed.
        /// </summary>
        public void MoveLeft()
        {
            if (ListItemRight.Count > 0)
            {
                listItem = new ListItemData();
                ListItemLeft.Add(listItem);
                listItem.ListItemText = "Item " + ListItemLeft.Count.ToString();
                listItem.ListItemIcon = Symbol.Emoji;
                ListItemRight.RemoveAt(ListItemRight.Count - 1);
                MoveRightCommand.RaiseCanExecuteChanged();
                MoveLeftCommand.RaiseCanExecuteChanged();
            }
        }

        /// <summary>
        /// Views subscribe to this event to get notified of property updates.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Notify subscribers of updates to the named property
        /// </summary>
        /// <param name="propertyName">The full, case-sensitive, name of a property.</param>
        protected void NotifyPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                PropertyChangedEventArgs args = new PropertyChangedEventArgs(propertyName);
                handler(this, args);
            }
        }
    }

    /// <summary>
    /// Convert a collection count to an opacity value of 0.0 or 1.0.
    /// </summary>
    public class OpacityConverter : IValueConverter
    {
        /// <summary>
        /// Converts a collection count to an opacity value of 0.0 or 1.0.
        /// </summary>
        /// <param name="value">The count passed in</param>
        /// <param name="targetType">Ignored.</param>
        /// <param name="parameter">Ignored</param>
        /// <param name="language">Ignored</param>
        /// <returns>1.0 if count > 0, otherwise returns 0.0</returns>
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            return ((int)value > 0 ? 1.0 : 0.0);
        }

        /// <summary>
        /// Not used, converter is not intended for two-way binding. 
        /// </summary>
        /// <param name="value">Ignored</param>
        /// <param name="targetType">Ignored</param>
        /// <param name="parameter">Ignored</param>
        /// <param name="language">Ignored</param>
        /// <returns></returns>
        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }
}

Por fim, aqui está nossa implementação da interface ICommandFinally, here's our implementation of the ICommand interface

Aqui, definimos um comando que implementa a interface ICommand e simplesmente retransmite sua funcionalidade a outros objetos.Here, we define a command that implements the ICommand interface and simply relays its functionality to other objects.

using System;
using System.Windows.Input;

namespace UICommand1
{
    /// <summary>
    /// A command whose sole purpose is to relay its functionality 
    /// to other objects by invoking delegates. 
    /// The default return value for the CanExecute method is 'true'.
    /// <see cref="RaiseCanExecuteChanged"/> needs to be called whenever
    /// <see cref="CanExecute"/> is expected to return a different value.
    /// </summary>
    public class RelayCommand : ICommand
    {
        private readonly Action _execute;
        private readonly Func<bool> _canExecute;

        /// <summary>
        /// Raised when RaiseCanExecuteChanged is called.
        /// </summary>
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// Creates a new command that can always execute.
        /// </summary>
        /// <param name="execute">The execution logic.</param>
        public RelayCommand(Action execute)
            : this(execute, null)
        {
        }

        /// <summary>
        /// Creates a new command.
        /// </summary>
        /// <param name="execute">The execution logic.</param>
        /// <param name="canExecute">The execution status logic.</param>
        public RelayCommand(Action execute, Func<bool> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("execute");
            _execute = execute;
            _canExecute = canExecute;
        }

        /// <summary>
        /// Determines whether this <see cref="RelayCommand"/> can execute in its current state.
        /// </summary>
        /// <param name="parameter">
        /// Data used by the command. If the command does not require 
        /// data to be passed, this object can be set to null.
        /// </param>
        /// <returns>true if this command can be executed; otherwise, false.</returns>
        public bool CanExecute(object parameter)
        {
            return _canExecute == null ? true : _canExecute();
        }

        /// <summary>
        /// Executes the <see cref="RelayCommand"/> on the current command target.
        /// </summary>
        /// <param name="parameter">
        /// Data used by the command. If the command does not require 
        /// data to be passed, this object can be set to null.
        /// </param>
        public void Execute(object parameter)
        {
            _execute();
        }

        /// <summary>
        /// Method used to raise the <see cref="CanExecuteChanged"/> event
        /// to indicate that the return value of the <see cref="CanExecute"/>
        /// method has changed.
        /// </summary>
        public void RaiseCanExecuteChanged()
        {
            var handler = CanExecuteChanged;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }
    }
}

ResumoSummary

A Plataforma Universal do Windows fornece um sistema de comandos robusto e flexível que permite que você crie aplicativos que compartilham e gerenciam os comandos nos tipos de controle, dispositivos e tipos de entrada.The Universal Windows Platform provides a robust and flexible commanding system that lets you build apps that share and manage commands across control types, devices, and input types.

Ao criar comandos para seus aplicativos do Windows, use as seguintes abordagens:Use the following approaches when building commands for your Windows apps:

  • Ouça e manipule eventos no XAML/code-behindListen for and handle events in XAML/code-behind
  • Associe a um método de manipulação de eventos, como ClickBind to an event handling method such as Click
  • Defina sua própria implementação do ICommandDefine your own ICommand implementation
  • Crie objetos de XamlUICommand com seus próprios valores para um conjunto predefinido de propriedadesCreate XamlUICommand objects with your own values for a pre-defined set of properties
  • Crie objetos de StandardUICommand com um conjunto de valores e propriedades de plataforma predefinidoCreate StandardUICommand objects with a set of pre-defined platform properties and values

Próximas etapasNext steps

Para obter um exemplo completo que demonstra uma implementação de XamlUICommand e StandardUICommand, confira a amostra da Galeria de controles XAML.For a complete example that demonstrates a XamlUICommand and StandardUICommand implementation, see the XAML Controls Gallery sample.

Veja tambémSee also

Controles e padrões para aplicativos do WindowsControls and patterns for Windows apps

AmostrasSamples

Amostras de tópicoTopic samples

Outras amostrasOther samples