How to Create Control Libraries
Uno Platform, like WinUI/WinAppSDK and UWP, supports Control Libraries. Control Libraries are a way to reuse UI components across multiple projects, either inside the solution or by using NuGet to distribute to other projects.
Creating such a library will make UI Controls compatible with all Uno Platform targets as well as WinUI or UWP.
Note
Control libraries are different from "normal" libraries as they reference WinAppSDK, Uno.WinUI or Uno.UI. Those libraries are special because they have explicit dependencies on platform-specific features. "Normal" libraries (e.g. Newtonsoft.Json) do not need any special treatment to work with Uno.
You can find the full ControlLibrary sample code for this how-to in our samples repository.
Create a Control Library
- In your solution, create a new Uno Platform Library, name it
XamlControlLibrary
- In your app's existing Class Library project, add a reference to your new library.
Create the Control
Right-click on the project library, then Add, New Item
In the Uno Platform section of C# Items, select Templated Control, name it
MyTemplatedControl
Tip
Choose the template flavor based on your library's flavor: UWP or WinUI. If your project uses the
Uno.UI
NuGet package, it's UWP otherwise Windows App SDK if it usesUno.WinUI
.Right click on the project library again, then Add, New Folder, call it
Themes
(case sentitive)Right click on the
Themes
folder, then Add, New ItemIn the Uno Platform section of C# Items, select Resource Dictionary, name it
Generic.xaml
(case sensitive)In the new created file, paste the following:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlControlLibrary"> <Style TargetType="local:MyTemplatedControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:MyTemplatedControl"> <Grid> <TextBlock Text="My templated control !" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
Use the control
In your application's
MainPage.xaml
, add the following namespacexmlns:myControlLib="using:XamlControlLibrary"
in thePage
elementAdd the following code somewhere in the page:
<myControlLib:MyTemplatedControl />
Moving the control style in a separate resource dictionary
Placing XAML styles in different files can be useful to make the XAML more readable and easier to browse.
Considering the example above:
Right click on the project library again, then Add, New Folder, call it
Styles
(case sentitive)Right click on the
Styles
folder, then Add, New ItemIn the Uno Platform section of C# Items, select Resource Dictionary, name it
MyControlStyles.xaml
(case sensitive)Move the contents of the
Generic.xaml
file intoMyControlStyles.xaml
to be:<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlControlLibrary"> <Style TargetType="local:MyTemplatedControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:MyTemplatedControl"> <Grid> <TextBlock Text="My templated control !" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
Finally, change the
Generic.xaml
file contents to be:<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="ms-appx:///XamlControlLibrary/Styles/MyControlStyles.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary>
Note
The path to
MyControlStyles.xaml
inGeneric.xaml
is containing the current project's assembly name. If you rename your project, you'll also need to change the path in theGeneric.xaml
file.
In a Control Class Library, conditional XAML and platform-specific C# can be used.
Library assets
WinUI 3 and Uno Platform (4.6 and later) Libraries support the inclusion of content assets to be used with StorageFile.GetFileFromApplicationUriAsync
, as well as with the ms-appx:///[libraryname]/[assetname_file_name]
format.
Important
When using library assets with non-WinAppSDK targets, the library name should also be lower cased.
Library assets can be of any type.
Library assets are supported in two configurations:
ProjectReference
, where the library project is included in the solution with the application that uses itPackageReference
, where the library project is being packaged as a NuGet package, and used in a separate solution, from a NuGet feed.
In both cases, for the build system to include the assets files, the following property must be set in the library's .csproj
:
<PropertyGroup>
<GenerateLibraryLayout>true</GenerateLibraryLayout>
</PropertyGroup>
Important
WinAppSDK does not support assets if the application is using the MSIX package mode. To use the unpackaged mode, see this article.