WPF复习知识点记录

由于近几年主要在做Web项目,客户端的项目主要是以维护为主,感觉对于基础知识的掌握没有那么牢靠,趁着这个周末重新复习下WPF的相关知识。

文章内容主要来自大佬刘铁锰老师的经典著作《深入浅出WPF》。

因为是复习,所以知识内容不会一一记录,如有需要了解更多可以看书中内容。

注意:博客中的代码示例我是以avalonia为UI框架写的。代码可能部分跟WPF的稍有不同。

1.从零起步认识XAML

1.什么是XAML

XAML(读作zaml)是WPF技术中专门用于设计UI 的语言

2.优点

  • 实现界面与代码的分离
  • 可以设计出专业的UI和动画
  • 基于XML的标记语言,简单易懂,结构清晰

3.XAML剖析

1.最简单的XAML代码

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
</Window>

这个示例中,Window是一个XAML元素,它表示窗口组件。xmlns属性定义了XML命名空间,即指明XAML所使用的命名空间。在这里,http://schemas.microsoft.com/winfx/2006/xaml/presentation是WPF的命名空间。

这个示例中的XAML代码只有一个Window元素,它是一个空的容器。可以在Window元素中添加其他界面元素,例如按钮、文本框等,来构建应用程序的用户界面。同样,可以在XAML中设置属性来更改元素的外观和行为。

2.property和attribute

先不说WPF中两个属性的定义,我们先看看对应一个类的对象。

1)属性是指类体里用get或set封装好的属性。属性是面向对象的理论范畴。比如说一个盒子,盒子的高度,长度,都是这个盒子的属性。在C#中实现的时候可以通过GET SET 封装。

2)特性是指应用于类,字段,方法,接口的进一步说明,用专业的术语就是给类,字段,方法,接口补充元数据,说的再白一点就是给它们打上标记,打了标记后编译器就知道如何来编译它。特性是属于编程语言层面的东西。比如2个相同的类,为了表示这2个类不完全相同或者有差异。这时候就要针对这两个类加一些特性。

[Serializable]                                   // 这是Attribute,打上该标记的类说明可以被序列化
class Order
{
protected internal Single Price { get; set; } // 这是Property [Obsolete("此方法已过时,请改用xxx.")] // 打上该标记说明此方法是过时的
public Single GetPrice()
{
return default(Single);
}
}

在看在XAML中:

Attribute 在XAML中的对于标签的属性特征,以下都是Window标签下的attribute

xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:AvaloniaMarkdown.ViewModels"
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="AvaloniaMarkdown.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
xmlns:md="clr-namespace:Markdown.Avalonia;assembly=Markdown.Avalonia"
Icon="/Assets/avalonia-logo.ico"
Title="AvaloniaMarkdown"

Property 在后台代码中针对对象的属性特征,对应的后端类的对象Text,就是一个 property:

private string _text="hello";
public string Text
{
get => _text;
set => this.RaiseAndSetIfChanged(ref _text, value);
}
private string _filePath;

3.xmlns 名称空间

xmlns[:可选的映射前缀]="名称空间"

用于引用外来程序集

xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:AvaloniaMarkdown.ViewModels"

没有映射前缀的是默认名称空间,默认名称空间只能有一个。

通过xmlns,我们可以直接使用这些CLR名称空间中的类型

4.partial关键字

XAML文件对应的.xaml.cs文件中的类的声明使用了partial关键字,可以把一个类拆分在多处定义,只要各部分代码不冲突即可,由于partial机制,我们实现逻辑代码留在.cs文件中,把UI元素相关代码分离出去。

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
} }

2.XAML语法

1.树形结构

<Window>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="10*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0"
Grid.Column="0" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="9*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" >
<Button>打开</Button>
<Button>保存</Button>
<Label/>
</StackPanel>
</Grid>
<TextBox Grid.Row="1" Grid.Column="0"/>
<md:MarkdownScrollViewer Grid.Row="1"
Grid.Column="1"/>
</Grid>
</Window>

XAML UI 框架是树状结构,以对象为根节点,一层一层往下包含。我们经常需要在这棵树上进行按名称查找元素、获取父子节点等操作。WPF使用VisualTreeHelper、LogicalTreeHelper来操作树。

