Creating Custom Controls
Custom controls in the Uno Platform enable developers to create reusable UI components that work seamlessly across iOS, Android, WebAssembly, Linux, macOS, and Windows. Uno Platform supports the same approach as WinUI/WinAppSDK and UWP, with a few specific considerations for cross-platform compatibility.
Note
For a more detailed explanation of creating custom controls, including dependency properties and control templates, refer to the official WinUI documentation: Build XAML controls with C# | Microsoft Learn.
If you're not familiar with concepts such as dependency properties, control templates, and visual states, it might be useful to explore those topics before diving into custom controls. These are fundamental concepts for creating reusable, maintainable UI components:
- Dependency Properties: These are properties that are tracked by a dedicated property system to allow binding, styling, animations, and tracking value changes to work. For more information, see Dependency properties overview | Microsoft Learn.
- Control Templates: These define the visual structure and behavior of a control, allowing you to separate design from logic. Check out Control templates | Microsoft Learn for further reading.
- Visual States and Visual State Manager: Visual states help you define different appearances for a control depending on its state (e.g., pressed, focused). Learn more here: VisualStateManager Class | Microsoft Learn.
Ensuring Cross-Platform Compatibility
To ensure your custom control functions properly across all platforms, make sure that the Themes/generic.xaml
file is included in your Uno project and correctly referenced for each platform. On non-Windows platforms, this file might not be automatically included, and you may need to adjust your project settings or add custom build steps to ensure it is properly referenced.
In WinUI apps, Themes/generic.xaml
is the standard location for default styles. It should be supported across all platforms and automatically referenced when Uno searches for implicit or default styles in any TemplatedControl
defined in generic.xaml
. Additionally, it's common to use a MergedDictionary
to reference resources from other directories within generic.xaml
. Currently, styles defined in Themes/generic.xaml
are not found automatically across platforms in Uno.
To resolve this, you can define styles in App.xaml
and use a MergedDictionary
to pull in the resources, as shown in the following example:
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<ResourceDictionary Source="ms-appx:///Themes/Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Handling Platform-Specific Adjustments
In some cases, custom control behavior might need adjustments based on the platform. Uno Platform provides the flexibility to handle platform-specific differences using conditional code in both XAML and C#. For XAML, platform-specific XML namespaces can be utilized, while #if
preprocessor directives are available in C#. For more details, refer to the documentation on Platform-Specific C# and XAML Conditions.