StandardUICommand、XamlUICommand、ICommand を使用するユニバーサル Windows プラットフォーム (UWP) アプリのコマンド処理Commanding in Universal Windows Platform (UWP) apps using StandardUICommand, XamlUICommand, and ICommand

このトピックでは、ユニバーサル Windows プラットフォーム (UWP) アプリケーションのコマンド処理について説明します。In this topic, we describe commanding in Universal Windows Platform (UWP) applications. 具体的には、XamlUICommand クラスと StandardUICommand クラスを (ICommand インターフェイスと共に) 使用し、使用しているデバイスや入力の種類に関係なく、さまざまな型のコントロールでコマンドを共有し、管理する方法について説明します。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.

共有コマンドで共通する使用方法を表す図: 複数の UI サーフェスと "お気に入り" コマンド

デバイスや入力の種類に関係なく、さまざまなコントロールでコマンドを共有するShare commands across various controls, regardless of device and input type

重要な APIImportant APIs

概要Overview

コマンドは、ボタンをクリックする、コンテキスト メニューから項目を選択するなど、UI 操作で直接呼び出すことができます。Commands can be invoked directly through UI interactions like clicking a button or selecting an item from a context menu. キーボード アクセラレータ、ジェスチャ、音声認識、自動化/アクセシビリティ ツールなど、入力装置から間接的に呼び出すこともできます。They can also be invoked indirectly through an input device such as a keyboard accelerator, gesture, speech recognition, or an automation/accessibility tool. 呼び出し後、コマンドは、コントロール (編集コントロールのテキスト ナビゲーション)、ウィンドウ (戻るナビゲーション)、またはアプリケーション (終了) で処理できます。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).

コマンドは、テキストを削除する、アクションを元に戻すなど、アプリ内の特定のコンテキストで操作できます。あるいは、音声を消す、明るさを調整するなど、コンテキストがない場合もあります。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.

次の画像で確認できる 2 つのコマンド インターフェイス (CommandBar とフローティング コンテキスト CommandBarFlyout) では、同じコマンドがいくつか共有されています。The following image shows two command interfaces (a CommandBar and a floating contextual CommandBarFlyout) that share some of the same commands.

Microsoft フォトのコマンドバーCommand bar in Microsoft Photos
Microsoft フォトのコマンドバーCommand bar in Microsoft Photos

Microsoft フォト ギャラリーのコンテキスト メニューContext menu in the Microsoft Photos gallery
Microsoft フォト ギャラリーのコンテキスト メニューContext menu in the Microsoft Photos gallery

コマンド操作Command interactions

さまざまなデバイス、入力の種類、UI サーフェスがコマンドの呼び出し方法に影響を与えるため、可能な限りたくさんのコマンド処理サーフェスを介してコマンドを公開することをお勧めします。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. たとえば、SwipeMenuBarCommandBarCommandBarFlyout、従来のコンテキスト メニューを組み合わせることができます。These can include a combination of Swipe, MenuBar, CommandBar, CommandBarFlyout, and traditional context menu.

重要なコマンドの場合、入力固有のアクセラレータを使用してください。For critical commands, use input-specific accelerators. 入力アクセラレータを使用すると、使用している入力装置によっては、ユーザーはアクションをよりすばやく実行できます。Input accelerators let a user perform actions more quickly depending on the input device they're using.

さまざまな入力の種類で共通する入力アクセラレータ:Here are some common input accelerators for various input types:

  • ポインター - マウスとペンのホバー ボタンPointer - Mouse & Pen hover buttons
  • キーボード - ショートカット (アクセス キーとアクセラレータ キー)Keyboard - Shortcuts (access keys and accelerator keys)
  • タッチ - スワイプTouch - Swipe
  • タッチ - 引いてデータを更新するTouch - Pull to refresh data

アプリケーションの機能を誰でも使えるようにするには、入力の種類と使い勝手を検討する必要があります。You must consider the input type and user experiences to make your application's functionality universally accessible. たとえば、コレクション (特に、ユーザーが編集できるコレクション) には通常、入力装置によって実行方法がかなり異なるコマンドがたくさん含まれています。For example, collections (especially user editable ones) typically include a variety of specific commands that are performed quite differently depending on the input device.

次の表は、典型的なコレクション コマンドとそれを公開する方法をまとめたものです。The following table shows some typical collection commands and ways to expose those commands.