2.x:Name

x:Name的作用:

  1. 告诉XAML编译器,带有x:Name的标签需要声明一个引用变量,变量名就是x:Name的值
  2. 将XAML标签对应的对象的Name属性也设为x:Name的值,并注册到UI树上,方便查找

2.x:Key

在资源字典(Resource Dictionary)中使用,构成其中的元素。资源(Resource )非常重要,存放需要重复使用的内容。

	<Application.Resources>
<Color x:Key="SystemAccentColor">rgb(155, 138, 255)</Color>
<Color x:Key="SystemAccentColorDark1">rgb(155, 138, 255)</Color>
<Color x:Key="SystemAltMediumLowColor">rgb(52, 53, 65)</Color>
<Color x:Key="ApplicationPageBackgroundThemeBrush">rgb(52, 53, 65)</Color>
<Color x:Key="ControlStrokeColorDefaultBrush">rgb(94, 95, 109)</Color>
</Application.Resources>

3.控件

1.ContentControl 单一内容控件

只能单一元素充当其内容。

例如:Button、Label等(具体看书中列表)

2.HeaderdContentControl

除了用于显示主体内容的区域外,控件还具有一个显示标题(header)的区域

例如:GroupBox、TabItem

3.ItemsControl

  • 显示列表化的数据
  • 内容属性为Items或ItemsSource
  • 每种ItemsControl都对应有自己的条目容器(Item Container)

例如:ListBox、TreeView

4.Decorator

在UI 上起装饰效果,比如可以使用Border元素为一些组织在一起的内容加个边框

例如:Border、ViewBox

5.TextBlock和TextBox

最常用的文本控件

  • TextBlock 用于显示文本,不能编辑
  • TextBox 允许编辑内容

6.Shape

绘制图形使用的元素

  • Fill 属性设置填充
  • Stroke 属性设置边线

7.Panel

所有的UI布局元素都属于这一族

Panel元素控制布局

包括:Canvas、Grid、StackPanel等

4.布局

WPF的UI形成的树形结构,我们称之为可视化树(Visual Tree)

控件框架形成的树形结构,我们称之为逻辑树(Logic Tree)

五种大类

  • Grid 网格面板
  • DockPanel 停靠面板
  • StackPanel 栈面板
  • WrapPanel 环绕面板
  • Canvas 精准定位

下面复习下它们的使用方法:

1.Grid

网格形式布局

1.CloumnDefinitions

定义多少列

2.RowDefinitions

定义了多少行

	<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="10*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0"
Grid.Column="0" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="9*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Classes="small" Margin="0,0,20,0" Command="{Binding UploadCommand}">打开</Button>
<Button Classes="small" Margin="0,0,20,0" Command="{Binding SaveCommand}">保存</Button>
<Label Content="{Binding FilePath}" Margin="0,0,20,0"/>
</StackPanel>
</Grid>

3.Grid长宽常用设置值

  • 绝对值:double 数值后加单位后缀
  • 比例值:double数值后加一个星号(*)(如上例)
  • 自动值:Auto

2.StackPanel

StackPanel可以把内部的元素在纵向或横向上紧凑排列,形成栈式布局

适合场合:

  • 同类元素需要紧凑排列(列表或菜单)
  • 移除其中的元素后能够自动补缺的布局或者动画

1.属性

常用属性 数据类型 可选值 说明
Orientation Orientation Horizontal(水平排列)\Vertical(垂直排列) 决定内部元素是水平还是垂直排列,默认值(Vertical)
Background Brush 背景色(Red/Yellow等等)
HorizontalAlignment HorizontalAlignment Center(中心)/Left(靠左)/Right(靠右)/Stretch(拉伸以填充父元素) 决定内部元素在水平方向的对齐方式
VerticalAlignment VerticalAlignment Top(上方)/Center(中心)/Bottom(下方)/Stretch(拉伸以填充父元素) 决定内部元素在垂直方向的对齐方式

3.Canvas

画布,可以使用Left、Top、Right、 Bottom。内部元素通过离上下左右的距离控制元素在布局中的位置。

4.DockPanel

DockPanel会对每个子元素进行排序,并停靠在面板的一侧,多个停靠在同侧的元素则按顺序排序,。

