Avalonia 学习笔记06. Page Layout(页面布局)

news/2025/9/23 19:42:36/文章来源:https://www.cnblogs.com/ggds/p/19107912

本节课程的目标是根据一个预先设计好的 UI 模型,使用 Avalonia XAML 来构建“设置”页面的结构。我们将重点放在如何使用 Grid 和 StackPanel 等布局控件来正确地放置元素,而将具体的样式(如颜色、字体、边框等)留到下一节课。这种将“结构”和“样式”分离的思路,是现代 UI 开发中的一个重要实践。

6.1 ViewModels\MainViewModel.cs

我们首先对 MainViewModel 做一个小修改,以解决 XAML 设计器中的一个预览问题。

using Avalonia.Svg.Skia;
using AvaloniaApplication2.Data;
using AvaloniaApplication2.Factories;
using AvaloniaApplication2.Views;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.DependencyInjection;namespace AvaloniaApplication2.ViewModels;public partial class MainViewModel : ViewModelBase
{private PageFactory _pageFactory;[ObservableProperty]private bool _sideMenuExpanded = true;[ObservableProperty][NotifyPropertyChangedFor(nameof(HomePageIsActive))][NotifyPropertyChangedFor(nameof(ProcessPageIsActive))][NotifyPropertyChangedFor(nameof(ActionsPageIsActive))][NotifyPropertyChangedFor(nameof(MacrosPageIsActive))][NotifyPropertyChangedFor(nameof(ReporterPageIsActive))][NotifyPropertyChangedFor(nameof(HistoryPageIsActive))][NotifyPropertyChangedFor(nameof(SettingsPageIsActive))]private PageViewModel _currentPage;public bool HomePageIsActive => CurrentPage.PageName == ApplicationPageNames.Home;public bool ProcessPageIsActive => CurrentPage.PageName == ApplicationPageNames.Process;public bool ActionsPageIsActive => CurrentPage.PageName == ApplicationPageNames.Actions;public bool MacrosPageIsActive => CurrentPage.PageName == ApplicationPageNames.Macros;public bool ReporterPageIsActive => CurrentPage.PageName == ApplicationPageNames.Reporter;public bool HistoryPageIsActive => CurrentPage.PageName == ApplicationPageNames.History;public bool SettingsPageIsActive => CurrentPage.PageName == ApplicationPageNames.Settings;/// <summary>/// 仅用于设计时 (Design-Time only constructor)。/// </summary>/// <remarks>/// 这个无参数的构造函数是专门为 XAML 设计器准备的。/// 因为我们引入了依赖注入,原来的构造函数需要一个 `PageFactory` 参数,/// 这是在程序“运行时”才由 DI 容器提供的。/// XAML 设计器在“设计时”无法提供这个参数,会导致预览失败。/// 通过添加这个无参数构造函数,并为 `CurrentPage` 设置一个默认页面(这里是 SettingsPageViewModel),/// 设计器就能够成功实例化 MainViewModel,从而正常显示 MainView 的预览界面。/// </remarks>public MainViewModel(){CurrentPage = new SettingsPageViewModel();}public MainViewModel(PageFactory pageFactory){_pageFactory = pageFactory;GoToHome();}[RelayCommand]private void SideMenuResize(){SideMenuExpanded = !SideMenuExpanded;}[RelayCommand]private void GoToHome(){CurrentPage = _pageFactory.GetPageViewModel(ApplicationPageNames.Home);}[RelayCommand]private void GoToProcess(){CurrentPage = _pageFactory.GetPageViewModel(ApplicationPageNames.Process);}[RelayCommand]private void GoToMacros(){CurrentPage = _pageFactory.GetPageViewModel(ApplicationPageNames.Macros);}[RelayCommand]private void GoToActions(){CurrentPage = _pageFactory.GetPageViewModel(ApplicationPageNames.Actions);}[RelayCommand]private void GoToReporter(){CurrentPage = _pageFactory.GetPageViewModel(ApplicationPageNames.Reporter);}[RelayCommand]private void GoToHistory(){CurrentPage = _pageFactory.GetPageViewModel(ApplicationPageNames.History);}[RelayCommand]private void GoToSettings(){CurrentPage = _pageFactory.GetPageViewModel(ApplicationPageNames.Settings);}
}

 

