XAML Essentials
XAML Namespace
XAML namespace was a feature inherited from xml, it allows to import namespaces at any level of element, and all of its child elements within the scope can access the namespace. A namespace follows syntax of xmlns[:<alias>]
, where <alias>
is available as identifier in scope, either as attribute name or a interpolated uri using another namespace alias.
NOTE
Namespace is not order-sensitive, they're structural.
<MyElement xmlns:vm="using:MyApp.ViewModels"
x:DataType="vm:MainWindowViewModel"> <!-- use vm alias in another namespace -->
<BarElement xmlns:BarElement="MyElement.BarElement" /> <!-- namespace can be imported in any level -->
</MyElement>
2
3
4
Default Namespace
Default namespace is a shorthand without alias name that emits members into current scope. The default namespace in xaml files is particularly a url, but compiler is not going to read any content of it, instead it's simply a unique identifier used as a key to a specific internal mapping.
<Foo xmlns="https://github.com/avaloniaui" />
Conventional Namespaces
xmlns:x
: a namespace of common XAML directives, see XAML Directivesxml<Foo xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />
1xmlns:d
xmlns:vm
xmlns:mc
XAML Directives
xmlns:x
contains common directives of XAML elements to bind special context for the xaml file, such its code-behind class and view model. Each child element within the scope can access it.
x:Class
: the class of control presented as xaml element.x:DataType
: theDataContext
(aka ViewModel in MVVM) for current control.x:Name
: name of the instance of control within the code-behind class.- XAML compiler would generate an instance by that name for your code-behind class.
- avalonia has a
StyledElement.NameProperty
available, which is an equivalence ofx:Name
x:Type
: accessor for types, can be used as a markup extension. It's the equivalent of using thetypeof
operator.
<Window.DataTemplates>
<DataTemplate DataType="{x:Type local:Student}">
<!-- ... -->
</DataTemplate>
</Window.DataTemplates>
2
3
4
5
x:Static
: accessor for static members in assembly, can be used as a markup extension.
<Window.Resources>
<SolidColorBrush Color="{x:Static Colors.Aqua}"></SolidColorBrush>
</Window.Resources>
2
3
x:Key
: similar tox:Name
but for static identifier in resource dictionary
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:MyApp.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="MyApp.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Title="MyApp">
<StackPanel>
<TextBlock x:Name="MyTextBlock" />
<TextBlock Name="MyAnotherTextBlock" /> <!-- this is equivalent way to declare the field -->
</StackPanel>
</Window>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using Avalonia.Controls;
namespace MyApp.Views;
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
// access the control instance declared in XAML
this.MyTextBlock.Text = nameof(MyTextBlock);
this.MyAnotherTextBlock.Text = nameof(MyAnotherTextBlock);
}
}
2
3
4
5
6
7
8
9
10
11
Property Syntax
A property can be assigned by attribute syntax or a nesting element(when the property is a structural element)
<MyWindow FooProperty="FooProperty"></MyWindow>
<!-- equivalent to -->
<MyWindow>
<MyWindow.FooProperty>FooProperty</MyWindow.FooProperty>
</MyWindow>
2
3
4
5
Implicit Bindings
ContentControl.Content
: xaml compiler would recognize the first(and only allow one) element as the value ofContent
.ItemsControl.Items
NOTE
ContentControl.Content
and ItemsControl.Items
are all marked by [Avalonia.Metadata.ContentAttribute]
public class ContentControl
: TemplatedControl,
IContentControl,
IContentPresenterHost {
/** ... **/
public static readonly StyledProperty<object?> ContentProperty =
AvaloniaProperty.Register<ContentControl, object?>(nameof(Content));
[Content]
[DependsOn(nameof(ContentTemplate))]
public object? Content {
get => GetValue(ContentProperty); // ContentProperty is of type AvaloniaProperty
set => SetValue(ContentProperty, value);
}
/** ... **/
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16