<Grid>
<DockPanel Width="Auto" Height="Auto">
<Button DockPanel.Dock="Left" >1</Button>
<Button DockPanel.Dock="Top">2</Button>
<Button DockPanel.Dock="Right">3</Button>
<Button DockPanel.Dock="Bottom">4</Button>
</DockPanel>
</Grid>

5.WrapPanel

流式布局,根据Orientation属性来设置其水平或垂直布局方向

默认是水平排列

<WrapPanel>
<Button />
<Button />
<Button />
<Button />
<Button />
<Button />
</WrapPanel>

垂直排列

<WrapPanel Orientation="Vertical">
</WrapPanel>

5.Binding 绑定

数据交互核心属性,在字段定义的set语句中使用一个PropertyChanged事件,,当为Binding设置了数据源后,就会自动侦听PropertyChanged事件

WPF

using CommunityToolkit.Mvvm

private string _searchKeyword;
public string SearchKeyword
{
get => _searchKeyword;
set => SetProperty(ref _searchKeyword, value);
}

Avalonia

using ReactiveUI;

private string _filePath;

public string FilePath
{
get => _filePath;
set => this.RaiseAndSetIfChanged(ref _filePath, value);
}

6.Dependency Property 依赖属性

依赖属性是一种本身没有可以没有值,能通过使用Binding从数据源获取值的属性。拥有依赖属性的对象称为“依赖对象”

特点包括:

  • 节省实例对内存的开销
  • 属性值可以通过Binding依赖在其他的对象上

7.Attached Property 附加属性

附加属性,被环境赋予的属性,作用是将属性与数据类型(宿主)解耦,让数据类型的设计更加灵活

	<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="10*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0"
Grid.Column="0" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="9*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" >
<Button>打开</Button>
<Button>保存</Button>
<Label/>
</StackPanel>
</Grid>
<TextBox Grid.Row="1" Grid.Column="0"/>
<md:MarkdownScrollViewer Grid.Row="1"
Grid.Column="1"/>
</Grid>

上面 TextBox 的Grid.Row,Grid.Column都是附加属性。

8.Route 和Event 路由事件

路由事件被激发后是沿着Visual Tree传递的,只有这样,“藏”在Templete里的控件才能把消息送出来。

9.Resource 资源

每个WPF的界面的元素都具有一个名为Resources的属性,这个属性继承自FrameWorkElement类,其类型为ResourceDictionary,用来存储资源。

	<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="/Assets/Lang/en-US.axaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </Application.Resources>

在使用资源时候分为静态资源(StaticResource)和动态资源(DynamicResource)

1.StaticResource

在程序载入内存时对资源一次性使用,之后就不再去访问这个资源了

 <TextBox Grid.Row="4"
Name="Editor3"
AcceptsReturn="True"
Text="{Binding Source={StaticResource VMLocator}, Path=EditorViewModel.Editor3Text,Mode=TwoWay}"
FontSize="{Binding Source={StaticResource VMLocator}, Path=EditorViewModel.EditorCommonFontSize}" />

2.StaticResource

程序运行过程中仍然会去访问资源

<Rectangle Name="PART_BottomRightCorner"
Fill="{DynamicResource DataGridScrollBarsSeparatorBackground}"
Grid.Column="2"
Grid.Row="2" />

10.Template 模板

1.ControlTemplate 控制器模板

