Windows Platform-Specifics

Platform-specifics allow you to consume functionality that's only available on a specific platform, without implementing custom renderers or effects. This article demonstrates how to consume the Windows platform-specifics that are built into Xamarin.Forms.

On the Universal Windows Platform (UWP), Xamarin.Forms contains the following platform-specifics:

Changing the Page Toolbar Placement

This platform-specific is used to change the placement of a toolbar on a Page, and is consumed in XAML by setting the Page.ToolbarPlacement attached property to a value of the ToolbarPlacement enumeration:

<TabbedPage ...
            xmlns:windows="clr-namespace:Xamarin.Forms.PlatformConfiguration.WindowsSpecific;assembly=Xamarin.Forms.Core"
            windows:Page.ToolbarPlacement="Bottom">
  ...
</TabbedPage>

Alternatively, it can be consumed from C# using the fluent API:

using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.WindowsSpecific;
...

page.On<Windows>().SetToolbarPlacement(ToolbarPlacement.Bottom);

The Page.On<Windows> method specifies that this platform-specific will only run on Windows. The Page.SetToolbarPlacement method, in the Xamarin.Forms.PlatformConfiguration.WindowsSpecific namespace, is used to set the toolbar placement, with the ToolbarPlacement enumeration providing three values: Default, Top, and Bottom.

The result is that the specified toolbar placement is applied to the Page instance:

Collapsing a MasterDetailPage Navigation Bar

This platform-specific is used to collapse the navigation bar on a MasterDetailPage, and is consumed in XAML by setting the MasterDetailPage.CollapseStyle and MasterDetailPage.CollapsedPaneWidth attached properties:

<MasterDetailPage ...
                  xmlns:windows="clr-namespace:Xamarin.Forms.PlatformConfiguration.WindowsSpecific;assembly=Xamarin.Forms.Core"
                  windows:MasterDetailPage.CollapseStyle="Partial"
                  windows:MasterDetailPage.CollapsedPaneWidth="48">
  ...
</MasterDetailPage>

Alternatively, it can be consumed from C# using the fluent API:

using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.WindowsSpecific;
...

page.On<Windows>().SetCollapseStyle(CollapseStyle.Partial).CollapsedPaneWidth(148);

The MasterDetailPage.On<Windows> method specifies that this platform-specific will only run on Windows. The Page.SetCollapseStyle method, in the Xamarin.Forms.PlatformConfiguration.WindowsSpecific namespace, is used to specify the collapse style, with the CollapseStyle enumeration providing two values: Full and Partial. The MasterDetailPage.CollapsedPaneWidth method is used to specify the width of a partially collapsed navigation bar.

The result is that a specified CollapseStyle is applied to the MasterDetailPage instance, with the width also being specified:

Displaying JavaScript Alerts

This platform-specific enables a WebView to display JavaScript alerts in a UWP message dialog. It's consumed in XAML by setting the WebView.IsJavaScriptAlertEnabled attached property to a boolean value:

<ContentPage ...
             xmlns:windows="clr-namespace:Xamarin.Forms.PlatformConfiguration.WindowsSpecific;assembly=Xamarin.Forms.Core">
    <StackLayout>
        <WebView ... windows:WebView.IsJavaScriptAlertEnabled="true" />
        ...
    </StackLayout>
</ContentPage>

Alternatively, it can be consumed from C# using the fluent API:

using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.WindowsSpecific;
...

var webView = new Xamarin.Forms.WebView
{
  Source = new HtmlWebViewSource
  {
    Html = @"<html><body><button onclick=""window.alert('Hello World from JavaScript');"">Click Me</button></body></html>"
  }
};
webView.On<Windows>().SetIsJavaScriptAlertEnabled(true);

The WebView.On<Windows> method specifies that this platform-specific will only run on the Universal Windows Platform. The WebView.SetIsJavaScriptAlertEnabled method, in the Xamarin.Forms.PlatformConfiguration.WindowsSpecific namespace, is used to control whether JavaScript alerts are enabled. In addition, the WebView.SetIsJavaScriptAlertEnabled method can be used to toggle JavaScript alerts by calling the IsJavaScriptAlertEnabled method to return whether they are enabled:

