Контекстно-зависимые команды для коллекций и списковContextual commanding for collections and lists

Многие приложения содержат коллекции содержимого в виде списков, сеток и деревьев, которыми пользователи могут управлять.Many apps contain collections of content in the form of lists, grids, and trees that users can manipulate. Например, пользователи могут удалять, переименовывать, отмечать или обновлять элементы.For example, users might be able to delete, rename, flag, or refresh items. В этой статье показано, как использовать контекстно-зависимые команды для реализации такого рода действий способом, который предоставляет наилучшее взаимодействие для всех типов ввода.This article shows you how to use contextual commands to implement these sorts of actions in a way that provides the best possible experience for all input types.

Важные API: интерфейс ICommand, свойство UIElement.ContextFlyout, интерфейс INotifyPropertyChangedImportant APIs: ICommand interface, UIElement.ContextFlyout property, INotifyPropertyChanged interface

Используйте различные методы ввода для выполнения команды Favorite

Создание команд для всех типов вводаCreating commands for all input types

Так как пользователи могут взаимодействовать с приложением Windows с помощью широкого спектра устройств и типов ввода, приложения должны предоставлять контекстные меню, не зависящие от метода ввода, и ускорители конкретного метода ввода.Because users can interact with a Windows app using a broad range of devices and inputs, your app should expose commands though both input-agnostic context menus and input-specific accelerators. Включение обеих позволяет пользователю быстро вызывать команды на содержимом, независимо от типа ввода или устройства.Including both lets the user quickly invoke commands on content, regardless of input or device type.

В этой таблице показаны некоторые стандартные команды коллекции и способы их отображения.This 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 Клавиша DELDEL key Провести, чтобы удалитьSwipe to delete
Отметить элементFlag item Контекстное менюContext menu Кнопка при наведенииHover button CTRL+SHIFT+GCtrl+Shift+G Провести пальцем, чтобы пометитьSwipe to flag
Обновить данныеRefresh data Контекстное менюContext menu Н/ДN/A Клавиша F5F5 key Обновление путем оттягиванияPull to refresh
Добавить элемент в избранноеFavorite an item Контекстное менюContext menu Кнопка при наведенииHover button F, CTRL+SF, Ctrl+S Провести, чтобы добавить в избранноеSwipe to favorite
  • Как правило, следует создать все команды для элемента, доступные в контекстном меню элемента.In general, you should make all commands for an item available in the item's context menu. Контекстные меню доступны пользователям, независимо от типа ввода и должны содержать все контекстно-зависимые команды, которые пользователь может выполнить.Context menus are accessible to users regardless of input type, and should contain all of the contextual commands that user can perform.

  • Для часто используемых команд рассмотрите возможность использования ускорителей ввода.For frequently accessed commands, consider using input accelerators. Ускорители ввода позволяют пользователю быстро выполнять действия на основе их устройства ввода.Input accelerators let the user perform actions quickly, based on their input device. Ускорители ввода включают в себя:Input accelerators include:

    • действие проведения пальцем (ускоритель сенсорного ввода);Swipe-to-action (touch accelerator)
    • обновление путем оттягивания (ускоритель сенсорного ввода);Pull to refresh data (touch accelerator)
    • сочетания клавиш (ускоритель клавиатуры);Keyboard shortcuts (keyboard accelerator)
    • клавиши доступа (акселератор клавиатуры);Access keys (keyboard accelerator)
    • кнопки мыши и пера при наведении (ускоритель указателя).Mouse & Pen hover buttons (pointer accelerator)

Примечание

Пользователи должны иметь возможность доступа ко всем командам из любого типа устройства.Users should be able to access all commands from any type of device. Например, если команды вашего приложения доступны только через ускорители указателя кнопки при наведении, пользователи сенсорного ввода не смогут получить к ним доступ.For example, if your app’s commands are only exposed through hover button pointer accelerators, touch users won't be able to access them. По крайней мере, используйте контекстное меню для предоставления доступа ко всем командам.At a minimum, use a context menu to provide access to all commands.

Пример: Модель данных PodcastObjectExample: The PodcastObject data model

Для демонстрации наших рекомендаций по командам в этой статье создан список подкастов для приложения подкастов.To demonstrate our commanding recommendations, this article creates a list of podcasts for a podcast app. В примере кода показано, как разрешить пользователю "добавлять в избранное" определенный подкаст из списка.The example code demonstrate how to enable the user to "favorite" a particular podcast from a list.

Вот определение объекта подкаста, с которым мы будем работать:Here's the definition for the podcast object we'll be working with:

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

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

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

    public event PropertyChangedEventHandler PropertyChanged;

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