<ControlTemplate>
<Border Name="DataGridBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto,*,Auto,Auto">
<DataGridColumnHeader Name="PART_TopLeftCornerHeader"
Theme="{StaticResource DataGridTopLeftColumnHeader}" />
<DataGridColumnHeadersPresenter Name="PART_ColumnHeadersPresenter"
Grid.Column="1"
Grid.Row="0" Grid.ColumnSpan="2" />
<Rectangle Name="PART_ColumnHeadersAndRowsSeparator"
Grid.Row="0" Grid.ColumnSpan="3" Grid.Column="0"
VerticalAlignment="Bottom"
Height="1"
Fill="{DynamicResource DataGridGridLinesBrush}" /> <DataGridRowsPresenter Name="PART_RowsPresenter"
Grid.Row="1"
Grid.RowSpan="2"
Grid.ColumnSpan="3" Grid.Column="0">
<DataGridRowsPresenter.GestureRecognizers>
<ScrollGestureRecognizer CanHorizontallyScroll="True" CanVerticallyScroll="True" />
</DataGridRowsPresenter.GestureRecognizers>
</DataGridRowsPresenter>
<Rectangle Name="PART_BottomRightCorner"
Fill="{DynamicResource DataGridScrollBarsSeparatorBackground}"
Grid.Column="2"
Grid.Row="2" />
<Image Source="/Assets/maskGrad.png"
Grid.Row="1" Grid.RowSpan="2" Grid.Column="0" Grid.ColumnSpan="4"
VerticalAlignment="Stretch"
HorizontalAlignment="Right"
Width="60"
Stretch="Fill"
IsHitTestVisible="False"
ZIndex="1" />
<ScrollBar Name="PART_VerticalScrollbar"
Orientation="Vertical"
Grid.Column="2"
Grid.Row="1"
Width="{DynamicResource ScrollBarSize}"
ZIndex="2" /> <Grid Grid.Column="1"
Grid.Row="2"
ColumnDefinitions="Auto,*">
<Rectangle Name="PART_FrozenColumnScrollBarSpacer" />
<ScrollBar Name="PART_HorizontalScrollbar"
Grid.Column="1"
Orientation="Horizontal"
Height="{DynamicResource ScrollBarSize}" />
</Grid>
<Border Name="PART_DisabledVisualElement"
Grid.ColumnSpan="3" Grid.Column="0"
Grid.Row="0" Grid.RowSpan="4"
IsHitTestVisible="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
CornerRadius="2"
Background="{DynamicResource DataGridDisabledVisualElementBackground}"
IsVisible="{Binding !$parent[DataGrid].IsEnabled}" />
</Grid>
</Border>
</ControlTemplate>

2.DataTemplate 数据模板

<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>

11.Style 风格

设计外观和行为动作

1.Setter 设置器

Setter 类的Property属性用来指明你想为目标的哪个属性赋值,Value属性则是你提供的属性值

<Style Selector="Grid Button">
<Setter Property="BorderBrush" Value="rgb(94, 95, 109)" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Padding" Value="10,0,10,2" />
<Setter Property="Height" Value="32" />
<Setter Property="CornerRadius" Value="6" />
<Setter Property="Margin" Value="0" />
<Setter Property="FontFamily" Value="avares://TmCGPTD/Assets/Lato-Regular.ttf#Lato" />
<Setter Property="Transitions">
<Transitions>
<BrushTransition Property="Background" Duration="0:0:0.2" />
</Transitions>
</Setter>
</Style>

上面的例子是针对 Grid ButtonStyle,使用了若干个Setter 来设置 Grid 中的Button的一些属性,这样,在程序中, Grid 中的Button就会具有统一的风格。

2.Trigger 触发器

当条件满足时会触发一个行为。

<Grid>
<TextBlock Text="raokun" Width="75" Height="20">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="blue" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>

上面的例子,是当鼠标移动在上面时,字体的颜色变成蓝色。

阅读如遇样式问题,请前往个人博客浏览: https://www.raokun.top
拥抱ChatGPT:https://ai.terramours.site
开源项目地址:https://github.com/firstsaofan/TerraMours

