Xamarin.FormsMenuItem 类定义菜单的菜单项,例如 ListView 项上下文菜单和 Shell 应用程序浮出控件菜单。
以下屏幕截图显示了 iOS 和 Android 上的 ListView 上下文菜单中的 MenuItem 对象:
MenuItem 类定义以下属性:
Command是一个ICommand,允许将用户操作(如手指点击或单击)绑定到 viewmodel 上定义的命令。CommandParameter是一个object,用于指定应传递给Command的参数。IconImageSource是定义显示图标的ImageSource值。IsDestructive是指示MenuItem是否从列表中删除其关联的 UI 元素的bool值。IsEnabled是指示此对象是否响应用户输入的bool值。Text是指定显示文本的string值。
这些属性由 BindableProperty 对象提供支持,因此 MenuItem 实例可以是数据绑定的目标。
创建 MenuItem
MenuItem 对象可在 ListView 对象项的上下文菜单中使用。 最常见的模式是在 ViewCell 实例中创建 MenuItem 对象,该实例用作 ListView ItemTemplate 的 DataTemplate 对象。 填充 ListView 对象时,它将使用 DataTemplate 创建每个项,并在为项激活上下文菜单时公开 MenuItem 选项。
以下示例演示 ListView 对象上下文中的 MenuItem 实例化:
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Context Menu Option" />
</ViewCell.ContextActions>
<Label Text="{Binding .}" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
还可以在代码中创建 MenuItem:
// 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 事件。 事件处理程序可以附加到此事件,以响应 XAML 中对 MenuItem 实例的点击或单击操作:
<MenuItem ...
Clicked="OnItemClicked" />
还可以在代码中附加事件处理程序:
MenuItem item = new MenuItem { ... }
item.Clicked += OnItemClicked;
前面的示例引用了 OnItemClicked 事件处理程序。 以下代码演示了一个示例实现:
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
}
使用 MVVM 定义 MenuItem 行为
MenuItem 类通过 BindableProperty 对象和 ICommand 接口支持模型-视图-视图模型 (MVVM) 模式。 以下 XAML 显示绑定到在 viewmodel 上定义的命令的 MenuItem 实例:
<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 属性绑定到 viewmodel 上的命令。 viewmodel 包含 XAML 中引用的命令:
public class ListPageViewModel : INotifyPropertyChanged
{
...
public ICommand EditCommand => new Command<string>((string item) =>
{
Message = $"Edit command was called on: {item}";
});
public ICommand DeleteCommand => new Command<string>((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 属性指定的文本。 以下屏幕截图显示了 Android 上带有图标的 MenuItem:
![]()
有关在 Xamarin.Forms 中使用图像的详细信息,请参阅 Xamarin.Forms 中的图像。
在运行时启用或禁用 MenuItem
若要在运行时启用或禁用 MenuItem,请将其 Command 属性绑定到 ICommand 实现,并确保 canExecute 委托根据需要启用或禁用 ICommand。
重要
使用 Command 属性启用或禁用 MenuItem 时,请勿将 IsEnabled 属性绑定到另一个属性。
以下示例演示了其 Command 属性绑定到 ICommand(名为 MyCommand)的 MenuItem:
<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);
}
}
在此示例中,设置 IsMenuItemEnabled 属性之前一直禁用 MenuItem。 发生这种情况时,将会调用 Command.ChangeCanExecute 方法,以便重新评估委托 MyCommand 的 canExecute 委托。
跨平台上下文菜单行为
上下文菜单在每个平台上以不同的方式进行访问和显示。
在 Android 上,通过长按列表项来激活上下文菜单。 上下文菜单可替换标题和导航栏区域,MenuItem 选项显示为水平按钮。
![]()
在 iOS 上,通过轻扫列表项来激活上下文菜单。 上下文菜单显示在列表项上,MenuItems 显示为水平按钮。

在 UWP 上,通过右键单击列表项来激活上下文菜单。 上下文菜单在光标附近显示为垂直列表。

