Skip to content

Creating widgets

Илья edited this page Aug 6, 2024 · 10 revisions

Table of Contents

Understanding uWidgets

  • uWidgets is a .NET Application for Windows made with Avalonia UI.
  • Each widget is a separate .dll assembly, that is loaded using Reflection.
  • You can use the guide below to create your own widget using C#.
  • You can publish your widget independently and distribute it as .dll,
    or you can create a Pull Request and it will be distributed with the next release after being merged

Step-by-step guide

0. Prerequisites

Before you begin, ensure you have the following prerequisites:

  • Operating System: Windows 8.1 or later
  • Development Kit: .NET 8.0 SDK
  • IDE: Visual Studio or JetBrains Rider

1. Clone the Repository

Start by cloning the repository where your widget development will take place.

git clone https://github.com/creewick/uWidgets.git

2. Prepare a New Project

image
  • Open ./src/uWidgets.sln with your IDE

  • Create a new project with the following settings:

    • Project Type: Class Library
    • Project Directory: ./src/Widgets/
    • Target Framework: net8.0
  • Add Avalonia package to the project

  • Add the following into your .csproj file, inside of the <PropertyGroup>:

    <OutputPath>..\..\uWidgets\bin\$(Configuration)\$(TargetFramework)\Widgets</OutputPath>
    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
  • Create AssemblyInfo.cs:

    using System.Reflection;
    
    [assembly: AssemblyCompany("<author-name>")]
    [assembly: AssemblyVersion("<widget-version>")]
  • Populate the folders
    Typically, your project would look like this:

    ├─ Locales
    │  └─ ...
    ├─ Models
    │  └─ ...
    ├─ ViewModels
    │  └─ ...
    ├─ Views
    │  └─ ...
    ├─ AssemblyInfo.cs
    └─ MyWidgetName.csproj
    

3. Adding a View

View is a class that represents widget's UI.

  • Create a new Avalonia User Control under the Views folder
    It will generate two files:

    • Layout file (.axaml)
    <UserControl xmlns="https://github.com/avaloniaui"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          x:Class="MyWidget.Views.MyWidgetView">
      <TextBlock Text="My Widget" />
    </UserControl>
    • and Code Behind file (.axaml.cs)
    using Avalonia.Controls;
    
    namespace MyWidget.Views;
    
    public partial class MyWidgetView : UserControl
    {
        public MyWidgetView()
        {
            InitializeComponent();
        }
    }
  • Register your View in the AssemblyInfo.cs using WidgetInfoAttribute

    [assembly: WidgetInfo(typeof(MyWidgetView))]
image
  • Build the solution and run the uWidgets project.
    You will see your project's assembly name in the sidebar menu.
    Click it, and you will see your View in the gallery.

4. Adding a ViewModel

ViewModel is a class that holds the data that the view needs to display.

4.1. Using View's code behind as ViewModel

For widgets with no complex logic, use can set the code behind class as ViewModel.

  • Use DataContext = this in code behind

    public string Text { get; } = "Hello World";
    
    public MyWidgetView()
    {
        DataContext = this;
        InitializeComponent();
    }
  • Add x:DataType="views:MyWidgetView" as <UserControl>'s attribute

  • Use {Binding <PropertyName>} to get your data

    <UserControl xmlns="https://github.com/avaloniaui"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          x:Class="MyWidget.Views.MyWidgetView"
          x:DataType="views:MyWidgetView">
      <TextBlock Text="{Binding Text}" />
    </UserControl>

4.2. Using a separate class as ViewModel

For widgets with complex logic, create a separate class

  • Create a class under the ViewModels folder

    public class MyWidgetViewModel
    {
        public string Text { get; } = "Hello World";
    }
  • Set it's instance as DataContext

    public MyWidgetView()
    {
        DataContext = new MyWidgetViewModel();
        InitializeComponent();
    }
  • Add x:DataType="viewsModels:MyWidgetViewModel" as <UserControl>'s attribute

  • Use {Binding <PropertyName>} to get your data

    <UserControl xmlns="https://github.com/avaloniaui"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          x:Class="MyWidget.Views.MyWidgetView"
          x:DataType="viewsModels:MyWidgetViewModel">
      <TextBlock Text="{Binding Text}" />
    </UserControl>
Clone this wiki locally