Avalonia 中的生命周期

打印 上一主题 下一主题

主题 746|帖子 746|积分 2238

总目录


前言

本文通过实际的案例来理解Avalonia中的生命周期,通过理解Avalonia中的生命周期可以帮助我们在合适的时间实行特定的逻辑,如资源的初始化与清理、用户交互的处理等。

一、Window生命周期

1. 先容

Window的生命周期是指Window从创建到销毁的整个过程,包括初始化、表现、激活、关闭等状态。
2. 案例

下面 通过一个案例来说明Window的生命周期:MainWindow中 点击按钮,弹出Window1窗口,然后通过Window1的关闭按钮来关闭Window1来展示完备的Window生命周期


  • 创建Avalonia .NET MVVM App(AvaloniaUI)项目,MVVMToolKit 选择 CommunityToolKit
  • MainWindow.axaml
  1. <Window xmlns="https://github.com/avaloniaui"
  2.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  3.         xmlns:vm="using:AvaloniaWindowDemo.ViewModels"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="250"
  7.         x:Class="AvaloniaWindowDemo.Views.MainWindow"
  8.         xmlns:v="using:AvaloniaWindowDemo.Views"
  9.         x:DataType="vm:MainWindowViewModel"
  10.         Icon="/Assets/avalonia-logo.ico"
  11.         Title="AvaloniaWindowDemo">
  12.     <Design.DataContext>
  13.         <vm:MainWindowViewModel />
  14.     </Design.DataContext>
  15.     <Grid Margin="50" Background="Red">
  16.                 <Button x:Name="testButton" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Test" Click="Button_Click"></Button>
  17.         </Grid>
  18. </Window>
复制代码


  • MainWindow.axaml.cs
  1.         private void Button_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
  2.         {
  3.             new Window1().Show();
  4.         }
复制代码


  • Window1.axaml
  1. <Window xmlns="https://github.com/avaloniaui"
  2.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  3.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  4.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  5.         mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
  6.         x:Class="AvaloniaWindowDemo.Window1"
  7.         Title="Window1">
  8.   Welcome to Avalonia!
  9. </Window>
复制代码


  • Window1.axaml.cs
  1. public partial class Window1 : Window
  2. {
  3.     public Window1()
  4.     {
  5.         InitializeComponent();
  6.         Debug.WriteLine("InitializeComponent 初始化");
  7.         this.Initialized += Window1_Initialized;
  8.         
  9.         this.AttachedToVisualTree += Window1_AttachedToVisualTree;
  10.         this.AttachedToLogicalTree += Window1_AttachedToLogicalTree;
  11.         this.DetachedFromVisualTree += Window1_DetachedFromVisualTree;
  12.         this.DetachedFromLogicalTree += Window1_DetachedFromLogicalTree;
  13.         this.Loaded += Window1_Loaded;
  14.         this.Opened += Window1_Opened;
  15.         this.Activated += Window1_Activated;
  16.         this.Deactivated += Window1_Deactivated;
  17.         this.Closing += Window1_Closing;
  18.         this.Closed += Window1_Closed;
  19.     }
  20.     private void Window1_DetachedFromLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
  21.     {
  22.         Debug.WriteLine("Window1_DetachedFromLogicalTree");
  23.     }
  24.     private void Window1_DetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
  25.     {
  26.         Debug.WriteLine("Window1_DetachedFromVisualTree");
  27.     }
  28.     private void Window1_Initialized(object? sender, System.EventArgs e)
  29.     {
  30.         Debug.WriteLine("Window1_Initialized");
  31.     }
  32.     private void Window1_Closed(object? sender, System.EventArgs e)
  33.     {
  34.         Debug.WriteLine("Window1_Closed");
  35.     }
  36.     private void Window1_Closing(object? sender, WindowClosingEventArgs e)
  37.     {
  38.         Debug.WriteLine("Window1_Closing");
  39.     }
  40.     private void Window1_Deactivated(object? sender, System.EventArgs e)
  41.     {
  42.         Debug.WriteLine("Window1_Deactivated");
  43.     }
  44.     private void Window1_Activated(object? sender, System.EventArgs e)
  45.     {
  46.         Debug.WriteLine("Window1_Activated");
  47.     }
  48.     private void Window1_Opened(object? sender, System.EventArgs e)
  49.     {
  50.         Debug.WriteLine("Window1_Opened");
  51.     }
  52.     private void Window1_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
  53.     {
  54.         Debug.WriteLine("Window1_Loaded");
  55.     }
  56.     private void Window1_AttachedToLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
  57.     {
  58.         Debug.WriteLine("Window1_AttachedToLogicalTree");
  59.     }
  60.     private void Window1_AttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
  61.     {
  62.         Debug.WriteLine("Window1_AttachedToLogicalTree");
  63.     }
  64. }
