Xamarin.Forms Item de menu
A Xamarin.FormsMenuItem
classe define itens de menu para menus como ListView
menus de contexto de item e menus de submenu do aplicativo Shell.
As capturas de tela a seguir mostram MenuItem
objetos em um menu de ListView
contexto no iOS e no Android:
A classe MenuItem
define as seguintes propriedades:
Command
é umICommand
que permite associar ações do usuário, como toques ou cliques, a comandos definidos em um modelo de exibição.CommandParameter
é umobject
que especifica o parâmetro que deve ser passado para oCommand
.IconImageSource
é umImageSource
valor que define o ícone de exibição.IsDestructive
é umbool
valor que indica se o removeMenuItem
seu elemento de interface do usuário associado da lista.IsEnabled
é umbool
valor que indica se esse objeto responde à entrada do usuário.Text
é umstring
valor que especifica o texto de exibição.
Essas propriedades são apoiadas por BindableProperty
objetos para que a MenuItem
instância possa ser o destino de associações de dados.
Criar um MenuItem
MenuItem
Os objetos podem ser usados em um menu de contexto nos itens de um ListView
objeto. O padrão mais comum é criar MenuItem
objetos dentro de uma ViewCell
instância, que é usada como objeto DataTemplate
para o ListView
s ItemTemplate
. Quando o objeto é preenchido ListView
, ele cria cada item usando o DataTemplate
, expondo as MenuItem
opções quando o menu de contexto é ativado para um item.
O exemplo a seguir mostra MenuItem
a instanciação dentro do contexto de um ListView
objeto:
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Context Menu Option" />
</ViewCell.ContextActions>
<Label Text="{Binding .}" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Um MenuItem
também pode ser criado no código:
// 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
};
Definir o comportamento de MenuItem com eventos
A classe MenuItem
expõe um evento Clicked
. Um manipulador de eventos pode ser anexado MenuItem
a esse evento para reagir a toques ou cliques na instância em XAML:
<MenuItem ...
Clicked="OnItemClicked" />
Um manipulador de eventos também pode ser anexado no código:
MenuItem item = new MenuItem { ... }
item.Clicked += OnItemClicked;
Exemplos anteriores faziam referência a um manipulador de OnItemClicked
eventos. O código a seguir mostra um exemplo de implementação:
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
}
Definir o comportamento de MenuItem com MVVM
A MenuItem
classe dá suporte ao padrão MVVM (Model-View-ViewModel) por meio BindableProperty
de objetos e da ICommand
interface. O XAML a seguir mostra MenuItem
instâncias associadas a comandos definidos em um 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>
No exemplo anterior, dois MenuItem
objetos são definidos com suas Command
propriedades e CommandParameter
associadas a comandos no viewmodel. O viewmodel contém os comandos referenciados no 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}";
});
}
O aplicativo de exemplo inclui uma DataService
classe usada para obter uma lista de itens para preencher os ListView
objetos. Um viewmodel é instanciado, com itens da DataService
classe, e definido como no BindingContext
code-behind:
public MenuItemXamlMvvmPage()
{
InitializeComponent();
BindingContext = new ListPageViewModel(DataService.GetListItems());
}
Ícones MenuItem
Aviso
MenuItem
os objetos exibem apenas ícones no Android. Em outras plataformas, somente o texto especificado pela Text
propriedade será exibido.
Os ícones são especificados usando a IconImageSource
propriedade. Se um ícone for especificado, o texto especificado pela Text
propriedade não será exibido. A captura de tela a seguir mostra um MenuItem
com um ícone no Android:
Para obter mais informações sobre como usar imagens no Xamarin.Forms, consulte Imagens no Xamarin.Forms.
Habilitar ou desabilitar um MenuItem em runtime
Para habilitar ou desabilitar um MenuItem
em tempo de execução, associe sua Command
propriedade a uma ICommand
implementação e verifique se um canExecute
delegado habilita e desabilita o ICommand
conforme apropriado.
Importante
Não vincule a IsEnabled
propriedade a outra propriedade ao usar a Command
propriedade para habilitar ou desabilitar o MenuItem
.
O exemplo a seguir mostra uma MenuItem
propriedade whose Command
se liga a um ICommand
named MyCommand
:
<MenuItem Text="My menu item"
Command="{Binding MyCommand}" />
A ICommand
implementação requer um canExecute
delegado que retorna o valor de uma bool
propriedade para habilitar e desabilitar o 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);
}
}
Neste exemplo, o é desabilitado MenuItem
até que a IsMenuItemEnabled
propriedade seja definida. Quando isso ocorre, o método é chamado, o Command.ChangeCanExecute
que faz com que o canExecute
delegado for MyCommand
seja reavaliado.
Comportamento do menu de contexto multiplataforma
Os menus de contexto são acessados e exibidos de forma diferente em cada plataforma.
No Android, o menu de contexto é ativado pressionando longamente um item da lista. O menu de contexto substitui a área do título e da barra de navegação e MenuItem
as opções são exibidas como botões horizontais.
No iOS, o menu de contexto é ativado deslizando em um item da lista. O menu de contexto é exibido no item da lista e MenuItems
é exibido como botões horizontais.
Na UWP, o menu de contexto é ativado clicando com o botão direito do mouse em um item de lista. O menu de contexto é exibido próximo ao cursor como uma lista vertical.