_webView.On<Windows>().SetIsJavaScriptAlertEnabled(!_webView.On<Windows>().IsJavaScriptAlertEnabled());

The result is that JavaScript alerts can be displayed in a UWP message dialog:

WebView JavaScript alert platform-specific

Enabling SearchBar Spell Check

This platform-specific enables a SearchBar to interact with the spell check engine. It's consumed in XAML by setting the SearchBar.IsSpellCheckEnabled attached property to a boolean value:

<ContentPage ...
             xmlns:windows="clr-namespace:Xamarin.Forms.PlatformConfiguration.WindowsSpecific;assembly=Xamarin.Forms.Core">
    <StackLayout>
        <SearchBar ... windows:SearchBar.IsSpellCheckEnabled="true" />
        ...
    </StackLayout>
</ContentPage>

Alternatively, it can be consumed from C# using the fluent API:

using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.WindowsSpecific;
...

searchBar.On<Windows>().SetIsSpellCheckEnabled(true);

The SearchBar.On<Windows> method specifies that this platform-specific will only run on the Universal Windows Platform. The SearchBar.SetIsSpellCheckEnabled method, in the Xamarin.Forms.PlatformConfiguration.WindowsSpecific namespace, turns the spell checker on and off. In addition, the SearchBar.SetIsSpellCheckEnabled method can be used to toggle the spell checker by calling the SearchBar.GetIsSpellCheckEnabled method to return whether the spell checker is enabled:

searchBar.On<Windows>().SetIsSpellCheckEnabled(!searchBar.On<Windows>().GetIsSpellCheckEnabled());

The result is that text entered into the SearchBar can be spell checked, with incorrect spellings being indicated to the user:

SearchBar spell check platform-specific

Note

The SearchBar class in the Xamarin.Forms.PlatformConfiguration.WindowsSpecific namespace also has EnableSpellCheck and DisableSpellCheck methods that can be used to enable and disable the spell checker on the SearchBar, respectively.

Detecting Reading Order from Content

This platform-specific enables the reading order (left-to-right or right-to-left) of bidirectional text in Entry, Editor, and Label instances to be detected dynamically. It's consumed in XAML by setting the InputView.DetectReadingOrderFromContent (for Entry and Editor instances) or Label.DetectReadingOrderFromContent attached property to a boolean value:

<ContentPage ...
             xmlns:windows="clr-namespace:Xamarin.Forms.PlatformConfiguration.WindowsSpecific;assembly=Xamarin.Forms.Core">
    <StackLayout>
        <Editor ... windows:InputView.DetectReadingOrderFromContent="true" />
        ...
    </StackLayout>
</ContentPage>

Alternatively, it can be consumed from C# using the fluent API:

using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.WindowsSpecific;
...

editor.On<Windows>().SetDetectReadingOrderFromContent(true);

The Editor.On<Windows> method specifies that this platform-specific will only run on the Universal Windows Platform. The InputView.SetDetectReadingOrderFromContent method, in the Xamarin.Forms.PlatformConfiguration.WindowsSpecific namespace, is used to control whether the reading order is detected from the content in the InputView. In addition, the InputView.SetDetectReadingOrderFromContent method can be used to toggle whether the reading order is detected from the content by calling the InputView.GetDetectReadingOrderFromContent method to return the current value:

editor.On<Windows>().SetDetectReadingOrderFromContent(!editor.On<Windows>().GetDetectReadingOrderFromContent());

The result is that Entry, Editor, and Label instances can have the reading order of their content detected dynamically:

InputView detecting reading order from content platform-specific

Note

Unlike setting the FlowDirection property, the logic for views that detect the reading order from their text content will not affect the alignment of text within the view. Instead, it adjusts the order in which blocks of bidirectional text are laid out.

