AKCSS declarations can target ordinary C# classes as well as Avalonia controls. The target does not need to derive from Control, AvaloniaObject, or another Avalonia base type. AKCSS resolves the CLR type and binds declarations to its writable properties.
This is useful when markup creates or configures data objects alongside the visual tree.
Define a custom class​
MyClass.cs:
namespace Data;
public class MyClass
{
public int Age { get; set; }
}
Import its namespace and declare type-only, typed-class, and mixed styles.
Styles.akcss:
@using Data;
MyClass {
Age: 1;
}
MyClass.anotherStyle {
Age: 10;
}
.myStyle {
MyClass.Age: 10;
Padding: 10;
}
Use the styles from markup:
Styles.akbura:
using Data;
<StackPanel>
<Button class="myStyle">Hello world!</Button>
<Button>
<MyClass class="myStyle"/>
</Button>
<Button>
<MyClass/>
</Button>
</StackPanel>
Properties are applied by target compatibility​
AKCSS binds every declaration against the object that receives the style. A declaration is applied only when its property belongs to that target type.
For .myStyle:
.myStyle {
MyClass.Age: 10;
Padding: 10;
}
the result depends on the target:
| Target | Applied | Ignored |
|---|---|---|
Button |
Padding: 10 |
MyClass.Age: 10 |
MyClass |
MyClass.Age: 10 |
Padding: 10 |
MyClass.Age does not belong to Button, so it is skipped when .myStyle is placed on a button. Conversely, MyClass has no Padding property, so that declaration is skipped when the same style is placed on MyClass.
This allows a shared class selector to contain declarations for several compatible target types without writing separate class names for each one.
Typed selectors​
A target type can be combined with an optional class name:
MyClass {
Age: 1;
}
MyClass.anotherStyle {
Age: 10;
}
MyClassis a type-only selector and applies its declarations to that type.MyClass.anotherStylealso requiresclass="anotherStyle".
Use a parenthesized or globally qualified selector when the type name is nested or ambiguous:
(Data.MyClass) { }
(global::Data.MyClass).anotherStyle { }
Reactive custom properties​
Expressions over custom objects follow the same observation rules as control styles. If the owning object implements INotifyPropertyChanged, AKCSS can reapply a style when a referenced property changes:
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace Data;
public class MyClass : INotifyPropertyChanged
{
private int _age;
public int Age
{
get => _age;
set
{
if (_age == value)
{
return;
}
_age = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Age)));
}
}
public event PropertyChangedEventHandler? PropertyChanged;
}
Without INotifyPropertyChanged or another supported observable source, the initial style value is still applied, but later property changes do not automatically trigger reevaluation.