复制代码
当点击 按钮 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 窗口


  1. <Window xmlns="https://github.com/avaloniaui"
  2.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  3.         xmlns:vm="using:AvaloniaWindowDemo.ViewModels"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="250"
  7.         x:Class="AvaloniaWindowDemo.Views.MainWindow"
  8.         xmlns:v="using:AvaloniaWindowDemo.Views"
  9.         x:DataType="vm:MainWindowViewModel"
  10.         Icon="/Assets/avalonia-logo.ico"
  11.         Title="AvaloniaWindowDemo">
  12.     <Design.DataContext>
  13.         <vm:MainWindowViewModel />
  14.     </Design.DataContext>
  15.     <Grid Margin="50" Background="Red">
  16.                 <Button x:Name="testButton" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Test" Click="Button_Click"></Button>
  17.         </Grid>
  18. </Window>
复制代码
  1.         private void Button_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
  2.         {
  3.             new Window1().Show();
  4.         }
复制代码


  • Window1

    • 作用:通过弹出的Window1 观察Window1的生命周期 和 Window1内 Button 和 UserControl的生命周期


  1. <Window xmlns="https://github.com/avaloniaui"
  2.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  3.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  4.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  5.         mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
  6.         x:Class="AvaloniaWindowDemo.Window1"
  7.                 xmlns:v="using:AvaloniaWindowDemo.Views"
  8.         Title="Window1">
  9.         <StackPanel Background="Azure">
  10.                 <Button x:Name="Button1" Content="Show" HorizontalAlignment="Center"></Button>
  11.                 <v:UserControl1 x:Name="UserControl1" Height="60"></v:UserControl1>
  12.         </StackPanel>
  13. </Window>
