总目录
前言
本文通过实际的案例来理解Avalonia中的生命周期,通过理解Avalonia中的生命周期可以帮助我们在合适的时候执行特定的逻辑,如资源的初始化与清理、用户交互的处理等。
一、Window生命周期
1. 介绍
Window的生命周期是指Window从创建到销毁的整个过程,包括初始化、显示、激活、关闭等状态。
2. 案例
下面 通过一个案例来说明Window的生命周期:MainWindow中 点击按钮,弹出Window1窗口,然后通过Window1的关闭按钮来关闭Window1来展示完整的Window生命周期
-
创建Avalonia .NET MVVM App(AvaloniaUI)项目,MVVMToolKit 选择 CommunityToolKit
-
MainWindow.axaml
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:AvaloniaWindowDemo.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="250"
x:Class="AvaloniaWindowDemo.Views.MainWindow"
xmlns:v="using:AvaloniaWindowDemo.Views"
x:DataType="vm:MainWindowViewModel"
Icon="/Assets/avalonia-logo.ico"
Title="AvaloniaWindowDemo">
<Design.DataContext>
<vm:MainWindowViewModel />
</Design.DataContext>
<Grid Margin="50" Background="Red">
<Button x:Name="testButton" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Test" Click="Button_Click"></Button>
</Grid>
</Window>
- MainWindow.axaml.cs
private void Button_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
new Window1().Show();
}
- Window1.axaml
<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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaWindowDemo.Window1"
Title="Window1">
Welcome to Avalonia!
</Window>
- Window1.axaml.cs
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
Debug.WriteLine("InitializeComponent 初始化");
this.Initialized += Window1_Initialized;
this.AttachedToVisualTree += Window1_AttachedToVisualTree;
this.AttachedToLogicalTree += Window1_AttachedToLogicalTree;
this.DetachedFromVisualTree += Window1_DetachedFromVisualTree;
this.DetachedFromLogicalTree += Window1_DetachedFromLogicalTree;
this.Loaded += Window1_Loaded;
this.Opened += Window1_Opened;
this.Activated += Window1_Activated;
this.Deactivated += Window1_Deactivated;
this.Closing += Window1_Closing;
this.Closed += Window1_Closed;
}
private void Window1_DetachedFromLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
{
Debug.WriteLine("Window1_DetachedFromLogicalTree");
}
private void Window1_DetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
Debug.WriteLine("Window1_DetachedFromVisualTree");
}
private void Window1_Initialized(object? sender, System.EventArgs e)
{
Debug.WriteLine("Window1_Initialized");
}
private void Window1_Closed(object? sender, System.EventArgs e)
{
Debug.WriteLine("Window1_Closed");
}
private void Window1_Closing(object? sender, WindowClosingEventArgs e)
{
Debug.WriteLine("Window1_Closing");
}
private void Window1_Deactivated(object? sender, System.EventArgs e)
{
Debug.WriteLine("Window1_Deactivated");
}
private void Window1_Activated(object? sender, System.EventArgs e)
{
Debug.WriteLine("Window1_Activated");
}
private void Window1_Opened(object? sender, System.EventArgs e)
{
Debug.WriteLine("Window1_Opened");
}
private void Window1_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
Debug.WriteLine("Window1_Loaded");
}
private void Window1_AttachedToLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
{
Debug.WriteLine("Window1_AttachedToLogicalTree");
}
private void Window1_AttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
Debug.WriteLine("Window1_AttachedToLogicalTree");
}
}
当点击 按钮 Show 出 Window1 时:
当点击Window1 的关闭按钮 时:
3. 小结
一个Window 的生命周期:
- 创建周期:
- 初始化(
InitializeComponent
) - 激活(
Activated
) - 打开界面(
Opened
) - 加载完成(
Loaded
)
- 初始化(
- 销毁周期:
- 激活(
Activated
) - 关闭中(
Closing
) - 失活(
Deactivated
) - 从逻辑树分离(
DetachedFromLogicalTree
) - 从视觉树分离(
DetachedFromVisualTree
) - 关闭(
Closed
)
- 激活(
理解生命周期的时间点,我们可以对应在生命周期 进行 一些初始化,更新UI状态,释放资源,执行资源回收等操作。
二、Avalonia 控件的生命周期
1. 介绍
Avalonia 中 如 TextBox,TextBlock ,Button 等控件也有着自己的生命周期,控件的生命周期主要体现在附加到视觉树和从视觉树分离上。
2. 案例
- MainWindow
- 作用:点击按钮 弹出 Window1 窗口
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:AvaloniaWindowDemo.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="250"
x:Class="AvaloniaWindowDemo.Views.MainWindow"
xmlns:v="using:AvaloniaWindowDemo.Views"
x:DataType="vm:MainWindowViewModel"
Icon="/Assets/avalonia-logo.ico"
Title="AvaloniaWindowDemo">
<Design.DataContext>
<vm:MainWindowViewModel />
</Design.DataContext>
<Grid Margin="50" Background="Red">
<Button x:Name="testButton" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Test" Click="Button_Click"></Button>
</Grid>
</Window>
private void Button_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
new Window1().Show();
}
- Window1
- 作用:通过弹出的Window1 观察Window1的生命周期 和 Window1内 Button 和 UserControl的生命周期
<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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaWindowDemo.Window1"
xmlns:v="using:AvaloniaWindowDemo.Views"
Title="Window1">
<StackPanel Background="Azure">
<Button x:Name="Button1" Content="Show" HorizontalAlignment="Center"></Button>
<v:UserControl1 x:Name="UserControl1" Height="60"></v:UserControl1>
</StackPanel>
</Window>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
Debug.WriteLine("InitializeComponent 初始化");
this.Initialized += Window1_Initialized;
this.AttachedToVisualTree += Window1_AttachedToVisualTree;
this.AttachedToLogicalTree += Window1_AttachedToLogicalTree;
this.DetachedFromVisualTree += Window1_DetachedFromVisualTree;
this.DetachedFromLogicalTree += Window1_DetachedFromLogicalTree;
this.Loaded += Window1_Loaded;
this.Opened += Window1_Opened;
this.Activated += Window1_Activated;
this.Deactivated += Window1_Deactivated;
this.Closing += Window1_Closing;
this.Closed += Window1_Closed;
this.Button1.Initialized += Button1_Initialized;
this.Button1.AttachedToVisualTree += Button1_AttachedToVisualTree;
this.Button1.AttachedToLogicalTree += Button1_AttachedToLogicalTree;
this.Button1.DetachedFromVisualTree += Button1_DetachedFromVisualTree;
this.Button1.DetachedFromLogicalTree += Button1_DetachedFromLogicalTree;
this.UserControl1.Initialized += UserControl1_Initialized;
this.UserControl1.Loaded += UserControl1_Loaded;
this.UserControl1.AttachedToVisualTree += UserControl1_AttachedToVisualTree;
this.UserControl1.AttachedToLogicalTree += UserControl1_AttachedToLogicalTree;
this.UserControl1.DetachedFromVisualTree += UserControl1_DetachedFromVisualTree;
this.UserControl1.DetachedFromLogicalTree += UserControl1_DetachedFromLogicalTree;
}
private void UserControl1_Initialized(object? sender, System.EventArgs e)
{
Debug.WriteLine("UserControl1_Initialized");
}
private void UserControl1_DetachedFromLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
{
Debug.WriteLine("UserControl1_DetachedFromLogicalTree");
}
private void UserControl1_DetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
Debug.WriteLine("UserControl1_DetachedFromVisualTree");
}
private void UserControl1_AttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
Debug.WriteLine("UserControl1_AttachedToVisualTree");
}
private void UserControl1_AttachedToLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
{
Debug.WriteLine("UserControl1_AttachedToLogicalTree");
}
private void UserControl1_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
Debug.WriteLine("UserControl1_Loaded");
}
private void Button1_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
Debug.WriteLine("Button1_Loaded");
}
private void Button1_DetachedFromLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
{
Debug.WriteLine("Button1_DetachedFromLogicalTree");
}
private void Button1_DetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
Debug.WriteLine("Button1_DetachedFromVisualTree");
}
private void Button1_AttachedToLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
{
Debug.WriteLine("Button1_AttachedToLogicalTree");
}
private void Button1_AttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
Debug.WriteLine("Button1_AttachedToVisualTree");
}
private void Button1_Initialized(object? sender, System.EventArgs e)
{
Debug.WriteLine("Button1_Initialized");
}
private void Window1_DetachedFromLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
{
Debug.WriteLine("Window1_DetachedFromLogicalTree");
}
private void Window1_DetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
Debug.WriteLine("Window1_DetachedFromVisualTree");
}
private void Window1_Initialized(object? sender, System.EventArgs e)
{
Debug.WriteLine("Window1_Initialized");
}
private void Window1_Closed(object? sender, System.EventArgs e)
{
Debug.WriteLine("Window1_Closed");
}
private void Window1_Closing(object? sender, WindowClosingEventArgs e)
{
Debug.WriteLine("Window1_Closing");
}
private void Window1_Deactivated(object? sender, System.EventArgs e)
{
Debug.WriteLine("Window1_Deactivated");
}
private void Window1_Activated(object? sender, System.EventArgs e)
{
Debug.WriteLine("Window1_Activated");
}
private void Window1_Opened(