Класс Xamarin.Forms MenuItem определяет элементы для контекстных меню элементов ListView и всплывающих меню для приложений Shell.
На следующих скриншотах показаны объекты MenuItem в контекстном меню ListView на iOS и Android:

Класс MenuItem определяет следующие свойства:
- Command – ICommand, позволяющий привязывать действия пользователя, такие как касания пальцем или щелчки, к командам, определенным на вью-модели.
- CommandParameter – объект, определяющий параметр, который должен быть передан команде.
- IconImageSource – значение ImageSource, определяющее иконку дисплея.
- IsDestructive – bool-значение, указывающее, удаляет ли данный MenuItem связанный с ним элемент пользовательского интерфейса из списка.
- IsEnabled – bool-значение, указывающее, реагирует ли данный объект на ввод пользователя.
- Text – строковое значение, задающее текст отображения.
Эти свойства поддерживаются объектами BindableProperty, поэтому экземпляр MenuItem может быть объектом привязки данных.
Создание MenuItem
Объекты MenuItem могут использоваться в контекстном меню Xamarin для элементов объекта ListView. Чаще всего такие объекты создаются в экземпляре ViewCell, который используется в качестве объекта DataTemplate для шаблона элементов ListView. Когда объект ListView заполняется, он создает каждый элемент с использованием шаблона DataTemplate, раскрывая возможности выбора MenuItem при активации контекстного меню для элемента.
Следующий пример показывает реализацию MenuItem в контексте объекта ListView:
<ListView> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <ViewCell.ContextActions> <MenuItem Text="Context Menu Option" /> </ViewCell.ContextActions> <Label Text="{Binding .}" /> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView>
MenuItem также может быть создан в коде:
C#
// A function returns a ViewCell instance that
// is used as the template for each list item
DataTemplate dataTemplate = new DataTemplate(() =>
{
// A Label displays the list item text
Label label = new Label();
label.SetBinding(Label.TextProperty, ".");
// A ViewCell serves as the DataTemplate
ViewCell viewCell = new ViewCell
{
View = label
};
// Add a MenuItem instance to the ContextActions
MenuItem menuItem = new MenuItem
{
Text = "Context Menu Option"
};
viewCell.ContextActions.Add(menuItem);
// The function returns the custom ViewCell
// to the DataTemplate constructor
return viewCell;
});
// Finally, the dataTemplate is provided to
// the ListView object
ListView listView = new ListView
{
...
ItemTemplate = dataTemplate
};
Определение поведения MenuItem с помощью событий
Класс MenuItem предоставляет событие Clicked. К этому событию может быть присоединен хэндлер, реагирующий на нажатия или клики на элемент MenuItem в XAML:
<MenuItem ...
Clicked="OnItemClicked" />
Обработчик события также может быть вложен в код:
C#
MenuItem item = new MenuItem { ... }
item.Clicked += OnItemClicked;
В предыдущих примерах упоминался обработчик события OnItemClicked. В следующем коде показан пример его реализации:
C#
void OnItemClicked(object sender, EventArgs e)
{
// The sender is the menuItem
MenuItem menuItem = sender as MenuItem;
// Access the list item through the BindingContext
var contextItem = menuItem.BindingContext;
// Do something with the contextItem here
}
Определение поведения MenuItem с помощью MVVM
Класс MenuItem поддерживает паттерн Model-View-ViewModel (MVVM) с помощью объектов BindableProperty и интерфейса ICommand. Следующий XAML показывает экземпляры MenuItem, привязанные к командам, определенным на ViewModel:
<ContentPage.BindingContext> <viewmodels:ListPageViewModel /> </ContentPage.BindingContext> <StackLayout> <Label Text="{Binding Message}" ... /> <ListView ItemsSource="{Binding Items}"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <ViewCell.ContextActions> <MenuItem Text="Edit" IconImageSource="icon.png" Command="{Binding Source={x:Reference contentPage}, Path=BindingContext.EditCommand}" CommandParameter="{Binding .}"/> <MenuItem Text="Delete" Command="{Binding Source={x:Reference contentPage}, Path=BindingContext.DeleteCommand}" CommandParameter="{Binding .}"/> </ViewCell.ContextActions> <Label Text="{Binding .}" /> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackLayout>
В предыдущем примере определены два объекта MenuItem, свойства которых Command и CommandParameter привязаны к командам на модели представления. Модель представления содержит команды, на которые ссылается XAML:
public class ListPageViewModel : INotifyPropertyChanged
{
...
public ICommand EditCommand => new Command((string item) =>
{
Message = $"Edit command was called on: {item}";
});
public ICommand DeleteCommand => new Command((string item) =>
{
Message = $"Delete command was called on: {item}";
});
}
Пример приложения включает класс DataService, который используется для получения списка элементов для заполнения объектов ListView. Реализуется ViewModel с элементами из класса DataService и устанавливается в качестве BindingContext в код:
public MenuItemXamlMvvmPage()
{
InitializeComponent();
BindingContext = new ListPageViewModel(DataService.GetListItems());
}
Иконки MenuItem
Предупреждение. Объекты MenuItem отображают значки только на Android. На других платформах будет отображаться только текст, заданный свойством Text.
Иконки указываются с помощью свойства IconImageSource. Если задан значок, то текст, указанный в свойстве Text, отображаться не будет. На следующем снимке экрана показан MenuItem с иконкой на Android:

Включение и отключение пункта меню во время выполнения программы
Чтобы включить или выключить элемент меню во время выполнения, привяжите его свойство Command к реализации ICommand и убедитесь, что canExecute включает и выключает ICommand в зависимости от ситуации.
Важно. Не связывайте свойство IsEnabled с другим свойством при использовании свойства Command для включения или выключения MenuItem.
В следующем примере показан MenuItem, свойство Command которого связывается с ICommand с именем MyCommand:
<MenuItem Text="My menu item"
Command="{Binding MyCommand}" />
Реализация ICommand требует наличия делегата canExecute, который возвращает значение свойства bool для включения и выключения MenuItem:
public class MyViewModel : INotifyPropertyChanged
{
bool isMenuItemEnabled = false;
public bool IsMenuItemEnabled
{
get { return isMenuItemEnabled; }
set
{
isMenuItemEnabled = value;
MyCommand.ChangeCanExecute();
}
}
public Command MyCommand { get; private set; }
public MyViewModel()
{
MyCommand = new Command(() =>
{
// Execute logic here
},
() => IsMenuItemEnabled);
}
}
В данном примере элемент MenuItem отключен до тех пор, пока не будет установлено свойство IsMenuItemEnabled. Когда это происходит, вызывается метод Command.ChangeCanExecute, который приводит к переоценке делегата canExecute для MyCommand.
Кроссплатформенное поведение контекстного меню
Доступ к контекстному меню и его отображение на каждой платформе осуществляется по-разному.
На Android контекстное меню активируется долгим нажатием на элемент списка. Контекстное меню заменяет область заголовка и навигационной панели, а опции MenuItem отображаются в виде горизонтальных кнопок.

В iOS контекстное меню активируется при проведении пальцем по элементу списка. Контекстное меню отображается на элементе списка, а MenuItems отображаются в виде горизонтальных кнопок.

В UWP контекстное меню активируется щелчком правой кнопки мыши на элементе списка. Контекстное меню отображается рядом с курсором в виде вертикального списка.