Disabling Legacy Color Mode

Some of the Xamarin.Forms views feature a legacy color mode. In this mode, when the IsEnabled property of the view is set to false, the view will override the colors set by the user with the default native colors for the disabled state. For backwards compatibility, this legacy color mode remains the default behavior for supported views.

This platform-specific disables this legacy color mode, so that colors set on a view by the user remain even when the view is disabled. It's consumed in XAML by setting the VisualElement.IsLegacyColorModeEnabled attached property to false:

<ContentPage ...
             xmlns:windows="clr-namespace:Xamarin.Forms.PlatformConfiguration.WindowsSpecific;assembly=Xamarin.Forms.Core">
    <StackLayout>
        ...
        <Editor Text="Enter text here"
                TextColor="Blue"
                BackgroundColor="Bisque"
                windows:VisualElement.IsLegacyColorModeEnabled="False" />
        ...
    </StackLayout>
</ContentPage>

Alternatively, it can be consumed from C# using the fluent API:

using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.WindowsSpecific;
...

_legacyColorModeDisabledEditor.On<Windows>().SetIsLegacyColorModeEnabled(false);

The VisualElement.On<Windows> method specifies that this platform-specific will only run on Windows. The VisualElement.SetIsLegacyColorModeEnabled method, in the Xamarin.Forms.PlatformConfiguration.WindowsSpecific namespace, is used to control whether the legacy color mode is disabled. In addition, the VisualElement.GetIsLegacyColorModeEnabled method can be used to return whether the legacy color mode is disabled.

The result is that the legacy color mode can be disabled, so that colors set on a view by the user remain even when the view is disabled:

Note

When setting a VisualStateGroup on a view, the legacy color mode is completely ignored. For more information about visual states, see The Xamarin.Forms Visual State Manager.

Enabling Tap Gesture Support in a ListView

On the Universal Windows Platform, by default the Xamarin.Forms ListView uses the native ItemClick event to respond to interaction, rather than the native Tapped event. This provides accessibility functionality so that the Windows Narrator and the keyboard can interact with the ListView. However, it also renders any tap gestures inside the ListView inoperable.

This platform-specific controls whether items in a ListView can respond to tap gestures, and hence whether the native ListView fires the ItemClick or Tapped event. It's consumed in XAML by setting the ListView.SelectionMode attached property to a value of the ListViewSelectionMode enumeration:

<ContentPage ...
             xmlns:windows="clr-namespace:Xamarin.Forms.PlatformConfiguration.WindowsSpecific;assembly=Xamarin.Forms.Core">
    <StackLayout>
        <ListView ... windows:ListView.SelectionMode="Inaccessible">
            ...
        </ListView>
    </StackLayout>
</ContentPage>

Alternatively, it can be consumed from C# using the fluent API:

using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.WindowsSpecific;
...

listView.On<Windows>().SetSelectionMode(ListViewSelectionMode.Inaccessible);

The ListView.On<Windows> method specifies that this platform-specific will only run on the Universal Windows Platform. The ListView.SetSelectionMode method, in the Xamarin.Forms.PlatformConfiguration.WindowsSpecific namespace, is used to control whether items in a ListView can respond to tap gestures, with the ListViewSelectionMode enumeration providing two possible values:

  • Accessible – indicates that the ListView will fire the native ItemClick event to handle interaction, and hence provide accessibility functionality. Therefore, the Windows Narrator and the keyboard can interact with the ListView. However, items in the ListView can't respond to tap gestures. This is the default behavior for ListView instances on the Universal Windows Platform.
  • Inaccessible – indicates that the ListView will fire the native Tapped event to handle interaction. Therefore, items in the ListView can respond to tap gestures. However, there's no accessibility functionality and hence the Windows Narrator and the keyboard can't interact with the ListView.

Note

The Accessible and Inaccessible selection modes are mutually exclusive, and you will need to choose between an accessible ListView or a ListView that can respond to tap gestures.

In addition, the GetSelectionMode method can be used to return the current ListViewSelectionMode.

