|
| 1 | +--- |
| 2 | +id: how-to-create-a-custom-controls-library |
| 3 | +title: How to Create and Reference a Custom Control Library |
| 4 | +--- |
| 5 | + |
| 6 | +import Tabs from '@theme/Tabs'; |
| 7 | +import TabItem from '@theme/TabItem'; |
| 8 | +import NewClassLibraryVS from '/img/guides/custom-controls/new-class-library-vs.png'; |
| 9 | +import NewClassLibraryRider from '/img/guides/custom-controls/new-class-library-rider.png'; |
| 10 | +import InstallAvaloniaInClassLibraryVS from '/img/guides/custom-controls/install-avalonia-in-class-library-vs.png'; |
| 11 | +import InstallAvaloniaInClassLibraryRider from '/img/guides/custom-controls/install-avalonia-in-class-library-rider.png'; |
| 12 | +import CustomControlSolution from '/img/guides/custom-controls/custom-control-solution.png'; |
| 13 | +import CustomControlPreview from '/img/guides/custom-controls/custom-control-preview.png'; |
| 14 | + |
| 15 | +# How To Create and Reference a Custom Control Library |
| 16 | + |
| 17 | +This guide shows you how to create a custom control library and reference it for use in an _Avalonia UI_ app. |
| 18 | + |
| 19 | +## Creating a custom control library |
| 20 | + |
| 21 | +### Creating a new class library project |
| 22 | + |
| 23 | +To start, you need a **class library** project in which to collect your custom control files. |
| 24 | + |
| 25 | +<Tabs> |
| 26 | + <TabItem value="rider" label="Rider"> |
| 27 | + 1. Go to **File → New Solution**. Alternatively, **Add → New Project** to add the class library as a new project within an existing solution. |
| 28 | + 2. In the left panel, under the section "Project Type", select **Class Library**. |
| 29 | + 3. Name the project, e.g. "CCLibrary". |
| 30 | + 4. For "Target framework", select the preferred .NET version. |
| 31 | + 5. Click **Create**. |
| 32 | + |
| 33 | + <Image light={NewClassLibraryRider} alt="A screenshot of the new project menu in Rider." position="center" maxWidth={400} cornerRadius="true"/> |
| 34 | + </TabItem> |
| 35 | + <TabItem value="vs" label="Visual Studio"> |
| 36 | + 1. Go to **File → New → Project/Solution**. |
| 37 | + 2. Select **.NET Class Library** as the project template. Use the search bar to locate this template if it does not appear on the suggested list. |
| 38 | + 3. Name the project, e.g. "CCLibrary". |
| 39 | + 4. For "Target framework", select the preferred .NET version. |
| 40 | + 5. Click **Create**. |
| 41 | + |
| 42 | + <Image light={NewClassLibraryVS} alt="A screenshot of the new project menu in Visual Studio." position="center" maxWidth={400} cornerRadius="true"/> |
| 43 | + </TabItem> |
| 44 | +</Tabs> |
| 45 | + |
| 46 | +### Installing Avalonia in the class library project |
| 47 | + |
| 48 | +Next, you must install the Avalonia NuGet package in the class library. |
| 49 | + |
| 50 | +<Tabs> |
| 51 | + <TabItem value="rider" label="Rider"> |
| 52 | + 1. In the solution panel, select your class library project. |
| 53 | + 2. Click **Tools → NuGet → Manage NuGet Packages**. |
| 54 | + 3. Search for "Avalonia" in the search bar. |
| 55 | + 4. Select **Avalonia**. |
| 56 | + 5. Select the preferred version. |
| 57 | + 6. Click the name of your class library project at the bottom of the panel to install Avalonia to that project. |
| 58 | + |
| 59 | + <Image light={InstallAvaloniaInClassLibraryRider} alt="A screenshot demonstrating how to install the Avalonia NuGet package in Rider." position="center" maxWidth={400} cornerRadius="true"/> |
| 60 | + </TabItem> |
| 61 | + <TabItem value="vs" label="Visual Studio"> |
| 62 | + 1. In the solution explorer, select your class library project. |
| 63 | + 2. Click **Project → Manage NuGet Packages**. |
| 64 | + 3. Go to the **Browse** tab. Search for "Avalonia". |
| 65 | + 4. Select **Avalonia**. |
| 66 | + 5. Select the preferred version. |
| 67 | + 6. Click **Install**. |
| 68 | + |
| 69 | + <Image light={InstallAvaloniaInClassLibraryVS} alt="A screenshot demonstrating how to install the Avalonia NuGet package in Visual Studio." position="center" maxWidth={400} cornerRadius="true"/> |
| 70 | + </TabItem> |
| 71 | +</Tabs> |
| 72 | + |
| 73 | +### Adding a custom control to the class library |
| 74 | + |
| 75 | +Now that your class library is set up, you can start adding custom controls to it. |
| 76 | + |
| 77 | +In this example, we'll create a simple custom control named `MyCustomControl`, a blank box that can be filled with a colour of your choice. |
| 78 | + |
| 79 | +1. In the class library project, create a new `.cs` file. |
| 80 | +2. Create the custom control as shown below. |
| 81 | + |
| 82 | +```cs |
| 83 | +using Avalonia; |
| 84 | +using Avalonia.Controls; |
| 85 | +using Avalonia.Media; |
| 86 | + |
| 87 | +namespace CCLibrary |
| 88 | +{ |
| 89 | + |
| 90 | + /// <summary>A custom control that renders a coloured rectangle.</summary> |
| 91 | + public class MyCustomControl : Control |
| 92 | + { |
| 93 | + /// <remarks> |
| 94 | + /// Defines a styled property for the background colour, which can be set in XAML.<br/> |
| 95 | + /// AddOwner reuses the existing BackgroundProperty from Border.<br/> |
| 96 | + /// </remarks> |
| 97 | + public static readonly StyledProperty<IBrush?> BackgroundProperty = |
| 98 | + Border.BackgroundProperty.AddOwner<MyCustomControl>(); |
| 99 | + |
| 100 | + /// <summary>Gets and sets the colour used to fill the rectangle.</summary> |
| 101 | + public IBrush? Background |
| 102 | + { |
| 103 | + get { return GetValue(BackgroundProperty); } |
| 104 | + set { SetValue(BackgroundProperty, value); } |
| 105 | + } |
| 106 | + |
| 107 | + /// <summary>Renders the control.</summary> |
| 108 | + public sealed override void Render(DrawingContext context) |
| 109 | + { |
| 110 | + if (Background != null) // Only render if a colour is set. |
| 111 | + { |
| 112 | + var renderSize = Bounds.Size; // Get the size of the control. |
| 113 | + context.FillRectangle(Background, new Rect(renderSize)); // Fill the rectangle with the colour. |
| 114 | + } |
| 115 | + base.Render(context); |
| 116 | + } |
| 117 | + } |
| 118 | +} |
| 119 | +``` |
| 120 | + |
| 121 | +You can continue adding as many custom controls to the library as you wish. |
| 122 | + |
| 123 | +## Referencing a custom control library |
| 124 | + |
| 125 | +Reference your custom control library in an Avalonia project to allow those custom controls to be used. |
| 126 | + |
| 127 | +In this example, we have created a new project using the Avalonia MVVM template titled `AvaloniaCCLib`. |
| 128 | + |
| 129 | +<Image light={CustomControlSolution} alt="A screenshot of a solution containing two projects in Visual Studio." position="center" maxWidth={400} cornerRadius="true"/> |
| 130 | + |
| 131 | +### Add a project reference |
| 132 | + |
| 133 | +1. Open the .csproj file of your Avalonia project. |
| 134 | +2. Within the `<Project>...</Project>` tags, add a `ProjectReference` tag pointing to the directory path of the .csproj file of the class library project. |
| 135 | + |
| 136 | +```xml |
| 137 | +<ItemGroup> |
| 138 | + <ProjectReference Include="..\MyControlsLibrary\CCLibrary.csproj" /> |
| 139 | +</ItemGroup> |
| 140 | +``` |
| 141 | + |
| 142 | +### Add XML namespace declaration |
| 143 | + |
| 144 | +You can now make a namespace declaration in .axaml files of your Avalonia project to access your custom controls in XAML. |
| 145 | + |
| 146 | +1. Add a line similar to this one to the opening `<Window>` tag: `xmlns:cc="using:CCLibrary"`. (Remember to change the name of the class library project if you used a different one.) |
| 147 | + |
| 148 | +2. Add a custom control to the window's content zone by prefixing with `cc`. |
| 149 | + |
| 150 | +```xml |
| 151 | +<Window xmlns="https://github.com/avaloniaui" |
| 152 | + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
| 153 | + xmlns:cc="using:CCLibrary" |
| 154 | + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
| 155 | + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
| 156 | + mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" |
| 157 | + x:Class="AvaloniaCCLib.Views.MainWindow" |
| 158 | + Title="AvaloniaCCLib"> |
| 159 | + <Window.Styles> |
| 160 | + <Style Selector="cc|MyCustomControl"> |
| 161 | + <Setter Property="Background" Value="Yellow"/> |
| 162 | + </Style> |
| 163 | + </Window.Styles> |
| 164 | + |
| 165 | + <cc:MyCustomControl Height="200" Width="300"/> |
| 166 | + |
| 167 | +</Window> |
| 168 | +``` |
| 169 | + |
| 170 | +3. Build the solution. |
| 171 | +4. Verify you can see the custom control in the running window or preview. |
| 172 | + |
| 173 | +<Image light={CustomControlPreview} alt="A screenshot of an IDE, displaying XAML code in one window and a preview of a user interface in another." position="center" maxWidth={400} cornerRadius="true"/> |
| 174 | + |
| 175 | +## XML Namespace Definitions |
| 176 | + |
| 177 | +When referencing a control library in a .axaml file, you can use the URL identification format. For example: |
| 178 | + |
| 179 | +```xml |
| 180 | +xmlns:cc="https://my.controls.url" |
| 181 | +``` |
| 182 | + |
| 183 | +This is possible because of the presence of XML namespace definitions in a control library. These map URLs to the code namespaces, and are in the project's `Properties/AssemblyInfo.cs` file. (See this [source code](https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Controls/Properties/AssemblyInfo.cs) for an example.) |
| 184 | + |
| 185 | +```csharp |
| 186 | +[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia")] |
| 187 | +``` |
| 188 | + |
| 189 | +### Common Namespace Definitions |
| 190 | + |
| 191 | +You can make one URL map several namespaces in your control library. To do this, simply add multiple XML namespace definitions that use the same URL, but which map to different code namespaces. |
| 192 | + |
| 193 | +```cs |
| 194 | +using Avalonia.Metadata; |
| 195 | + |
| 196 | +[assembly: XmlnsDefinition("https://my.controls.url", "My.NameSpace")] |
| 197 | +[assembly: XmlnsDefinition("https://my.controls.url", "My.NameSpace.Other")] |
| 198 | +``` |
0 commit comments