Xamarin.Forms Menuitem

Baixar exemplo Baixar o exemplo

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 ListView menu de contexto no iOS e no Android:

A MenuItem classe define as seguintes propriedades:

  • Command é um ICommand que permite associar ações do usuário, como toques de dedo ou cliques, a comandos definidos em um viewmodel.
  • CommandParameter é um object que especifica o parâmetro que deve ser passado para o Command.
  • IconImageSource é um ImageSource valor que define o ícone de exibição.
  • IsDestructive é um bool valor que indica se o remove seu MenuItem elemento de interface do usuário associado da lista.
  • IsEnabled é um bool valor que indica se esse objeto responde à entrada do usuário.
  • Text é um string 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 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 o DataTemplate objeto para o ListViews ItemTemplate. Quando o ListView objeto for preenchido, ele criará cada item usando o DataTemplate, expondo as MenuItem opções quando o menu de contexto for 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 a esse evento para reagir a toques ou cliques na MenuItem 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 referenciavam um OnItemClicked manipulador de 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 o BindingContext no code-behind:

public MenuItemXamlMvvmPage()
{
    InitializeComponent();
    BindingContext = new ListPageViewModel(DataService.GetListItems());
}

Aviso

MenuItem somente os objetos exibem ícones no Android. Em outras plataformas, somente o texto especificado pela Text propriedade será exibido.

Í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 a desabilitação de um MenuItem em runtime, 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 associe a IsEnabled propriedade a outra propriedade ao usar a Command propriedade para habilitar ou desabilitar o MenuItem.

O exemplo a seguir mostra um MenuItem cuja Command propriedade é associada a um ICommand chamado 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 MenuItem é desabilitado até que a IsMenuItemEnabled propriedade seja definida. Quando isso ocorre, o método é chamado, o Command.ChangeCanExecute que faz com que o canExecute delegado seja MyCommand 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 por pressionamento longo em um item de lista. O menu de contexto substitui a área da barra de navegação e o título e MenuItem as opções são exibidas como botões horizontais.

No iOS, o menu de contexto é ativado passando o dedo em um item de lista. O menu de contexto é exibido no item de 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.