Обратите внимание на то, что PodcastObject реализует INotifyPropertyChanged, чтобы реагировать на изменения свойств, когда пользователь переключает свойство IsFavorite.Notice that the PodcastObject implements INotifyPropertyChanged to respond to property changes when the user toggles the IsFavorite property.

Определение команд с помощью интерфейса ICommandDefining commands with the ICommand interface

Интерфейс ICommand помогает определить команду, которая доступна для нескольких типов ввода.The ICommand interface helps you to define a command that's available for multiple input types. Например, вместо написания одного и того же кода для команды удаления в двух разных обработчиках событий, одного — для нажатия клавиши Delete пользователем, и одного — для выбора команды "Удалить" в контекстном меню правой кнопки мыши, вы можете реализовать логику удаления один раз, как ICommand, и сделать ее доступной для различных типов ввода.For example, instead of writing the same code for a delete command in two different event handlers, one for when the user presses the Delete key and one for when the user right clicks "Delete" in a context menu, you can implement your delete logic once, as an ICommand, and then make it available to different input types.

Необходимо определить ICommand, которая представляет действие "Favorite".We need to define the ICommand that represents the "Favorite" action. Мы будем использовать метод Execute команды для добавления подкаста в избранное.We will use the command's Execute method to favorite a podcast. Определенный подкаст будет предоставлен методу execute через параметр команды, который может быть связан с помощью свойства CommandParameter.The particular podcast will be provided to the execute method via the command's parameter, which can be bound using the CommandParameter property.

public class FavoriteCommand: ICommand
{
    public event EventHandler CanExecuteChanged;

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

Для использования одной и той же команды с несколькими коллекциями и элементами вы можете сохранить команду как ресурс на странице или в приложении.To use the same command with multiple collections and elements, you can store the command as a resource on the page or on the app.

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

Чтобы выполнить команду, следует вызвать ее метод Execute.To execute the command, you call its Execute method.

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

Создание элемента UserControl для реагирования на различные методы вводаCreating a UserControl to respond to a variety of inputs

Если у вас имеется список элементов и каждый из этих элементов должен реагировать на несколько типов ввода, можно упростить код путем определения UserControl для элемента и его использования для определения контекстного меню и обработчиков событий своих элементов.When you have a list of items and each of those items should respond to multiple inputs, you can simplify your code by defining a UserControl for the item and using it to define your items' context menu and event handlers.

Создание UserControl в Visual Studio.To create a UserControl in Visual Studio:

  1. В обозревателе решений щелкните проект правой кнопкой мыши.In the Solution Explorer, right click the project. Откроется контекстное меню.A context menu appears.
  2. Выберите Добавить > Новый элемент...Select Add > New Item...
    Откроется диалоговое окно Добавление нового элемента.The Add New Item dialog appears.
  3. Выберите UserControl из списка элементов.Select UserControl from the list of items. Присвойте ему имя и нажмите кнопку Добавить.Give it the name you want and click Add. Visual Studio создаст заглушку UserControl.Visual Studio will generate a stub UserControl for you.

В нашем примере подкаста каждый подкаст будет отображаться в списке, который будет представлять различные способы добавления подкаста в "Избранное".In our podcast example, each podcast will be displayed in a list, which will expose a variety of ways to "Favorite" a podcast. Пользователь сможет выполнять следующие действия для добавления подкаста в "Избранное".The user will be able to perform the following actions to "Favorite" the podcast:

  • Вызов контекстного менюInvoke a context menu
  • Выполнение сочетаний клавишPerform keyboard shortcuts
  • Отображение кнопки при наведенииShow a hover button
  • Жест прокруткиPerform a swipe gesture

Чтобы инкапсулировать эти поведения и использовать FavoriteCommand, давайте создадим новый объект UserControl с именем "PodcastUserControl" для представления подкастов в списке.In order to encapsulate these behaviors and use the FavoriteCommand, let's create a new UserControl named "PodcastUserControl" to represent a podcast in the list.

Элемент PodcastUserControl отображает поля объекта PodcastObject как TextBlocks и отвечает на различные виды взаимодействия с пользователем.The PodcastUserControl displays the fields of the PodcastObject as TextBlocks, and responds to various user interactions. Мы будем ссылаться и развертывать объект PodcastUserControl в этой статье.We will reference and expand upon the PodcastUserControl throughout this article.

PodcastUserControl.xamlPodcastUserControl.xaml

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

PodcastUserControl.xaml.csPodcastUserControl.xaml.cs

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

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