コマンドCommand 入力方法を問わないInput-agnostic マウス アクセラレータMouse accelerator キーボード アクセラレータKeyboard accelerator タッチ アクセラレータTouch accelerator
項目の削除Delete item ショートカット メニューContext menu ホバー ボタンHover button DEL キーDEL key スワイプして削除Swipe to delete
フラグの設定Flag item ショートカット メニューContext menu ホバー ボタンHover button Ctrl + Shift + GCtrl+Shift+G スワイプしてフラグを設定Swipe to flag
データの更新Refresh data ショートカット メニューContext menu 該当なしN/A F5 キーF5 key 引っ張って更新Pull to refresh
お気に入りに追加Favorite an item ショートカット メニューContext menu ホバー ボタンHover button F、Ctrl + SF, Ctrl+S スワイプしてお気に入りに追加Swipe to favorite

コンテキスト メニューを常に提供する 従来のコンテキスト コマンドまたは CommandBarFlyout に関連するすべてのコンテキスト コマンドを含めることをお勧めします。いずれも、入力の種類を問わず、サポートされています。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. たとえば、ポインターのホバー イベント中にのみコマンドが公開される場合、タッチ専用デバイスでは利用できません。For example, if a command is exposed only during a pointer hover event, it cannot be used on a touch-only device.

UWP アプリケーションのコマンドCommands in UWP applications

UWP アプリケーションのコマンド処理方法は、いくつかの方法で共有し、管理できます。There are a few ways you can share and manage commanding experiences in a UWP application. 分離コードで、クリックなど、標準的な操作にイベント ハンドラーを定義したり (UI の複雑度によっては、かなり非効率的になることがあります)、標準的な操作のイベント リスナーを共有ハンドラーにバインドしたり、コマンド ロジックを表す ICommand 実装にコントロールの Command プロパティをバインドしたりできます。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.

コマンド サーフェス全体で、機能が豊富で包括的なユーザー エクスペリエンスを効率的かつ、コード重複を最小限に抑えて提供するには、このトピックで説明するコマンド バインド機能を利用することをお勧めします (標準的なイベント処理については、個々のイベント トピックをご覧ください)。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).

共有コマンド リソースにコントロールをバインドするには、ICommand インターフェイスを自分で実装したり、XamlUICommand ベース クラスまたは StandardUICommand 派生クラスによって定義されるプラットフォーム コマンドの 1 つからコマンドをビルドしたりできます。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.

  • ICommand インターフェイス (Windows.UI.Xaml.Input.ICommand または System.Windows.Input.ICommand) を利用すると、完全にカスタマイズされた、再利用可能なコマンドをアプリ全体で作成できます。The ICommand interface (Windows.UI.Xaml.Input.ICommand or System.Windows.Input.ICommand) lets you create fully customized, reusable commands across your app.
  • XamlUICommand からもこの機能が与えられますが、コマンドの動作、キーボード ショートカット (アクセス キーとアクセラレータ キー)、アイコン、ラベル、説明など、一連の組み込みコマンド プロパティを公開するため、開発が簡単になります。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.
  • StandardUICommand では、プロパティが事前定義されている一連の標準プラットフォーム コマンドから選択できるため、さらに簡単になります。StandardUICommand simplifies things further by letting you choose from a set of standard platform commands with predefined properties.

重要

