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:dxmlns:vmxmlns: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.NamePropertyavailable, which is an equivalence ofx:Name
x:Type: accessor for types, can be used as a markup extension. It's the equivalent of using thetypeofoperator.
<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:Namebut 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