复制代码
  1. public partial class Window1 : Window
  2. {
  3.     public Window1()
  4.     {
  5.         InitializeComponent();
  6.         Debug.WriteLine("InitializeComponent 初始化");
  7.         this.Initialized += Window1_Initialized;
  8.         
  9.         this.AttachedToVisualTree += Window1_AttachedToVisualTree;
  10.         this.AttachedToLogicalTree += Window1_AttachedToLogicalTree;
  11.         this.DetachedFromVisualTree += Window1_DetachedFromVisualTree;
  12.         this.DetachedFromLogicalTree += Window1_DetachedFromLogicalTree;
  13.         this.Loaded += Window1_Loaded;
  14.         this.Opened += Window1_Opened;
  15.         this.Activated += Window1_Activated;
  16.         this.Deactivated += Window1_Deactivated;
  17.         this.Closing += Window1_Closing;
  18.         this.Closed += Window1_Closed;
  19.         this.Button1.Initialized += Button1_Initialized;
  20.         this.Button1.AttachedToVisualTree += Button1_AttachedToVisualTree;
  21.         this.Button1.AttachedToLogicalTree += Button1_AttachedToLogicalTree;
  22.         this.Button1.DetachedFromVisualTree += Button1_DetachedFromVisualTree;
  23.         this.Button1.DetachedFromLogicalTree += Button1_DetachedFromLogicalTree;
  24.         this.UserControl1.Initialized += UserControl1_Initialized;
  25.         this.UserControl1.Loaded += UserControl1_Loaded;
  26.         this.UserControl1.AttachedToVisualTree += UserControl1_AttachedToVisualTree;
  27.         this.UserControl1.AttachedToLogicalTree += UserControl1_AttachedToLogicalTree;
  28.         this.UserControl1.DetachedFromVisualTree += UserControl1_DetachedFromVisualTree;
  29.         this.UserControl1.DetachedFromLogicalTree += UserControl1_DetachedFromLogicalTree;
  30.     }
  31.     private void UserControl1_Initialized(object? sender, System.EventArgs e)
  32.     {
  33.         Debug.WriteLine("UserControl1_Initialized");
  34.     }
  35.     private void UserControl1_DetachedFromLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
  36.     {
  37.         Debug.WriteLine("UserControl1_DetachedFromLogicalTree");
  38.     }
  39.     private void UserControl1_DetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
  40.     {
  41.         Debug.WriteLine("UserControl1_DetachedFromVisualTree");
  42.     }
  43.     private void UserControl1_AttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
  44.     {
  45.         Debug.WriteLine("UserControl1_AttachedToVisualTree");
  46.     }
  47.     private void UserControl1_AttachedToLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
  48.     {
  49.         Debug.WriteLine("UserControl1_AttachedToLogicalTree");
  50.     }
  51.     private void UserControl1_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
  52.     {
  53.         Debug.WriteLine("UserControl1_Loaded");
  54.     }
  55.     private void Button1_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
  56.     {
  57.         Debug.WriteLine("Button1_Loaded");
  58.     }
  59.     private void Button1_DetachedFromLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
  60.     {
  61.         Debug.WriteLine("Button1_DetachedFromLogicalTree");
  62.     }
  63.     private void Button1_DetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
  64.     {
  65.         Debug.WriteLine("Button1_DetachedFromVisualTree");
  66.     }
  67.     private void Button1_AttachedToLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
  68.     {
  69.         Debug.WriteLine("Button1_AttachedToLogicalTree");
  70.     }
  71.     private void Button1_AttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
  72.     {
  73.         Debug.WriteLine("Button1_AttachedToVisualTree");
  74.     }
  75.     private void Button1_Initialized(object? sender, System.EventArgs e)
  76.     {
  77.         Debug.WriteLine("Button1_Initialized");
  78.     }
  79.     private void Window1_DetachedFromLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
  80.     {
  81.         Debug.WriteLine("Window1_DetachedFromLogicalTree");
  82.     }
  83.     private void Window1_DetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
  84.     {
  85.         Debug.WriteLine("Window1_DetachedFromVisualTree");
  86.     }
  87.     private void Window1_Initialized(object? sender, System.EventArgs e)
  88.     {
  89.         Debug.WriteLine("Window1_Initialized");
  90.     }
  91.     private void Window1_Closed(object? sender, System.EventArgs e)
  92.     {
  93.         Debug.WriteLine("Window1_Closed");
  94.     }
  95.     private void Window1_Closing(object? sender, WindowClosingEventArgs e)
  96.     {
  97.         Debug.WriteLine("Window1_Closing");
  98.     }
  99.     private void Window1_Deactivated(object? sender, System.EventArgs e)
  100.     {
  101.         Debug.WriteLine("Window1_Deactivated");
  102.     }
  103.     private void Window1_Activated(object? sender, System.EventArgs e)
  104.     {
  105.         Debug.WriteLine("Window1_Activated");
  106.     }
  107.     private void Window1_Opened(object? sender, System.EventArgs e)
  108.     {
  109.         Debug.WriteLine("Window1_Opened");
  110.     }
  111.     private void Window1_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
  112.     {
  113.         Debug.WriteLine("Window1_Loaded");
  114.     }
  115.     private void Window1_AttachedToLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
  116.     {
  117.         Debug.WriteLine("Window1_AttachedToLogicalTree");
  118.     }
  119.     private void Window1_AttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
  120.     {
  121.         Debug.WriteLine("Window1_AttachedToLogicalTree");
  122.     }
  123. }
复制代码


  • UserControl1

    • 通过UserControl 观察UserControl 内部TextBlock 的生命周期


  1. <UserControl xmlns="https://github.com/avaloniaui"
  2.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  3.              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  4.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  5.              mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
  6.              x:Class="AvaloniaWindowDemo.Views.UserControl1">
  7.     <Border Background="Aqua">
  8.         <TextBlock x:Name="UserControl_TextBlock" Text="这是一个UserControl"></TextBlock>
  9.     </Border>
  10. </UserControl>