    public PodcastUserControl()
    {
        this.InitializeComponent();

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

Обратите внимание на то, что PodcastUserControl содержит ссылку на PodcastObject как DependencyProperty.Notice that the PodcastUserControl maintains a reference to the PodcastObject as a DependencyProperty. Это позволяет нам связать PodcastObjects с PodcastUserControl.This enables us to bind PodcastObjects to the PodcastUserControl.

После создания нескольких объектов PodcastObjects можно создать список подкастов с помощью привязки PodcastObjects к элементу управления ListView.After you have generated some PodcastObjects, you can create a list of podcasts by binding the PodcastObjects to a ListView. Объекты PodcastUserControl описывают визуализацию объектов PodcastObjects и, таким образом, задаются с помощью элемента ItemTemplate ListView.The PodcastUserControl objects describe the visualization of the PodcastObjects, and are therefore set using the ListView's ItemTemplate.

MainPage.xamlMainPage.xaml

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

Создание контекстных менюCreating context menus

В контекстных меню отображается список команд или параметров, когда пользователь запрашивает их.Context menus display a list of commands or options when the user requests them. Контекстные меню предоставляют контекстно-зависимые команды, связанные с их присоединенным элементом, и обычно зарезервированы для дополнительных действий, относящихся к этому элементу.Context menus provide contextual commands related to their attached element, and are generally reserved for secondary actions specific to that item.

Отображение контекстного меню для элемента

Пользователь может вызвать контекстные меню с помощью следующих "контекстных действий".The user can invoke context menus using these "context actions":

ВводInput Контекстное действиеContext action
МышьMouse Щелчок правой кнопкой мышиRight click
КлавиатураKeyboard SHIFT+F10, кнопка менюShift+F10, Menu button
TouchTouch Длительное нажатие элементаLong press on item
ПероPen Нажатие кнопки пера, длительное нажатие элементаBarrel button press, long press on item
ГеймпадGamepad Кнопка менюMenu button

Так как пользователь может открыть контекстное меню независимо от типа ввода, ваше контекстное меню должно содержать все контекстно-зависимые команды, доступные для элемента списка.Since the user can open a context menu regardless of input type, your context menu should contain all of the contextual commands available for the list item.

ContextFlyoutContextFlyout

Свойство ContextFlyout, определенное в классе UIElement, позволяет легко создать контекстное меню, которое работает со всеми типами ввода.The ContextFlyout property, defined by the UIElement class, makes it easy to create a context menu that works with all input types. Вы предоставляете всплывающий элемент, представляющий ваше контекстное меню, с помощью MenuFlyout, и когда пользователь выполняет "контекстное действие", как указано выше, отображается объект MenuFlyout, соответствующий элементу.You provide a flyout representing your context menu using MenuFlyout, and when the user performs a “context action” as defined above, the MenuFlyout corresponding to the item will be displayed.

Мы добавим ContextFlyout к PodcastUserControl.We will add a ContextFlyout to the PodcastUserControl. MenuFlyout, указанный как ContextFlyout, содержит один элемент для добавления подкаста в избранное.The MenuFlyout specified as the ContextFlyout contains a single item to favorite a podcast. Обратите внимание на то, что этот MenuFlyoutItem использует действие favoriteCommand, определенное выше, с привязкой CommandParamter к PodcastObject.Notice that this MenuFlyoutItem uses the favoriteCommand defined above, with the CommandParamter bound to the PodcastObject.

PodcastUserControl.xamlPodcastUserControl.xaml

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

Обратите внимание на то, что вы также можете использовать событие ContextRequested, чтобы реагировать на действия контекста.Note that you can also use the ContextRequested event to respond to context actions. Событие ContextRequested не сработает, если был указан ContextFlyout.The ContextRequested event will not fire if a ContextFlyout has been specified.

Создание ускорителей вводаCreating input accelerators

Несмотря на то, что каждый элемент в коллекции должен иметь контекстное меню, содержащее все контекстно-зависимых команды, вы можете предоставить пользователям возможность быстро выполнять небольшой набор часто выполняемых команд.Although each item in the collection should have a context menu containing all contextual commands, you might want to enable users to quickly perform a smaller set of frequently performed commands. Например, почтовые приложения могут иметь дополнительные команды, такие как "Ответить", "Архивировать", "Переместить в папку", "Установить флажок" и "Удалить", которые отображаются в контекстном меню, но наиболее часто используемыми командами являются "Удалить" и "Пометить".For example, a mailing app may have secondary commands like Reply, Archive, Move to Folder, Set Flag, and Delete which appear in a context menu, but the most common commands are Delete and Flag. После определения, какие команды используются чаще, можно использовать упростить ускорители ввода, чтобы упростить выполнение этих команд пользователями.After you have identified which commands are most common, you can use input-based accelerators to make these commands easier for a user to perform.

В приложении подкастов часто выполняемая команда — "Добавить в избранное".In the podcast app, the frequently performed command is the "Favorite" command.

Сочетания клавишKeyboard accelerators

Сочетания клавиш и прямая обработка нажатия клавишShortcuts and direct key handling

Нажатие клавиш CTRL и F для выполнения действия

В зависимости от типа содержимого вы можете определить определенные сочетания клавиш, которые должны выполнять действие.Depending on the type of content, you may identify certain key combinations that should perform an action. В приложении электронной почты, например, клавиша DEL может использоваться для удаления выбранного сообщения.In an email app, for example, the DEL key may be used to delete the email that is selected. В приложении подкастов клавиши CTRL+S или F могут добавлять подкаст в избранное для использования в будущем.In a podcast app, the Ctrl+S or F keys could favorite a podcast for later. Хотя у некоторых команд есть общие, известные сочетания клавиш, например, DEL для удаления, другие команды могут использовать сочетания клавиш для конкретного приложения или домена.Although some commands have common, well-known keyboard shortcuts like DEL to delete, other commands have app- or domain-specific shortcuts. По возможности используйте известные клавиши или рассмотрите возможность предоставления текста напоминания в подсказке для обучения пользователя.Use well-known shortcuts if possible, or consider providing reminder text in a tooltip to teach the user about the shortcut command.

Ваше приложение может отвечать, когда пользователь нажимает клавишу, с помощью события KeyDown.Your app can respond when the user presses a key using the KeyDown event. Как правило, пользователи ожидают, что приложение будет реагировать при первом нажатии клавиши, а не ждать, пока они отпустят ее.In general, users expect that the app will respond when they first press the key down, rather than waiting until they release the key.

В этом примере рассмотрено, как добавить обработчик KeyDown в PodcastUserControl, чтобы добавить подкаст в Избранное, когда пользователь нажимает клавиши CTRL+S. Используется та же команда, что и раньше.This example walks through how to add the KeyDown handler to the PodcastUserControl to favorite a podcast when the user presses Ctrl+S or F. It uses the same command as before.

PodcastUserControl.xaml.csPodcastUserControl.xaml.cs

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

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

Ускорители мышиMouse accelerators

Наведение указателя мыши на элемент, чтобы показать кнопки

Пользователям знакомы контекстные меню правой кнопки мыши, но вы можете предоставить пользователям возможность выполнять распространенные команды с использованием только одного щелчка мыши.Users are familiar with right-click context menus, but you may wish to empower users to perform common commands using only a single click of the mouse. Для включения этой возможности вы можете включить специальные кнопки на холсте элемента коллекции.To enable this experience, you can include dedicated buttons on your collection item's canvas. Чтобы предоставить пользователям возможность действовать быстро с помощью мыши и свести к минимуму визуальные помехи, вы можете выбрать только отображение этих кнопок, когда пользователь наводит указатель на определенный элемент в списке.To both empower users to act quickly using mouse, and to minimize visual clutter, you can choose to only reveal these buttons when the user has their pointer within a particular list item.

В этом примере команда "Добавить в избранное" представлена кнопкой, определенной непосредственно в PodcastUserControl.In this example, the Favorite command is represented by a button defined directly in the PodcastUserControl. Отметим, что кнопка в этом примере использует ту же команду, FavoriteCommand, что и раньше.Note that the button in this example uses the same command, FavoriteCommand, as before. Для переключения видимости этой кнопки можно использовать VisualStateManager для переключения между визуальными состояниями, когда указатель входит в элемент управления или выходит из него.To toggle visibility of this button, you can use the VisualStateManager to switch between visual states when the pointer enters and exits the control.

PodcastUserControl.xamlPodcastUserControl.xaml

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

Кнопки при наведении должны отображаться и исчезать при входе мыши и ее выходе из элемента.The hover buttons should appear and disappear when the mouse enters and exits the item. Для реагирования на события мыши можно использовать события PointerEntered и PointerExited в PodcastUserControl.To respond to mouse events, you can use the PointerEntered and PointerExited events on the PodcastUserControl.

PodcastUserControl.xaml.csPodcastUserControl.xaml.cs

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

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

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

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

Кнопки, отображаемые в состоянии наведения, будут доступны только через тип ввода указателя.The buttons displayed in the hover state will only be accessible via the pointer input type. Так как эти кнопки ограничены вводом указателем, вы можете свести к минимуму или удалить заполнение вокруг значка кнопки, чтобы оптимизировать ввод указателем.Because these buttons are limited to pointer input, you may choose to minimize or remove the padding around the icon of the button to optimize for pointer input. Если вы решите сделать это, убедитесь, что размер кнопки не меньше 20х20 пикселей, чтобы ее можно было использовать с пером и мышью.If you choose to do so, ensure that the button footprint is at least 20x20px to remain usable with pen and mouse.

Ускорители сенсорного вводаTouch accelerators

SwipeSwipe

Проведение пальцем по элементу для отображения команды

Команды проведения — это акселератор сенсорного ввода, который позволяет пользователям сенсорных устройств выполнять распространенные дополнительные действия с помощью сенсорного ввода.Swipe commanding is a touch accelerator that enables users on touch devices to perform common secondary actions using touch. Проведение позволяет пользователям сенсорных устройств быстро и естественно взаимодействовать с содержимым с помощью общих операций, например, прокрутки для удаления или проведения для вызова.Swipe empowers touch users to quickly and naturally interact with content, using common actions like Swipe-to-Delete or Swipe-to-Invoke. В статье Команды прокрутки приведены дополнительные сведения.See the swipe commanding article to learn more.

Чтобы интегрировать проведение в коллекцию, вам потребуются два компонента: SwipeItems, в котором размещается команды, и SwipeControl, который служит оболочкой для элемента и обеспечивает взаимодействие проведением.In order to integrate swipe into your collection, you need two components: SwipeItems, which hosts the commands; and a SwipeControl, which wraps the item and allows for swipe interaction.

SwipeItems может быть определен как Resource в PodcastUserControl.The SwipeItems can be defined as a Resource in the PodcastUserControl. В этом примере SwipeItems содержит команду к добавления элемента в избранное.In this example, SwipeItems contains a command to Favorite an item.

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

SwipeControl создает программу-оболочку элемента, и позволяет пользователю взаимодействовать с ним с помощью жеста прокрутки.The SwipeControl wraps the item and allows the user to interact with it using the swipe gesture. Обратите внимание на то, что SwipeControl содержит ссылку на SwipeItems как его RightItems.Notice that the SwipeControl contains a reference to the SwipeItems as its RightItems. Элемент Favorite будет отображаться, когда пользователь будет проводить пальцем справа налево.The Favorite item will show when the user swipes from right to left.

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

Когда пользователь проводит для вызова команды избранного, вызывается соответствующий метод.When the user swipes to invoke the Favorite command, the Invoked method is called.

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

Обновление путем оттягиванияPull to refresh

Обновление путем оттягивания позволяет пользователю потянуть коллекцию данных вниз, чтобы получить дополнительные данные.Pull to refresh lets a user pull down on a collection of data using touch in order to retrieve more data. В статье Обновление путем оттягивания содержатся дополнительные сведения.See the pull to refresh article to learn more.

Ускорители пераPen accelerators

Тип ввода пером обеспечивает точность ввода указателем.The pen input type provides the precision of pointer input. Пользователи могут выполнять основные действия, например, открывать контекстное меню, с помощью ускорителей пера.Users can perform common actions such as opening context menus using pen-based accelerators. Чтобы открыть контекстное меню, пользователи могут коснуться экрана при нажатой кнопке пера или нажать и удерживать содержимое.To open a context menu, users can tap the screen with the barrel button pressed, or long press on the content. Пользователи также могут использовать перо для наведения указателя на содержимое, чтобы получить более глубокое понимание пользовательского интерфейса, например, отобразить всплывающие подсказки или дополнительные действия при наведении, аналогично мыши.Users can also use the pen to hover over content to get a deeper understanding of the UI like displaying tooltips, or to reveal secondary hover actions, similar to mouse.

Чтобы оптимизировать приложение для ввода с помощью пера, изучите статью Взаимодействие пера и стилуса.To optimize your app for pen input, see the pen and stylus interaction article.

Что рекомендуется и что не рекомендуется делатьDo's and don'ts

  • Убедитесь, что пользователи имеют доступ ко всем командам со всех типов устройств Windows.Do make sure that users can access all commands from all types of Windows devices.
  • Включайте контекстное меню, которое предоставляет доступ ко всем командам, доступным для элемента коллекции.Do include a context menu that provides access to all the commands available for a collection item.
  • Предоставьте ускорители ввода для часто используемых команд.Do provide input accelerators for frequently-used commands.
  • Используйте интерфейс ICommand для реализации команд.Do use the ICommand interface to implement commands.