AKCSS declarations can target ordinary C# classes as well as Avalonia controls. 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.