UWP アプリケーションでは、コマンドは、Windows.UI.Xaml.Input.ICommand (C++) または System.Windows.Input.ICommand (C#) インターフェイスの実装になります。選択した言語フレームワークによって決まります。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.

StandardUICommand クラスを使用したコマンド エクスペリエンスCommand experiences using the StandardUICommand class

XamlUiCommand (derived from Windows.UI.Xaml.Input.ICommand for C++ または System.Windows.Input.ICommand for C#) から派生した StandardUICommand クラスからは、アイコン、キーボード アクセラレータ、説明など、プロパティが事前定義された一連の標準プラットフォーム コマンドが公開されます。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.

StandardUICommand の場合、SaveDelete など、共通のコマンドを一貫性のある方法で簡単に定義できます。A StandardUICommand provides a quick and consistent way to define common commands such as Save or Delete. 必要な作業は、execute 関数と canExecute 関数を指定することだけです。All you have to do is provide the execute and canExecute functions.

Example

StandardUICommand サンプル

StandardUICommandSampleStandardUICommandSample

この例のコードをダウンロードするDownload the code for this example
UWP コマンド処理サンプル (StandardUICommand)UWP commanding sample (StandardUICommand)

この例では、StandardUICommand クラスを介して実装された項目削除コマンドで基本の ListView を機能強化し、同時に、MenuBarSwipe コントロール、ホバー ボタン、コンテキスト メニューを利用し、さまざまな種類の入力方法を最適化する方法を確認できます。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.

注意

このサンプルは Microsoft.UI.Xaml.Controls NuGet パッケージを必要としますが、これは Microsoft Windows UI ライブラリに含まれています。This sample requires the Microsoft.UI.Xaml.Controls NuGet package, a part of the Microsoft Windows UI Library.

Xaml:Xaml:

サンプル UI には、5 つの項目の ListView が含まれています。The sample UI includes a ListView of five items. Delete StandardUICommandMenuBarItemSwipeItemAppBarButtonContextFlyout メニューにバインドされています。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-behind

  1. まず、テキスト文字列と ListView の ListViewItem 別の ICommand を含む ListItemData クラスを定義します。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. MainPage クラスで、ListView ItemTemplateDataTemplateListItemData オブジェクトのコレクションを定義します。In the MainPage class, we define a collection of ListItemData objects for the DataTemplate of the ListView ItemTemplate. 次に、5 つの項目の最初のコレクションをそれに入力します (テキストと関連する StandardUICommand Delete)。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. 次に、ICommand ExecuteRequested ハンドラーを定義します。このハンドラーに項目の削除コマンドを実装します。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. 最後に、PointerEnteredPointerExitedSelectionChanged イベントなど、さまざま ListView イベントのハンドラーを定義します。Finally, we define handlers for various ListView events, including PointerEntered, PointerExited, and SelectionChanged events. ポインターのイベント ハンドラーは、各項目の [削除] ボタンを表示するか、非表示にする目的で使用されます。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);
}

XamlUICommand クラスを使用したコマンド エクスペリエンスCommand experiences using the XamlUICommand class

StandardUICommand クラスで定義されないコマンドを作成する必要がある場合、あるいはコマンドの外見をもっと調整する場合、ICommand から派生するXamlUiCommand クラスでさまざまな UI プロパティ (アイコン、ラベル、説明、キーボード ショートカットなど)、メソッド、イベントを追加し、カスタム コマンドの UI と動作を簡単に定義できます。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.

XamlUICommand を利用すると、個別のプロパティを設定することなく、アイコン、ラベル、説明、キーボード ショートカット (アクセス キーとキーボード アクセラレータの両方) などの UI をコントロール バインドで指定できます。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.

Example

XamlUICommand サンプル

XamlUICommandSampleXamlUICommandSample

この例のコードをダウンロードするDownload the code for this example
UWP コマンド処理サンプル (XamlUICommand)UWP commanding sample (XamlUICommand)

この例では、前の StandardUICommand の例と削除機能が同じくしていますが、XamlUICommand クラスを利用することで、独自のフォント アイコン、ラベル、キーボード アクセラレータ、説明でカスタムの削除アイコンを定義できることを示しています。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. StandardUICommand の例と同様に、基本の ListViewXamlUICommand クラス経由で実装された項目削除コマンドで機能強化し、同時に、MenuBarSwipe コントロール、ホバー ボタン、コンテキスト メニューを利用し、さまざまな種類の入力方法を最適化しています。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.

前のセクションの StandardUICommand の例で見られたように、多くのプラットフォーム コントロールでは XamlUICommand プロパティがこっそり使用されています。Many platform controls use the XamlUICommand properties under the covers, just like our StandardUICommand example in the previous section.

注意

このサンプルは Microsoft.UI.Xaml.Controls NuGet パッケージを必要としますが、これは Microsoft Windows UI ライブラリに含まれています。This sample requires the Microsoft.UI.Xaml.Controls NuGet package, a part of the Microsoft Windows UI Library.

Xaml:Xaml:

サンプル UI には、5 つの項目の ListView が含まれています。The sample UI includes a ListView of five items. カスタムの XamlUICommand Delete は MenuBarItemSwipeItemAppBarButtonContextFlyout メニューにバインドされています。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-behind

  1. まず、テキスト文字列と ListView の ListViewItem 別の ICommand を含む ListItemData クラスを定義します。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. MainPage クラスで、ListView ItemTemplateDataTemplateListItemData オブジェクトのコレクションを定義します。In the MainPage class, we define a collection of ListItemData objects for the DataTemplate of the ListView ItemTemplate. 次に、5 つの項目の最初のコレクションをそれに入力します (テキストと関連する XamlUICommand)。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. 次に、ICommand ExecuteRequested ハンドラーを定義します。このハンドラーに項目の削除コマンドを実装します。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. 最後に、PointerEnteredPointerExitedSelectionChanged イベントなど、さまざま ListView イベントのハンドラーを定義します。Finally, we define handlers for various ListView events, including PointerEntered, PointerExited, and SelectionChanged events. ポインターのイベント ハンドラーは、各項目の [削除] ボタンを表示するか、非表示にする目的で使用されます。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);
}

