共用方式為


Xamarin.Forms MenuItem

類別 Xamarin.FormsMenuItem 會定義功能表的功能表項,例如 ListView 專案操作功能表和Shell應用程式飛出視窗選單。

下列螢幕快照顯示 MenuItem iOS 和 Android 上操作選單中的物件 ListView

“iOS 和 Android 上的 MenuItems”

類別 MenuItem 會定義下列屬性:

  • CommandICommand是,允許將用戶動作,例如手指點選或按下,系結至 ViewModel 上定義的命令。
  • CommandParameterobject是 ,指定應該傳遞至 的參數Command
  • IconImageSourceImageSource是定義顯示圖示的值。
  • IsDestructive 是值 bool ,指出是否會 MenuItem 從清單中移除其相關聯的UI元素。
  • IsEnabled 是值 bool ,指出這個物件是否回應用戶輸入。
  • Text 是指定 string 顯示文字的 值。

這些屬性是由 BindableProperty 物件所支援, MenuItem 因此實例可以是數據系結的目標。

建立 MenuItem

MenuItem 物件可以在物件項目的內容功能表中 ListView 使用。 最常見的模式是在 實例內ViewCell建立MenuItem物件,該實例會做為 DataTemplateListViewItemTemplate物件。 ListView當物件填入時,它會使用 DataTemplate來建立每個專案,以MenuItem在項目啟動操作功能表時公開選項。

下列範例顯示 MenuItem 物件內容 ListView 內的具現化:

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

MenuItem也可以在程式代碼中建立 :

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

使用事件定義 MenuItem 行為

MenuItem 類別會公開 Clicked 事件。 事件處理程式可以附加至此事件,以回應 XAML 中的實例點選或按兩下 MenuItem

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

事件處理程式也可以在程式代碼中附加:

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

先前的範例參考 OnItemClicked 事件處理程式。 下列程式代碼顯示範例實作:

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
}

使用MVVM定義 MenuItem 行為

類別 MenuItem 支援透過 BindableProperty 物件和 ICommand 介面的Model-View-ViewModel(MVVM) 模式。 下列 XAML 顯示 MenuItem 系結至 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>

在上一個範例中,兩個MenuItem物件會使用其 和 CommandParameter 屬性來定義,這些Command物件會系結至 viewmodel 上的命令。 viewmodel 包含 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}";
    });
}

範例應用程式包含用來 DataService 取得專案清單的類別,以填入 ListView 物件。 ViewModel 會具現化,其中包含 類別 DataService 中的專案,並在程式代碼後置中設定為 BindingContext

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

警告

MenuItem 物件只會在 Android 上顯示圖示。 在其他平臺上,只會顯示 屬性所 Text 指定的文字。

圖示是使用 IconImageSource 屬性來指定。 如果指定圖示,則不會顯示 屬性所 Text 指定的文字。 下列螢幕快照顯示 MenuItem Android 上具有圖示的 :

[Android 上的 MenuItem 圖示螢幕快照]

如需在 中使用 Xamarin.Forms影像的詳細資訊,請參閱 中的 Xamarin.Forms影像。

在運行時間啟用或停用 MenuItem

若要在執行時間開啟 停用 MenuItem ,請將其 Command 屬性系結至 ICommand 實作,並確定 canExecute 委派會適當地啟用和停用 ICommand

重要

使用 屬性來啟用或停用 MenuItemCommand,請勿將 IsEnabled 屬性系結至另一個屬性。

下列範例顯示 MenuItem ,其 Command 屬性系結至 ICommand 具名 MyCommand的 :

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

實作 ICommand 需要傳 canExecute 回 屬性值的 bool 委派,才能啟用和停用 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);
    }
}

在此範例中, MenuItem 會停用 ,直到 IsMenuItemEnabled 設定 屬性為止。 發生此情況時, Command.ChangeCanExecute 會呼叫 方法,這會導致 canExecute 重新評估的委派 MyCommand

跨平臺操作功能表行為

操作功能表會在每個平臺上以不同的方式存取和顯示。

在Android上,操作功能表會由清單專案上的長按來啟動。 操作選單會取代標題和導覽列區域,選項 MenuItem 會顯示為水平按鈕。

[Android 上操作功能表的螢幕快照]

在iOS上,操作功能表會藉由在清單專案上撥動來啟動。 操作功能表會顯示在清單專案上,並 MenuItems 顯示為水平按鈕。

「iOS 上操作功能表的螢幕快照」

在UWP上,以滑鼠右鍵按下清單專案,即可啟動操作功能表。 操作功能表會在游標附近顯示為垂直清單。

[UWP 上操作功能表的螢幕快照]