The result is that a specified ListViewSelectionMode is applied to the ListView, which controls whether items in the ListView can respond to tap gestures, and hence whether the native ListView fires the ItemClick or Tapped event.

Enabling Icons on a TabbedPage

This platform-specific enables page icons to be displayed on a TabbedPage toolbar, and provides the ability to optionally specify the icon size. It's consumed in XAML by setting the TabbedPage.HeaderIconsEnabled attached property to true, and by optionally setting the TabbedPage.HeaderIconsSize attached property to a Size value:

<TabbedPage ...
            xmlns:windows="clr-namespace:Xamarin.Forms.PlatformConfiguration.WindowsSpecific;assembly=Xamarin.Forms.Core"
            windows:TabbedPage.HeaderIconsEnabled="true">
    <windows:TabbedPage.HeaderIconsSize>
        <Size>
            <x:Arguments>
                <x:Double>24</x:Double>
                <x:Double>24</x:Double>
            </x:Arguments>
        </Size>
    </windows:TabbedPage.HeaderIconsSize>
    <ContentPage Title="Todo" Icon="todo.png">
        ...
    </ContentPage>
    <ContentPage Title="Reminders" Icon="reminders.png">
        ...
    </ContentPage>
    <ContentPage Title="Contacts" Icon="contacts.png">
        ...
    </ContentPage>
</TabbedPage>

Alternatively, it can be consumed from C# using the fluent API:

using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.WindowsSpecific;
...

public class WindowsTabbedPageIconsCS : Xamarin.Forms.TabbedPage
{
  public WindowsTabbedPageIconsCS()
	{
    On<Windows>().SetHeaderIconsEnabled(true);
    On<Windows>().SetHeaderIconsSize(new Size(24, 24));

    Children.Add(new ContentPage { Title = "Todo", Icon = "todo.png" });
    Children.Add(new ContentPage { Title = "Reminders", Icon = "reminders.png" });
    Children.Add(new ContentPage { Title = "Contacts", Icon = "contacts.png" });
  }
}

The TabbedPage.On<Windows> method specifies that this platform-specific will only run on the Universal Windows Platform. The TabbedPage.SetHeaderIconsEnabled method, in the Xamarin.Forms.PlatformConfiguration.WindowsSpecific namespace, is used to turn header icons on or off. The TabbedPage.SetHeaderIconsSize method optionally specifies the header icon size with a Size value.

In addition, the TabbedPage class in the Xamarin.Forms.PlatformConfiguration.WindowsSpecific namespace also has a EnableHeaderIcons method that enables header icons, a DisableHeaderIcons method that disables header icons, and a IsHeaderIconsEnabled method that returns a boolean value that indicates whether header icons are enabled.

The result is that page icons can be displayed on a TabbedPage toolbar, with the icon size being optionally set to a desired size:

TabbedPage icons enabled platform-specific

Setting VisualElement Access Keys

Access keys are keyboard shortcuts that improve the usability and accessibility of apps on the Universal Windows Platform by providing an intuitive way for users to quickly navigate and interact with the app's visible UI through a keyboard instead of via touch or a mouse. They are combinations of the Alt key and one or more alphanumeric keys, typically pressed sequentially. Keyboard shortcuts are automatically supported for access keys that use a single alphanumeric character.

Access key tips are floating badges displayed next to controls that include access keys. Each access key tip contains the alphanumeric keys that activate the associated control. When a user presses the Alt key, the access key tips are displayed.

This platform-specific is used to specify an access key for a VisualElement. It's consumed in XAML by setting the VisualElement.AccessKey attached property to an alphanumeric value, and by optionally setting the VisualElement.AccessKeyPlacement attached property to a value of the AccessKeyPlacement enumeration, the VisualElement.AccessKeyHorizontalOffset attached property to a double, and the VisualElement.AccessKeyVerticalOffset attached property to a double:

