Xamarin.Forms Menuitem

Beispiel herunterladen Das Beispiel herunterladen

Die Xamarin.FormsMenuItem -Klasse definiert Menüelemente für Menüs, z ListView . B. Elementkontextmenüs und Flyoutmenüs für Shellanwendungen.

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

Die MenuItem-Klasse definiert die folgenden Eigenschaften:

  • Command ist eine ICommand , die das Binden von Benutzeraktionen, z. B. Fingerklicks oder Klicks, an Befehle ermöglicht, die in einem ViewModel definiert sind.
  • CommandParameter ist ein object , der den Parameter angibt, der Commandan den übergeben werden soll.
  • IconImageSource ist ein ImageSource Wert, der das Anzeigesymbol definiert.
  • IsDestructive ist ein bool Wert, der angibt, ob das MenuItem zugehörige 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 unterstützt, sodass die MenuItem instance das Ziel von Datenbindungen sein kann.

Erstellen eines MenuItem-Objekts

MenuItem -Objekte können innerhalb eines Kontextmenüs für die Elemente eines ListView Objekts verwendet werden. Das gebräuchlichste Muster ist das Erstellen MenuItem von Objekten innerhalb einer ViewCell instance, die als Objekt für die DataTemplateListViews ItemTemplateverwendet wird. Wenn das ListView Objekt aufgefüllt wird, wird jedes Element mithilfe von DataTemplateerstellt, wobei die MenuItem Auswahlmöglichkeiten verfügbar sind, 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 Klicken auf die MenuItem instance in XAML zu reagieren:

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

Ein Ereignishandler kann auch im Code angefü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-Muster (MVVM) über BindableProperty Objekte und die ICommand -Schnittstelle. Der folgende XAML-Code zeigt MenuItem Instanzen, die an Befehle gebunden sind, die in einem ViewModel 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 definiert, wobei deren Command Eigenschaften und CommandParameter an Befehle im ViewModel gebunden sind. Das Viewmodel 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, die zum Abrufen einer Liste von Elementen zum Auffüllen der ListView Objekte verwendet wird. Ein Viewmodel wird mit Elementen aus der DataService -Klasse instanziiert und im CodeBehind als festgelegt BindingContext :

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

Warnung

MenuItem -Objekte zeigen nur Symbole unter Android an. Auf anderen Plattformen wird nur der von der Text -Eigenschaft angegebene Text angezeigt.

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

Weitere Informationen zur Verwendung von Bildern in Xamarin.Formsfinden Sie unter Images in Xamarin.Forms.

Aktivieren oder Deaktivieren eines MenuItem zur Laufzeit

Um das Deaktivieren eines MenuItem zur Laufzeit zu aktivieren, binden Sie die - Command Eigenschaft an eine ICommand -Implementierung, und stellen Sie sicher, dass ein canExecute Delegat die ICommand aktiviert und deaktiviert.

Wichtig

Binden Sie die IsEnabled -Eigenschaft nicht an eine andere Eigenschaft, wenn Sie die Command -Eigenschaft zum Aktivieren oder Deaktivieren von MenuItemverwenden.

Das folgende Beispiel zeigt eine MenuItem , deren Command Eigenschaft an einen ICommand namens MyCommandgebunden wird:

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

Die ICommand Implementierung erfordert einen canExecute Delegaten, der den Wert einer bool Eigenschaft zurückgibt, um die 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 wird deaktiviert MenuItem , bis die IsMenuItemEnabled -Eigenschaft festgelegt ist. In diesem Fall wird die Command.ChangeCanExecute -Methode aufgerufen, wodurch der canExecute Delegat für MyCommand neu ausgewertet wird.

Plattformübergreifendes Kontextmenüverhalten

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

Unter Android wird das Kontextmenü durch langes Drücken auf ein Listenelement aktiviert. Das Kontextmenü ersetzt den Titel- und Navigationsleistenbereich, und MenuItem Optionen werden als horizontale Schaltflächen angezeigt.

Screenshot des Kontextmenüs unter Android Screenshot

Unter iOS wird das Kontextmenü durch Wischen auf ein Listenelement aktiviert. Das Kontextmenü wird im Listenelement angezeigt und MenuItems als horizontale Schaltflächen angezeigt.

Screenshot des Kontextmenüs unter iOS Screenshot

Auf UWP wird das Kontextmenü durch Klicken mit der rechten Maustaste auf ein Listenelement aktiviert. Das Kontextmenü wird in der Nähe des Cursors als vertikale Liste angezeigt.

Screenshot des Kontextmenüs auf UWP Screenshot