Avalonia 中的生命周期

总目录


前言

本文通过实际的案例来理解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(
上一篇:【Liunx篇】基础开发工具-自动化构建-make/Makefile-前言:


下一篇:WPF依赖属性详解