You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/concepts/markupextensions/index.md
+73-24Lines changed: 73 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,12 +1,22 @@
1
1
---
2
-
id: markupextensions
3
-
title: Markup Extensions
2
+
id: index
3
+
title: Markup extensions
4
+
description: Markup extensions are simple classes that provide values to XAML properties at runtime. They provide a convenient, reusable option for code-based customization of properties.
4
5
---
5
6
6
-
A `MarkupExtension` allows code-based customization of setter logic to a target property in a convenient, reusable
7
-
syntax within XAML. Curly braces are used to differentiate the usage from plain text.
7
+
Markup extensions are simple classes that provide values to XAML properties at runtime. They provide a convenient, reusable option for code-based customization of properties.
- Optionally inherits from `MarkupExtension` (not required in Avalonia)
15
+
- Is used from XAML via the `{ns:Extension ...}` syntax
16
+
17
+
In Avalonia, `ProvideValue` is allowed to return **any** type. This means the result can be strongly typed, as the returned value is assigned directly to the target property.
18
+
19
+
Avalonia provides the following markup extensions:
@@ -21,7 +31,7 @@ Avalonia provides the following:
21
31
22
32
## Compiler intrinsics
23
33
24
-
These technically fall outside of `MarkupExtension`s as part of the XAML compiler, but the XAML syntax is the same.
34
+
These technically fall outside of `MarkupExtension` as part of the XAML compiler, but the XAML syntax is the same.
25
35
26
36
| Intrinsic | Assigns to Property |
27
37
|-----------|-----------------------|
@@ -31,14 +41,13 @@ These technically fall outside of `MarkupExtension`s as part of the XAML compile
31
41
| x:Static| Static member value |
32
42
| x:Type|`System.Type` literal |
33
43
34
-
The `x:True` and `x:False` literals have use cases where the target binding property is `object` and you need
35
-
to provide a boolean. In these scenarios that lack type information, providing "True" remains a `string`.
44
+
The `x:True` and `x:False` literals have use cases where the target binding property is `object` and you need to provide a boolean. In these scenarios that lack type information, providing "True" remains a `string`.
When strong types are used instead of `object`, you will receive compile-time errors when there is a mismatch in the XAML use of constructor parameters, properties, or the return value in `ProvideValue`. When returning `object`, the actual type returned must match the target property's type, else an `InvalidCastException` is thrown at runtime.
55
81
56
-
### Receiving Literal Parameters
82
+
### Using `IServiceProvider`
83
+
84
+
The `IServiceProvider` passed to `ProvideValue` exposes XAML context services, enabling the extension to understand where it is used.
85
+
86
+
Common standard services include:
87
+
88
+
-**`IProvideValueTarget`** — gives access to the target object and property.
89
+
-**`IRootObjectProvider`** — provides the XAML document’s root object.
90
+
91
+
Avalonia also provides additional, XAML-IL specific services:
92
+
93
+
-**`IAvaloniaXamlIlParentStackProvider`** — exposes the parent object stack during XAML parsing.
These services are optional, but essential for more advanced or context-aware extensions.
97
+
98
+
### Receiving literal parameters
57
99
58
100
When parameters are required, use a constructor to receive each parameter in order.
59
101
@@ -84,13 +126,11 @@ public class MultiplyLiteral
84
126
<TextBlockText="This has FontSize=40"FontSize="{namespace:MultiplyLiteral 10, 8, Third=0.5}" />
85
127
```
86
128
87
-
### Receiving Parameters From Bindings
129
+
### Receiving parameters from bindings
130
+
131
+
A common scenario is to transform data coming in from a binding and updating the target property. When all parameters come from bindings, this is straightforward by creating a `MultiBinding` with an `IMultiValueConverter`.
88
132
89
-
A common scenario is wanting to transform data coming in from a binding and updating the target property. When all parameters
90
-
come from bindings, this is somewhat straightforward by creating a `MultiBinding` with an `IMultiValueConverter`. In the
91
-
sample below, `MultiplyBinding` requires two bound parameters. If a mix of literal and bound parameters is necessary,
92
-
creating an `IMultiValueConverter` would allow for passing of literals as constructor or `init` parameters. `BindingBase`
93
-
allows for both `CompiledBinding` and `ReflectionBinding` to be used, but does not allow literals.
133
+
In the sample below, `MultiplyBinding` requires two bound parameters. If a mix of literal and bound parameters is necessary, creating an `IMultiValueConverter` would allow for passing of literals as constructor or `init` parameters. `BindingBase` allows for both `CompiledBinding` and `ReflectionBinding` to be used, but does not allow literals.
94
134
95
135
```csharp
96
136
publicclassMultiplyBinding
@@ -123,15 +163,24 @@ public class MultiplyBinding
123
163
```
124
164
125
165
:::info
126
-
127
166
An alternate approach is to return an `IObservable<T>.ToBinding()` instead.
128
-
129
167
:::
130
168
131
-
### Returning Parameters
169
+
### Returning parameters
170
+
171
+
Avalonia’s markup extension model is flexible: `ProvideValue` may return anything.
172
+
173
+
This includes:
174
+
175
+
- Static .NET object
176
+
- Typed .NET object, which can be validated at compile time when assigned to a property
177
+
-**Binding** instances
178
+
-**Observables (`IObservable<T>`)** for dynamic, reactive values
179
+
180
+
Binding-returning or observable-returning markup extensions are supported and integrate with Avalonia’s property and data-binding systems.
181
+
182
+
To make a markup extension compatible with multiple target property types, you can set `ProvideValue` to return an `object` in its method signature, so that each type can be handled individually.
132
183
133
-
To make a `MarkupExtension` compatible with multiple target property types, return an `object` and handle each
description: An options markup extension is a special type of markup extension, specialized for switch-like expressions.
5
+
---
6
+
7
+
`OptionsMarkupExtension` is a special type of markup extension, specialized for switch-like expressions. Its purpose is to provide optimization by removing branches that will never be used, allowing trimming by the compiler.
8
+
9
+
## `OnPlatform` markup extension
10
+
11
+
One example of an options markup extension is the built-in `OnPlatform` markup extension. This markup extension defines values per runtime platform (Windows, macOS, Linux, etc.) to optimize branches, selecting only those relevant to the platform being compiled for.
12
+
13
+
With `OnPlatform`, you can, for instance, use the `Markdown` control on Linux and the `WebView` control on other platforms. The unused control would be excluded, thus reducing the binary size.
14
+
15
+
## Creating custom options markup extensions
16
+
17
+
Here is an example of a custom implementation with `RuntimeInformation.ProcessArchitecture`. As shown in this example, we recommend using compiler flags or .NET runtime APIs that are effectively constant.
0 commit comments