Skip to content

Popup context menu

Håvard Moås edited this page Jan 21, 2023 · 12 revisions

ContextMenuButton / ContextMenuController

namespace DIPS.Xamarin.UI.Controls.ContextMenu

To help people make choices that affect the content or the surrounding views, a context menu can be opened by tapping a button / area within a page. This component lets you place a desired view in your page with an attached context menu. The implementation is inspired from these online sources:

Samples can be found here


To start off, you will need to either add a ContextMenuButton or a ContextMenuControl to your page. A ContextMenuButton gives you a Xamarin.Forms Button that will open a context menu when people click it. A ContextMenuController gives you a way to customise the view of the content of the button by setting the ContextMenuController.TheContent property. To add a context menu you to either of these two controls you will have to set the ItemSource property with ContextMenuItem.

👉 To get started, make sure you have followed the getting started steps

👉 ItemSource is a bindable property which makes this easy to use using the MVVM pattern.

👉 ItemClickedCommand / ItemClicked event can be used to get a callback with the ContextMenuItem that tapped by people.

👉 The way you can organise the context menu is limited, but we will add more possibilities later as our requirements changes.

Context menu item as an action

Present items in the menu as actions that people can tap. You can achieve this behaviour by simply adding a ContextMenuItem and setting the ContextMenuItem .Title.

<!-- Single item -->
<contextMenu:ContextMenuControl VerticalOptions="Start"
                                ItemClickedCommand="{Binding ItemClickedCommand}">
    <contextMenu:ContextMenuControl.ItemsSource>
        <contextMenu:ContextMenuItem Title="Item" />
    </contextMenu:ContextMenuControl.ItemsSource>
    <Button Text="Single item"
            BackgroundColor="White" />
</contextMenu:ContextMenuControl>

image

Context menu item in groups

Display menu items inside of a group / submenu to group up items that are similar to each other or to limit the number of items on the root of the context menu.

<!-- Grouped items -->
<contextMenu:ContextMenuControl VerticalOptions="Start"
                                ItemClickedCommand="{Binding ItemClickedCommand}">
    <contextMenu:ContextMenuControl.ItemsSource>
        <contextMenu:ContextMenuGroup Title="Group 1">
            <contextMenu:ContextMenuItem Title="Item 1" />
            <contextMenu:ContextMenuItem Title="Item 2" />
        </contextMenu:ContextMenuGroup>
        <contextMenu:ContextMenuGroup Title="Group 2">
            <contextMenu:ContextMenuItem Title="Item 1" />
            <contextMenu:ContextMenuItem Title="Item 2" />
        </contextMenu:ContextMenuGroup>
    </contextMenu:ContextMenuControl.ItemsSource>
    <Button Text="Grouped items"
            BackgroundColor="White" />
</contextMenu:ContextMenuControl>

image

When people open a group it looks like this:

image

Context menu item as an checkable action

Present items as menu items that people can click to toggle something on / off.

"Single" check-mode

Every item is individual and checking them do not un-check the other items surrounding items.

<!--Checkable items (single)-->
<contextMenu:ContextMenuControl VerticalOptions="Start"
                                ItemClickedCommand="{Binding ItemClickedCommand}">
    <contextMenu:ContextMenuControl.ItemsSource>
        <contextMenu:ContextMenuGroup IsCheckable="True">
            <contextMenu:ContextMenuItem Title="Item 1" />
            <contextMenu:ContextMenuItem Title="Item 2" />
        </contextMenu:ContextMenuGroup>
    </contextMenu:ContextMenuControl.ItemsSource>
    <Button Text="Checkable items (single)"
            BackgroundColor="White" />
</contextMenu:ContextMenuControl>

image

"All" check-mode

Items that are grouped together and checked will un-check the surrounding items, like a radio button.

<!--Checkable items (all)-->
<contextMenu:ContextMenuControl VerticalOptions="Start"
                                ItemClickedCommand="{Binding ItemClickedCommand}">
    <contextMenu:ContextMenuControl.ItemsSource>
        <contextMenu:ContextMenuItem Title="Item 1"
                                     IsCheckable="True" />
        <contextMenu:ContextMenuItem Title="Test 2"
                                     IsCheckable="True" />
    </contextMenu:ContextMenuControl.ItemsSource>
    <Button Text="Checkable items (all)"
            BackgroundColor="White" />
</contextMenu:ContextMenuControl>

image

Icons

You do have the ability to add icons to your context menu items so people can more easily scan through and recognise the options they have. This requires you to follow the Xamarin approach by adding an image in your Android and iOS resources. Once that is done you can refer it like you would with any other Xamarin component that takes a image source:

<!-- Single item -->
<contextMenu:ContextMenuControl VerticalOptions="Start"
                                ItemClickedCommand="{Binding ItemClickedCommand}">
    <contextMenu:ContextMenuControl.ItemsSource>
        <contextMenu:ContextMenuItem Title="Edit" Icon="edit" />
    </contextMenu:ContextMenuControl.ItemsSource>
    <Button Text="Single item"
            BackgroundColor="White" />
</contextMenu:ContextMenuControl>

Using built in icons

You can override the icon by specifying a android resource name or a iOS system symbol name:

Android:

<contextMenu:ContextMenuControl VerticalOptions="Start"
                                ItemClickedCommand="{Binding ItemClickedCommand}">
    <contextMenu:ContextMenuControl.ItemsSource>
        <contextMenu:ContextMenuItem Title="Edit" Icon="edit">
            <contextMenu:ContextMenuItem.AndroidOptions>
                <contextMenu:AndroidContextMenuItemOptions IconResourceName="material_ic_edit_black_24dp"/>
            </contextMenu:ContextMenuItem.AndroidOptions>
        </contextMenu:ContextMenuItem>
    </contextMenu:ContextMenuControl.ItemsSource>
    <Button Text="Single item"
            BackgroundColor="White" />
</contextMenu:ContextMenuControl>

iOS:

<!-- Single item -->
<contextMenu:ContextMenuControl VerticalOptions="Start"
                                ItemClickedCommand="{Binding ItemClickedCommand}">
    <contextMenu:ContextMenuControl.ItemsSource>
        <contextMenu:ContextMenuItem Title="Edit" Icon="edit">
            <contextMenu:ContextMenuItem.iOSOptions>
                <contextMenu:iOSContextMenuItemOptions SystemIconName="pencil"/>
            </contextMenu:ContextMenuItem.iOSOptions>
        </contextMenu:ContextMenuItem>
    </contextMenu:ContextMenuControl.ItemsSource>
    <Button Text="Single item"
            BackgroundColor="White" />
</contextMenu:ContextMenuControl>

On Android it would look exactly the same as material_ic_edit_black_24dp is the exact same icon as the one that was downloaded to edit.png, but on iOS this will replace the icon with SF Symbol pencil:

Properties

Here is a list of the properties available when using context menu and context menu items: