Xamarin.Forms Menuitem

Die Xamarin.FormsMenuItem Klasse definiert Menüelemente für Menüs wie ListView Elementkontextmenüs und Shell-Anwendungs-Flyoutmenüs.

Die folgenden Screenshots zeigen MenuItem Objekte in einem ListView Kontextmenü unter iOS und Android:

Die MenuItem-Klasse definiert die folgenden Eigenschaften:

  • Command ist ein ICommand, das die Bindung von Benutzeraktionen, wie Fingertipps oder Klicks, an Befehle ermöglicht, die in einem Viewmodel definiert sind.
  • CommandParameter ist ein object, das den Parameter angibt, der an den Command übergeben werden soll.
  • IconImageSource ist ein ImageSource Wert, der das Anzeigesymbol definiert.
  • IsDestructive ist ein bool Wert, der angibt, ob das MenuItem zugeordnete UI-Element aus der Liste entfernt wird.
  • IsEnabled ist ein bool Wert, der angibt, ob dieses Objekt auf Benutzereingaben reagiert.
  • Text ist ein string Wert, der den Anzeigetext angibt.

Diese Eigenschaften werden von BindableProperty Objekten gesichert, sodass die MenuItem Instanz das Ziel von Datenbindungen sein kann.

Erstellen eines MenuItem

MenuItem Objekte können in einem Kontextmenü für die Elemente eines ListView Objekts verwendet werden. Das am häufigsten verwendete Muster besteht darin, Objekte innerhalb einer ViewCell Instanz zu erstellenMenuItem, die als DataTemplate Objekt für die ListViewObjekte ItemTemplateverwendet werden. Wenn das ListView-Objekt aufgefüllt wird, wird jedes Element mithilfe des DataTemplate-Objekts erstellt. Die MenuItem-Auswahlmöglichkeiten werden dabei verfügbar gemacht, wenn das Kontextmenü für ein Element aktiviert wird.

Das folgende Beispiel zeigt MenuItem die Instanziierung im Kontext eines ListView Objekts:

<ListView>
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <ViewCell.ContextActions>
                    <MenuItem Text="Context Menu Option" />
                </ViewCell.ContextActions>
                <Label Text="{Binding .}" />
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Ein MenuItem kann auch im Code erstellt werden:

// 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
};

Definieren des MenuItem-Verhaltens mit Ereignissen

Die MenuItem-Klasse macht ein Clicked-Ereignis verfügbar. An dieses Ereignis kann ein Ereignishandler angefügt werden, um auf Tippen oder Klicks auf die MenuItem Instanz in XAML zu reagieren:

<MenuItem ...
          Clicked="OnItemClicked" />

Ein Ereignishandler kann auch im Code hinzugefügt werden:

MenuItem item = new MenuItem { ... }
item.Clicked += OnItemClicked;

In früheren Beispielen wurde auf einen OnItemClicked Ereignishandler verwiesen. Der folgende Code zeigt eine Beispielimplementierung:

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
}

Definieren des MenuItem-Verhaltens mit MVVM

Die MenuItem Klasse unterstützt das Model-View-ViewModel (MVVM)-Muster über BindableProperty Objekte und die ICommand Schnittstelle. Der folgende XAML-Code zeigt Instanzen, MenuItem die an Befehle gebunden sind, die in einem Ansichtsmodell definiert sind:

<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>

Im vorherigen Beispiel werden zwei MenuItem Objekte mit ihren Command und CommandParameter eigenschaften definiert, die an Befehle im Ansichtsmodell gebunden sind. Das Ansichtsmodell enthält die Befehle, auf die im XAML-Code verwiesen wird:

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}";
    });
}

Die Beispielanwendung enthält eine DataService Klasse zum Abrufen einer Liste von Elementen zum Auffüllen der ListView Objekte. Ein Ansichtsmodell wird instanziiert, mit Elementen aus der DataService Klasse und als BindingContext codeBehind festgelegt:

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

Warnung

MenuItem-Objekte zeigen nur Symbole unter Android an. Auf anderen Plattformen wird nur der durch die Text-Eigenschaft spezifizierte Text angezeigt.

Symbole werden mithilfe der IconImageSource-Eigenschaft angegeben. Wenn ein Symbol angegeben wird, wird der durch die Text Eigenschaft angegebene Text nicht angezeigt. Der folgende Screenshot zeigt ein MenuItem mit einem Symbol unter Android:

Weitere Informationen zur Verwendung von Bildern in finden Sie unter "Bilder" Xamarin.Formsin Xamarin.Forms.

Aktivieren oder Deaktivieren eines MenuItem zur Laufzeit

Um die Deaktivierung einer MenuItem Laufzeit zu aktivieren, binden Sie ihre Command Eigenschaft an eine ICommand Implementierung, und stellen Sie sicher, dass ein canExecute Delegat die ICommand entsprechende Option aktiviert und deaktiviert.

Wichtig

Binden Sie die Eigenschaft nicht an eine andere Eigenschaft, wenn Sie die IsEnabledCommand Eigenschaft zum Aktivieren oder Deaktivieren der MenuItemEigenschaft verwenden.

Das folgende Beispiel zeigt eine MenuItem Eigenschaft, deren Command Eigenschaft an einen ICommand Benannten MyCommandgebunden ist:

<MenuItem Text="My menu item"
          Command="{Binding MyCommand}" />

Die ICommand Implementierung erfordert einen canExecute Delegaten, der den Wert einer bool Eigenschaft zurückgibt, um folgendes MenuItemzu aktivieren und zu deaktivieren:

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);
    }
}

In diesem Beispiel ist die MenuItem Einstellung deaktiviert, bis die IsMenuItemEnabled Eigenschaft festgelegt ist. In diesem Fall wird die Command.ChangeCanExecute Methode aufgerufen, die bewirkt, dass der canExecute Delegat MyCommand erneut ausgewertet wird.

Plattformübergreifendes Kontextmenüverhalten

Auf Kontextmenüs wird zugegriffen und auf jeder Plattform anders angezeigt.

Unter Android wird das Kontextmenü durch langes Drücken eines Listenelements aktiviert. Das Kontextmenü ersetzt den Titel und die Navigationsleiste, und die MenuItem-Optionen werden als horizontale Schaltflächen dargestellt.

Unter iOS wird das Kontextmenü durch Wischen in einem Listenelement aktiviert. Das Kontextmenü wird im Listenelement angezeigt, und MenuItems werden als horizontale Schaltflächen dargestellt.

Unter UWP wird das Kontextmenü aktiviert, indem mit der rechten Maustaste auf ein Listenelement geklickt wird. Das Kontextmenü wird in der Nähe des Cursors als vertikale Liste angezeigt.