Cross platform tray bar applications with Xamarin.Forms

Before we start, why are we doing this?

  • All code can be written in C# or F#. Whether it is shared code or something platform specific.
  • The UI can get written in either C# or XAML. While Xamarin.Forms does not use the same XAML dialect known from WPF or UWP, most code can get ported quite easily which would allow to port an existing Windows only tray application to macOS.
  • Xamarin provides full access to the platform SDKs which allows for scenarios where other frameworks like Electron require extensions written in the native languages. This can be specially useful when writing applications that interact with the system.


  • Visual Studio 2019 with the “.NET desktop development” and “Mobile development with .NET” workloads
  • An icon in the .ico format and resolution 32*32 for Windows and 18*18 for macOS.

Anatomy of a Xamarin.Forms tray application

  • Setting up the project with the shared Xamarin.Forms content
  • Building the macOS tray icon (or menu bar item to be more precisely)
  • Building the Windows tray icon

Setting up the project and shared content

  • .NETStandard 2.0: A shared project which will host all shared ui and logic.
    NuGet: Xamarin.Forms (4.3.*+)
  • Xamarin.macOS: The MacOS project which will contain the setup logic for macOS and platform specific logic.
    References: The shared project, NuGet: Xamarin.Forms (4.3.*+)
  • WPF: The Windows project which will contain the setup logic for macOS and platform specific logic. You cant use .NET Core here currently since Xamarin.Forms is not compatible currently, but a PR is already on its way!
    References: The shared project, NuGet: Xamarin.Forms (4.3.*+), Xamarin.Forms.Platform.WPF (4.3.*+)
Shared startup logic

Windows platform

  • Add an icon in the .ico format and 32*32 resolution to the application Resources (Properties/Resources.resx).
  • Add a reference to the PresentationFramework. It contains the NotifyIcon class we will utilize to create the tray icon.
  • Remove the MainWindow.xaml and .xaml.cs and remove StartupUri=”MainWindow.xaml” from the App.xaml file.
The application is positioned in the lower-right corner
  • When the tray icon is left clicked (right click will open the context menu by default).
  • When the close button of the window is clicked: We intercept the close method to avoid exiting the application and toggle the window instead.
  • When clicked outside the window (see below).

macOS platform

  • Since we don't want to show the initial window from the storyboard, uncheck the Is Initial Controller from the start window.
  • A tray application normally does not show up in the dock. To get this behavior, we have to modify the Info.plist and set the application as agent.
  • Add the icon in the .ico format with a 18*18 resolution to the Resources folder with the build action “BundleResource”.




Software developer from germany.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How To Upgrade The Kubernetes Version Of Your AKS Default Node Pool With Terraform

How Nigeria’s Fintech Ecosystem Went Fully Remote

Build Your First Kubernetes Service with ReplicaSet

Incident Management. Not everything is critical

Velociraptor 0.6.1 Release

I Stayed on Trump’s Campaign Email List and what I found will Shock You

Ember + Azure 🔥🔥

REST vs. GraphQL: A Critical Review

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Konrad Müller

Konrad Müller

Software developer from germany.

More from Medium

Drag & Drop without Blazor

Visual Studio 2022 Browser Edge with Your Profile

I started programming on .NET

Use ASP.NET Core hosted services to run a background task