<TabbedPage ...
            xmlns:windows="clr-namespace:Xamarin.Forms.PlatformConfiguration.WindowsSpecific;assembly=Xamarin.Forms.Core">
    <ContentPage Title="Page 1"
                 windows:VisualElement.AccessKey="1">
        <StackLayout Margin="20">
            ...
            <Switch windows:VisualElement.AccessKey="A" />
            <Entry Placeholder="Enter text here"
                   windows:VisualElement.AccessKey="B" />
            ...
            <Button Text="Access key F, placement top with offsets"
                    Margin="20"
                    Clicked="OnButtonClicked"
                    windows:VisualElement.AccessKey="F"
                    windows:VisualElement.AccessKeyPlacement="Top"
                    windows:VisualElement.AccessKeyHorizontalOffset="20"
                    windows:VisualElement.AccessKeyVerticalOffset="20" />
            ...
        </StackLayout>
    </ContentPage>
    ...
</TabbedPage>

Alternatively, it can be consumed from C# using the fluent API:

using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.WindowsSpecific;
...

var page = new ContentPage { Title = "Page 1" };
page.On<Windows>().SetAccessKey("1");

var switchView = new Switch();
switchView.On<Windows>().SetAccessKey("A");
var entry = new Entry { Placeholder = "Enter text here" };
entry.On<Windows>().SetAccessKey("B");
...

var button4 = new Button { Text = "Access key F, placement top with offsets", Margin = new Thickness(20) };
button4.Clicked += OnButtonClicked;
button4.On<Windows>()
    .SetAccessKey("F")
    .SetAccessKeyPlacement(AccessKeyPlacement.Top)
    .SetAccessKeyHorizontalOffset(20)
    .SetAccessKeyVerticalOffset(20);
...

The VisualElement.On<Windows> method specifies that this platform-specific will only run on the Universal Windows Platform. The VisualElement.SetAccessKey method, in the Xamarin.Forms.PlatformConfiguration.WindowsSpecific namespace, is used to set the access key value for the VisualElement. The VisualElement.SetAccessKeyPlacement method, optionally specifies the position to use for displaying the access key tip, with the AccessKeyPlacement enumeration providing the following possible values:

  • Auto – indicates that the access key tip placement will be determined by the operating system.
  • Top – indicates that the access key tip will appear above the top edge of the VisualElement.
  • Bottom – indicates that the access key tip will appear below the lower edge of the VisualElement.
  • Right – indicates that the access key tip will appear to the right of the right edge of the VisualElement.
  • Left – indicates that the access key tip will appear to the left of the left edge of the VisualElement.
  • Center – indicates that the access key tip will appear overlaid on the center of the VisualElement.

Note

Typically, the Auto key tip placement is sufficient, which includes support for adaptive user interfaces.

The VisualElement.SetAccessKeyHorizontalOffset and VisualElement.SetAccessKeyVerticalOffset methods can be used for more granular control of the access key tip location. The argument to the SetAccessKeyHorizontalOffset method indicates how far to move the access key tip left or right, and the argument to the SetAccessKeyVerticalOffset method indicates how far to move the access key tip up or down.

Note

Access key tip offsets can't be set when the access key placement is set Auto.

In addition, the GetAccessKey, GetAccessKeyPlacement, GetAccessKeyHorizontalOffset, and GetAccessKeyVerticalOffset methods can be used to retrieve an access key value and it's location.

The result is that access key tips can be displayed next to any VisualElement instances that define access keys, by pressing the Alt key:

VisualElement access keys platform-specific

When a user activates an access key, by pressing the Alt key followed by the access key, the default action for the VisualElement will be executed. For example, when a user activates the access key on a Switch, the Switch is toggled. When a user activates the access key on an Entry, the Entry gains focus. When a user activates the access key on a Button, the event handler for the Clicked event is executed.

For more information about access keys, see Access keys.

Summary

This article demonstrated how to consume the Windows platform-specifics that are built into Xamarin.Forms. Platform-specifics allow you to consume functionality that's only available on a specific platform, without implementing custom renderers or effects.