ICommand インターフェイスを使用したコマンド エクスペリエンスCommand experiences using the ICommand interface

標準の UWP コントロール (ボタン、リスト、選択、暦、予測テキスト) からは、さまざまな共通コマンド操作の基本が提供されます。Standard UWP controls (button, list, selection, calendar, predictive text) provide the basis for many common command experiences. コントロールの種類の完全一覧については、UWP アプリのコントロールとパターンに関するページを参照してください。For a complete list of control types, see Controls and patterns for UWP apps.

構造化されたコマンド処理をサポートする最も基本的な方法は、ICommand インターフェイスの実装を定義することです (Windows.UI.Xaml.Input.ICommand for C++ または System.Windows.Input.ICommand for 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#). この ICommand インスタンスはその後、ボタンなどのコントロールにバインドできます。This ICommand instance can then be bound to controls such as buttons.

注意

場合によっては、メソッドを Click イベントにバインドし、プロパティを 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.

Example

コマンド インターフェイスの例

ICommand 例ICommand example

この例のコードをダウンロードするDownload the code for this example
UWP コマンド処理サンプル (ICommand)UWP commanding sample (ICommand)

この基本例では、ボタン クリック、キーボード アクセラレータ、マウス ホイールの回転で 1 つのコマンドを呼び出す方法を実演します。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.

ListViews を 2 つ使用しますが、1 つには 5 つの項目を入力し、もう 1 つは空にします。また、ボタンを 2 つ使用しますが、1 つは左の ListView から右の ListView に項目を移動させるためのものであり、もう 1 つは右から左に項目を移動させるためのものです。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. 各ボタンは対応するコマンド (それぞれ、ViewModel.MoveRightCommand と ViewModel.MoveLeftCommand) にバインドされており、関連する ListView の項目数に基づいて自動的に有効または無効になります。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.

次の XAML コードでは、今回の例の UI が定義されます。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>

前の UI の分離コードは次のようになります。Here's the code-behind for the preceding UI.

分離コードでは、コマンド コードが含まれるビュー モデルに接続します。In code-behind, we connect to our view model that contains our command code. また、やはりコマンド コードをつなげる、マウス ホイールからの入力のためのハンドラーを定義します。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;
                }
            }
        }
    }
}

ビュー モデルからのコードは次のようになります。Here's the code from our view model

今回のビュー モデルでは、アプリに 2 つのコマンドの実行詳細を定義し、1 つの ListView に入力し、各 ListView の項目数に基づき、一部の追加 UI の表示/非表示を決定するための不透明度コンバーターを提供します。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();
        }
    }
}

最後になりますが、ICommand インターフェイスの実装は次のようになります。Finally, here's our implementation of the ICommand interface

ここで、ICommand インターフェイスを実装し、その機能性を他のオブジェクトにリレーするコマンドを定義します。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);
            }
        }
    }
}

概要Summary

ユニバーサル Windows プラットフォームからは、コントロールの種類、デバイス、入力の種類を問わず、コマンドを共有し、管理するアプリを構築できる堅牢かつ柔軟なコマンド処理システムが与えられます。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.

UWP アプリのコマンドを構築するときは、次の手法を使用してください。Use the following approaches when building commands for your UWP apps:

  • XAML/分離コードのイベントを待ち受け、処理するListen for and handle events in XAML/code-behind
  • クリックなど、イベント処理メソッドにバインドするBind to an event handling method such as Click
  • 独自の ICommand 実装を定義するDefine your own ICommand implementation
  • 事前定義された一連のプロパティに独自の値を指定し、XamlUICommand オブジェクトを定義するCreate XamlUICommand objects with your own values for a pre-defined set of properties
  • 事前定義された一連のプロパティや値を利用し、StandardUICommand オブジェクトを作成するCreate StandardUICommand objects with a set of pre-defined platform properties and values

次のステップNext steps

XamlUICommandStandardUICommand の実装を実演する完全な例については、XAML コントロール ギャラリー サンプルをご覧ください。For a complete example that demonstrates a XamlUICommand and StandardUICommand implementation, see the XAML Controls Gallery sample.

関連項目See also

UWP アプリのコントロールとパターンControls and patterns for UWP apps

サンプルSamples

トピックのサンプルTopic samples

その他のサンプルOther samples