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 é um ICommand que permite associar ações do usuário, como toques ou cliques, a comandos definidos em um modelo de exibição.
  • 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 MenuItem seu 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 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 ListViews 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());
}

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.