复制代码
  1. public partial class UserControl1 : UserControl
  2. {
  3.     public UserControl1()
  4.     {
  5.         InitializeComponent();
  6.         this.UserControl_TextBlock.Initialized += UserControl_TextBlock_Initialized;
  7.         this.UserControl_TextBlock.Loaded += UserControl_TextBlock_Loaded;
  8.         this.UserControl_TextBlock.AttachedToVisualTree += UserControl_TextBlock_AttachedToVisualTree;
  9.         this.UserControl_TextBlock.AttachedToLogicalTree += UserControl_TextBlock_AttachedToLogicalTree;
  10.         this.UserControl_TextBlock.DetachedFromVisualTree += UserControl_TextBlock_DetachedFromVisualTree;
  11.         this.UserControl_TextBlock.DetachedFromLogicalTree += UserControl_TextBlock_DetachedFromLogicalTree;
  12.     }
  13.     private void UserControl_TextBlock_DetachedFromLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
  14.     {
  15.         Debug.WriteLine("UserControl_TextBlock_DetachedFromLogicalTree");
  16.     }
  17.     private void UserControl_TextBlock_DetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
  18.     {
  19.         Debug.WriteLine("UserControl_TextBlock_DetachedFromVisualTree");
  20.     }
  21.     private void UserControl_TextBlock_AttachedToLogicalTree(object? sender, Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs e)
  22.     {
  23.         Debug.WriteLine("UserControl_TextBlock_AttachedToLogicalTree");
  24.     }
  25.     private void UserControl_TextBlock_AttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
  26.     {
  27.         Debug.WriteLine("UserControl_TextBlock_AttachedToVisualTree");
  28.     }
  29.     private void UserControl_TextBlock_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
  30.     {
  31.         Debug.WriteLine("UserControl_TextBlock_Loaded");
  32.     }
  33.     private void UserControl_TextBlock_Initialized(object? sender, System.EventArgs e)
  34.     {
  35.         Debug.WriteLine("UserControl_TextBlock_Initialized");
  36.     }
  37. }
复制代码


  • 当我们点击MainWindow中的 按钮,弹出Window1 窗口时:
  1. UserControl_TextBlock_AttachedToLogicalTree
  2. InitializeComponent 初始化
  3. Button1_AttachedToVisualTree
  4. UserControl1_AttachedToVisualTree
  5. UserControl_TextBlock_AttachedToVisualTree
  6. UserControl_TextBlock_Initialized
  7. Window1_Activated
  8. Window1_Opened
  9. UserControl1_Loaded
  10. UserControl_TextBlock_Loaded
  11. Window1_Loaded
  12. Window1_Deactivated
复制代码


  • 当我们点击Window1中的 关闭按钮时:
  1. Window1_Activated
  2. Window1_Closing
  3. Window1_Deactivated
  4. Window1_DetachedFromLogicalTree
  5. Button1_DetachedFromLogicalTree
  6. UserControl1_DetachedFromLogicalTree
  7. UserControl_TextBlock_DetachedFromLogicalTree
  8. Window1_DetachedFromVisualTree
  9. Button1_DetachedFromVisualTree
  10. UserControl1_DetachedFromVisualTree
  11. UserControl_TextBlock_DetachedFromVisualTree
  12. Window1_Closed
复制代码
3. 小结

通过以上案例可知:


  • 当Window内全部的控件都完成了Loaded以后,Window 才会进行Loaded
  • 控件在所在的Window 被Show出来时的生命周期:

    • 附加到逻辑树(AttachedToLogicalTree)
    • 附加到视觉树(AttachedToVisualTree)
    • 初始化完成(Initialized)
    • 加载完成(Loaded)

  • 控件在所在的Window 被关闭时的生命周期:

    • 从逻辑树分离(DetachedFromLogicalTree)
    • 从视觉树分离(DetachedFromVisualTree)

   视觉树和逻辑树案例说明:
  

  • Window1 中的StackPanel 下 有 Button 和 UserControl1
  • UserControl1 中的Border 下 有 TextBlock
  • 视觉树:到Window1 的Button 和 UserControl 为止
  • 逻辑树:细化到UserControl的 TextBlock 为止
  
结语

回到目录页: Avalonia 知识汇总
希望以上内容可以帮助到各人,如文中有不对之处,还请品评指正。

参考资料:
Avalonia中的Window 生命周期
Avalonia的UI组件

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

渣渣兔

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表