6.2 ViewModels\SettingsPageViewModel.cs

这是为“设置”页面创建的新的 ViewModel。我们在这里添加一些临时的示例数据,以便在 UI 上看到列表的显示效果。

using System.Collections.Generic;
using AvaloniaApplication2.Data;
using CommunityToolkit.Mvvm.ComponentModel;namespace AvaloniaApplication2.ViewModels;public partial class SettingsPageViewModel : PageViewModel
{// 使用 [ObservableProperty] 特性,CommunityToolkit.Mvvm 会自动为私有字段 `_locationPaths`// 生成一个名为 `LocationPaths` 的公共属性。// 这个属性会自动实现 INotifyPropertyChanged 接口,当它的值改变时,会通知 UI 更新。
    [ObservableProperty]private List<string> _locationPaths;public SettingsPageViewModel(){PageName = ApplicationPageNames.Settings;// TEMP: Remove// 在构造函数中,我们为 LocationPaths 初始化了一些临时的假数据。// 这使得我们在开发 UI 界面时,即使没有后端逻辑,也能看到列表的实际显示效果。// 这里使用了 C# 12 的集合表达式 `[...]` 和逐字字符串 `@""`,使代码更简洁。LocationPaths =[@"C:\Users\Luke\Downloads\TestActions",@"C:\Users\Luke\Documents\BatchProcess",@"X:\Shared\BatchProcess\Templates"];}
}

 

6.3 Views\SettingsPageView.axaml

这是本节课的核心,即“设置”页面的 XAML 结构代码。我们一步步将设计图分解为 XAML 控件。

<UserControl 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="clr-namespace:AvaloniaApplication2.ViewModels"mc:Ignorable="d" d:DesignWidth="1100" d:DesignHeight="900"Background="{DynamicResource PrimaryBackground}"Foreground="{DynamicResource PrimaryForeground}"x:DataType="vm:SettingsPageViewModel"x:Class="AvaloniaApplication2.Views.SettingsPageView"><!-- 为设计器提供数据上下文(DataContext)。这行代码告诉 XAML 设计器在预览时使用 `SettingsPageViewModel` 的一个实例作为数据源。这使得在设计器中可以看到数据绑定(如 ItemsSource="{Binding LocationPaths}")的效果。它只在设计时生效,不影响程序实际运行。--><Design.DataContext><vm:SettingsPageViewModel></vm:SettingsPageViewModel></Design.DataContext><!-- 页面根布局:一个2行2列的 Grid。- ColumnDefinitions="*, *": 定义两个宽度相等的列,它们会平分所有可用宽度。- RowDefinitions="Auto, *": 定义两行。第一行(头部)的高度由其内容决定(Auto),第二行(内容区)占据所有剩余的高度(*)。这是构建经典“头+体”布局的常用方式。--><Grid ColumnDefinitions="*, *" RowDefinitions="Auto, *"><!-- Header: 头部区域 --><!-- Grid.ColumnSpan="2" 让这个头部的 Grid 横跨两列 --><Grid Name="HeaderGrid" Grid.ColumnSpan="2"><!-- Grid 是一个很好的堆叠控件。这里我们将 Image 和 StackPanel 放在同一个单元格中,它们会重叠在一起,Image 在下,StackPanel 在上。- Image 的 Stretch="UniformToFill" 属性确保图片在保持自身比例的同时,填满整个容器区域,超出部分会被裁剪。--><Image Source="{SvgImage /Assets/Images/background-settings.svg}" Height="160" Stretch="UniformToFill"></Image><StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"><Label HorizontalAlignment="Center" Content="Settings"></Label><Label HorizontalAlignment="Center" Content="Version 3.0.0.2 Beta"></Label><Label HorizontalAlignment="Center" Content="Compiled Jul 07 2025"></Label></StackPanel></Grid><!-- Left side content: 左侧内容区 --><!-- - Grid.Column="0" Grid.Row="1" 将这个 StackPanel 放置在主 Grid 的第一列、第二行。- Spacing="10" 为 StackPanel 内的直接子元素(如此处的 General 和 Location 两个区域)之间添加 10 个单位的垂直间距。- Margin="15" 在 StackPanel 的四周添加 15 个单位的外边距,起到内边距的效果,让内容不至于贴边。--><StackPanel Grid.Column="0" Grid.Row="1" Spacing="10" Margin="15"><!-- General: “常规”设置区域 --><StackPanel><Label Content="General"></Label><!-- 使用一个嵌套的 Grid 来对齐左侧的描述文本和右侧的控件。- ColumnDefinitions="*, Auto": 左列占据所有剩余空间,右列宽度由其内容(按钮、复选框)决定。--><Grid ColumnDefinitions="*, Auto" RowDefinitions="Auto, Auto, Auto"><!-- Release license --><!-- TextBlock 用于显示长文本,因为它支持 TextWrapping="Wrap" 自动换行。Label 不支持。--><TextBlock TextWrapping="Wrap" Text="Remove license of BatchProcess from this machine and release the license back to the server ready to be transferred to another machine."></TextBlock><Button Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch"><StackPanel Orientation="Horizontal"><!-- &#xE2FE; 是一个图标字体的 Unicode 编码,用于显示图标 --><Label Classes="icon" Content="&#xE2FE;"></Label><Label Classes="akko" Content="Release License"></Label></StackPanel></Button><!-- Skip Files --><TextBlock Grid.Row="1" Grid.Column="0" TextWrapping="Wrap" Text="Skip files if only Open, Save (Optional) and Close are Valid actions."></TextBlock><CheckBox Grid.Row="1" Grid.Column="1"></CheckBox><!-- Duplicate Entries --><TextBlock Grid.Row="2" Grid.Column="0" TextWrapping="Wrap" Text="Allow duplicate entries of the same file in project list"></TextBlock><CheckBox Grid.Row="2" Grid.Column="1"></CheckBox></Grid></StackPanel><!-- Location: “位置”设置区域 --><StackPanel><Label Content="Location"></Label><Grid ColumnDefinitions="*, Auto"><StackPanel><TextBlock TextWrapping="Wrap" Text="Add or remove the locations to search for Reporter Templates, Macros, Actions and other custom files or templates."></TextBlock><TextBlock TextWrapping="Wrap" Text="All sub-directories will be searched automatically"></TextBlock></StackPanel><Button Grid.Column="1" HorizontalAlignment="Stretch"><StackPanel Orientation="Horizontal"><Label Classes="akko" Content="+ Folder"></Label></StackPanel></Button></Grid><!--使用 ListBox 来显示文件夹路径列表。- ItemsSource="{Binding LocationPaths}" 是核心的数据绑定语法,它将此列表的数据源绑定到 ViewModel 中的 `LocationPaths` 属性。- 选择 ListBox 而不是更基础的 ItemsControl,是因为 ListBox 自带了选中、悬停等交互效果和基本样式,方便后续功能开发。--><ListBox ItemsSource="{Binding LocationPaths}"></ListBox></StackPanel></StackPanel><!-- Right Side Content: 右侧内容区 --><StackPanel Grid.Column="1" Grid.Row="1" Spacing="10" Margin="15"><!-- SolidWorks Host --><StackPanel><Label Content="SolidWorks Host"></Label><TextBlock TextWrapping="Wrap">BatchProcess can work locally on the current machine, or on any machine accessibleover the network or even internet.<LineBreak /><LineBreak />Enter the machines IP address, network name or localhost for this machine.</TextBlock><ComboBox></ComboBox><Label Content="Connection established"></Label></StackPanel><!-- PDM Enterprise --><StackPanel Spacing="15"><Label Content="PDM Enterprise"></Label><TextBlock TextWrapping="Wrap" Text="If you are using PDM Enterprise enter the credentials below and test login. BatchProcess can then automatically handle checking in and out files from PDM Enterprise."></TextBlock><!-- 这里使用三列等宽的 Grid,是为了让三个输入框(ComboBox, TextBox, TextBox)平分横向空间。如果使用水平 StackPanel,它们只会各自占据所需宽度,无法实现均分拉伸的效果。--><Grid ColumnDefinitions="*, *, *"><ComboBox HorizontalAlignment="Stretch"></ComboBox><TextBox Grid.Column="1"></TextBox><TextBox Grid.Column="2"></TextBox></Grid><StackPanel Orientation="Horizontal"><Button Grid.Column="1" HorizontalAlignment="Stretch"><StackPanel Orientation="Horizontal"><Label Classes="icon" Content="&#xE23E;"></Label><Label Classes="akko" Content="Login"></Label></StackPanel></Button><Button Grid.Column="1" HorizontalAlignment="Stretch"><StackPanel Orientation="Horizontal"><Label Classes="icon" Content="&#xE094;"></Label><Label Classes="akko" Content="Refresh Vault"></Label></StackPanel></Button></StackPanel><Label Content="Connection Established"></Label></StackPanel><!-- Setting Cache --><StackPanel Spacing="15"><Label Content="Setting Cache"></Label><TextBlock TextWrapping="Wrap">Various settings are stored locally including Processes, Actions, Macros, Reports and History. <LineBreak /><LineBreak />If you are experiencing issues you can try clearing the cache (this won't remove the license).</TextBlock><StackPanel Orientation="Horizontal"><Button Grid.Column="1" HorizontalAlignment="Stretch"><StackPanel Orientation="Horizontal"><Label Classes="icon" Content="&#xEC54;"></Label><Label Classes="akko" Content="Clear Cache"></Label></StackPanel></Button><Button Grid.Column="1" HorizontalAlignment="Stretch"><StackPanel Orientation="Horizontal"><Label Classes="icon" Content="&#xE5DE;"></Label><Label Classes="akko" Content="Export Cache"></Label></StackPanel></Button><Button Grid.Column="1" HorizontalAlignment="Stretch"><StackPanel Orientation="Horizontal"><Label Classes="icon" Content="&#xE20C;"></Label><Label Classes="akko" Content="Import Cache"></Label></StackPanel></Button></StackPanel></StackPanel></StackPanel></Grid>
</UserControl>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/913664.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

发表第一篇文章,谈谈对软件工程的理解

正文内容 软件工程(Software Engineering)是一门研究如何以工程化方法开发和维护高质量软件的综合学科。它不仅涵盖计算机科学的理论基础,还引入工程管理的思想,旨在在成本、进度与质量之间取得可度量的平衡。其核…

上海互联网做网站网站建设的基本流程有哪些

近期&#xff0c;苹果向部分ipad用户推送了iPadOS系统&#xff0c;据系统介绍&#xff0c;这是一款强大的操作系统&#xff0c;更能体现iPad的独特之处。iPadOS与IOS同源&#xff0c;针对iPad的大显示屏和多功能增加了全新和直观的强大功能。刚才小编给大家提到了部分iPad用户&…

龙华网站 建设深圳信科沃尔玛网上商城是正品吗

1.位置参数 2.默认参数 指向参数为不可变对象 3.可变参数 **args 一个列表list或是元组tuple 4.关键字参数 **kw,是一个字典dict 5.命名关键字参数 *, 转载于:https://www.cnblogs.com/aliy-pan/p/5198025.html

媒体查询做响应式网站娱乐建网站

导航一、方法计时器二、valid 参数校验的通用返回三、接口访问频次拦截&#xff08;幂等&#xff09;一、方法计时器 注解类&#xff1a;MethodTimer Target({ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) public interface MethodTimer { }处理器&#xff08;需…

国内h5网站欣赏专业制作网站哪家专业

概述 HashMap是我们常用的一种数据结构&#xff0c;他是一个key-value结构。我们来深入了解一下。 1.8之前用的数组加链表 1.8之后用的数组加链表加红黑树&#xff0c;当链表数量大于8时&#xff0c;将链表转为红黑树。当红黑书节点小于6又会转为链表。 浅析HashMap的put()方…

网站设计有创意的主题微信开发应用平台

随着工业AI、5G、边缘计算等前沿技术的迅速发展&#xff0c;未来工业正朝着大规模智能生产和柔性生产的方向稳步迈进。东土科技紧跟产业发展潮流&#xff0c;结合自身在工业底层控制技术、网络技术等方面的深厚积累&#xff0c;积极创新。 亮点带你看 鸿道操作系统&#xff0…

组织架构及营销网络网站优化培训中心

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 cs数模团队在亚太赛 APMCM前为大家提供了许多资料的内容呀&…

南磨房网站建设公司wordpress 文章

告诉你们一个震撼人心的消息&#xff0c;那个检测能力超强的 WAF——长亭雷池&#xff0c;他推出免费社区版啦&#xff0c;体验地址见文末。 八年前我刚从学校毕业&#xff0c;在腾讯做安全研究&#xff0c;看到宇森在 BlackHat 上演讲的议题 《永别了&#xff0c;SQL 注入》 …

重庆当地网站闵行专业做网站

文章目录 TDI网络过滤驱动应用1. 技术概览2. 数据包的抓取3. 应用实例3.1 TrafficShaper(限流)3.2 DnsRedirector(DNS重定向)3.3 TcpRedirector(TCP重定向) 4. 总结与参考 TDI网络过滤驱动应用 在前面的文章中&#xff0c;我们分析了TDI网络过滤驱动的基本开发框架以及TDI网络…

nRF54LM20A 芯片分析;

Nordic 宣布推出新一代nRF54L系列超低功耗无线系统级芯片 (SoC)的最新成员nRF54LM20A。nRF54L系列基于Nordic创新的22nm技术平台,不仅简化设计挑战,同时实现了可靠通信、更长的电池寿命和紧凑的产品设计。1、nRF54LM…

第二天

今天的编程小车课,完全是一场“找bug”的实战演练——小车一动不动地趴在桌上,我盯着线路板看了半天,连哪里出问题都不知道,从硬件、程序到设备状态,一步步拆解问题,瞬间清晰多了。 先查硬件连接时,我才发现L29…

wordpress做过的大型网站山东济南网站建设公司

【习题】保存应用数据 判断题 首选项是关系型数据库。 错误(False) 应用中涉及到Student信息&#xff0c;如包含姓名&#xff0c;性别&#xff0c;年龄&#xff0c;身高等信息可以用首选项来存储。 错误(False) 同一应用或进程中每个文件仅存在一个Preferences实例。 正确(T…

怎么样建设自己的网站上海科技网站建设

从这一讲开始&#xff0c;我们将一起探讨设计模式的性能调优。在《Design Patterns: Elements of Reusable Object-Oriented Software》一书中&#xff0c;有 23 种设计模式的描述&#xff0c;其中&#xff0c;单例设计模式是最常用的设计模式之一。无论是在开源框架&#xff0…

毕业设计h5网站制作贵阳好的网站建设公司

import React, { Component } from react;class List extends Component {constructor(props) {super(props);}render() {return <div>1111</div>;} }export default List;

网站流量查询网站统计查询网站建设需要写语句吗

PEP 8是最古老的PEP之一&#xff0c;它向Python程序员提供了代码格式设置指南。PEP 8的篇幅很长&#xff0c;但大都与复杂的编码结构相关。 https://python.org/dev/peps/pep-0008/转载于:https://www.cnblogs.com/botoo/p/7830980.html

教做甜点的网站换友情链接的网站

朴素的 f[S]表示S到(1<<n)的期望次数 发现1的个数只增加不减少 所以可以类似拓扑序的图&#xff0c;然后枚举子集O(3^n)转移 没有优化的余地 另辟蹊径&#xff1a; 拆开每一位来看 t[i]表示第i位变成1的次数 ansE(max(t[i])) 根据min-max容斥 得到&#xff1a;ans∑E(t[i…

海口智能建站价格国外服务器租用价格

Description 给你一个字符串str&#xff0c;字符串中的字母都已按照升序排序&#xff0c;且只包含小写字母。另外给出一个目标字母target&#xff0c;请你寻找在这一有序字符串里比目标字母大的最小字母。 在比较时&#xff0c;字母是依序循环出现的。例如&#xff0c;str“ab…

福田专门做网站推广公司做网站怎么回本

41、计算机操作的最小时间单位是__________。A A. 时钟周期 B. 指令周期 C. CPU周期 D. 外围设备 42、微程序控制器中&#xff0c;机器指令与微指令的关系是__________。B A. 每一条机器指令由一条微指令来执行 B. 每一条机器指令由一段用微指令编成…

Win10服务器远程连接断开后.bat脚本进程中断的全面解决高效的方案

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

NRF54L15 两者结合的jlink保护机制(硬件+软件)

默认更安全:只有当硬件和软件两层都“解锁”时,调试端口才开放。 典型流程: 上电/复位时,硬件先根据 UICR.APPROTECT 决定是否允许软件控制。 如果硬件允许,固件可通过写 APPROTECT.DISABLE 临时解锁调试端口(直…