WPF复习知识点记录的更多相关文章

  1. C#知识点记录

    用于记录C#知识要点. 参考:CLR via C#.C#并发编程.MSDN.百度 记录方式:读每本书,先看一遍,然后第二遍的时候,写笔记. CLR:公共语言运行时(Common Language Ru ...

  2. spring mvc开发过程知识点记录

    给一个客户做的一个小项目,需求就是输入类似一个短网址http://dd.yy/xxxx然后跳转到另外一个域名下的图书文件.(实际很多短网址站都提供API供调用吧,不过客户需求是他自己建立一个短网址服务 ...

  3. javascript知识点记录(1)

    javascript一些知识点记录 1.substring,slice,substr的用法 substring 和slice 都有startIndex 和 endIndex(不包括endInex),区 ...

  4. JavaScript算法与数据结构知识点记录

    JavaScript算法与数据结构知识点记录 zhanweifu

  5. DB知识点记录

    DB知识点记录 分页 SqlServer:ROW_NUMBER () over (ORDER BY ID) AS RN, MySql:limit Oracle:ROWNUM AS RN 数据表的基本结 ...

  6. 【千纸诗书】—— PHP/MySQL二手书网站后台开发之知识点记录

    前言:使用PHP和MySQL开发后台管理系统的过程中,发现有一些通用的[套路小Tip],这里集中记录一下.结合工作中ing的后台业务,我逐渐体会到:除了技术知识外.能使用户体验好的“使用流程设计”积累 ...

  7. 计算机二级C语言选择题错题知识点记录。

    计算机二级C语言选择题错题知识点记录. 1,在数据流图中,用标有名字的箭头表示数据流.在程序流程图中,用标有名字的箭头表示控制流. 2,结构化程序设计的基本原则:自顶向下,逐步求精,模块化,限制使用g ...

  8. JavaEE期末复习知识点总结

    JavaEE期末复习知识点总结 Java企业应用开发环境 Maven的基础概念 Maven是一个项目管理工具,可以对 Java 项目进行构建.依赖管理 Maven仓库 Maven 仓库是项目中依赖的第 ...

  9. C# 知识点记录(持续更新中)

    从看C#入门经典开始系统的学习C#,本文主要记录学习过程中的一些知识点,也是我博客生涯的开始,比较重要成体系的部分会单重新写文章整理归纳. 1.一字不变的字符串 @字符 使转义序列不被处理,按照原样输 ...

  10. 年度巨献-WPF项目开发过程中WPF小知识点汇总(原创+摘抄)

    WPF中Style的使用 Styel在英文中解释为”样式“,在Web开发中,css为层叠样式表,自从.net3.0推出WPF以来,WPF也有样式一说,通过设置样式,使其WPF控件外观更加美化同时减少了 ...

随机推荐

  1. python实现微信自动发消息功能

    import timeimport uiautomation as autofrom uiautomation.uiautomation import Bitmapimport win32clipbo ...

  2. [NotePad++]NotePad++实用技巧

    2 应用技巧 2.1 匹配并捕获/截取 截取第1列的数据 截取前 "(.*)", "(.*)", "(.*)"\)\); 截取后: 2.2 ...

  3. NTP 4.2.6p5版本导致多个系统安全漏洞

    问题描述:通过漏洞扫描发现NTP 4.2.6p5版本导致多个系统漏洞,需要升级版本更高的ntp,一般刚开始都是yum直接装ntp包,现在需要重新卸载安装源码包 下载链接:http://distfile ...

  4. Python常见面试题017: Python中是否可以获取类的所有实例

    017. Python中是否可以获取类的所有实例 转载请注明出处,https://www.cnblogs.com/wuxianfeng023 出处 https://docs.python.org/zh ...

  5. 【Vue】二

    一个第三方js处理类库 BootCDN Vue过滤器 Date.now() 获取时间戳 Date.now() 1652411231222 计算属性实现 <body> <div id= ...

  6. ROS机器人摄像头寻线

    ROS机器人摄像头寻线 连接小车 注意:必须在同一区域网 ssh clbrobort@clbrobort 激活树莓派主板 roslaunch clbrobot bringup.launch 开启摄像头 ...

  7. Python LOG-日志

    LOG https://www.cnblogs.com/yyds/p/6901864.html logging logging模块提供模块级别的函数记录日志 包括四大组件 1. 日志相关概念 日志 日 ...

  8. 工作中,Oracle常用函数

    目录 1.序言 2.Oracle函数分类 3.数值型函数 3.1 求绝对值函数 3.2 求余函数 3.3 判断数值正负函数 3.4 三角函数 3.5 返回以指定数值为准整数的函数 3.6 指数.对数函 ...

  9. 学node 之前你要知道这些

    初识nodejs   19年年底一个偶然的机会接到年会任务,有微信扫码登录.投票.弹幕等功能,于是决定用node 来写几个服务,结果也比较顺利.   当时用看了下koa2的官方文档,知道怎么连接数据库 ...

  10. Yolov5 根据自己的需要更改 预测框box和蒙版mask的颜色

    1.首先找到项目中 utils/plots.py 文件,打开该代码 将原来的 Colors类注释掉(或删掉),改成如下Colors类 class Colors: def __init__(self): ...