WPF学习笔记——基础必要知识
WPF是干什么的?
使用 Windows Presentation Foundation (WPF),你可以创建适用于 Windows 且具有非凡视觉效果的桌面客户端应用程序。
Windows Presentation Foundation (WPF) 是一种演示框架,可用于开发以下类型的应用程序:
- 独立应用程序(传统风格的 Windows 应用程序,以可执行程序集的形式生成,安装在客户端计算机上并从客户端计算机上运行)。
- XAML browser applications (XBAPs)(由导航页面构成的应用程序,这些页面以可执行程序集的形式生成,由 Microsoft Internet Explorer 和 Mozilla Firefox 这类 Web 浏览器承载)。
- 自定义控件库(包含可重用控件的不可执行程序集)。
- 类库(包含可重用类的不可执行程序集)。
开发模式或特点
通常使用 XAML 标记实现应用程序的外观,同时使用托管编程语言,比如c#来实现其行为。 这种外观和行为的分离具有以下优点:
- 降低了开发和维护成本,因为特定于外观的标记与特定于行为的代码不紧密耦合。
- 开发效率更高,因为设计人员在实现应用程序外观的同时,开发人员可以实现应用程序的行为。
- WPF 应用程序的全球化和本地化 得以简化。
典型的 WPF 应用程序定义通过结合使用标记(XAML)和代码隐藏(c#)来实现。 这使您能够使用标记以声明方式设置应用程序的属性、资源以及注册事件,同时在代码隐藏中处理事件并实现特定于应用程序的行为。
WPF开发与web开发相比较:
web开发,HTML负责文档创建编写,定义了页面有什么;CSS对页面即HTML文档进行排版美化;JS处理用户交互即事件处理等。
WPF中,仅用XAML对窗口页面进行元素定义、布局和样式控制,相当于HTML+CSS,对于用户交互即事件的响应处理,则属于后端代码(比如c#编写相关事件处理),没有JS这种东西。
外观实现是在VS中拖拽控件并配合属性窗口完成,还是直接手巧代码?
visual studio中,WPF的布局完全可以用可视化的工具箱窗口和属性窗口,完成元素编辑和排版。工具箱窗口可以通过鼠标将目标控件拖到页面中,属性窗口可以对当前所选控件进行排版和美化以及事件交互的设置。缺点是:慢,巨慢。
建议:直接手敲XAML代码,忘掉拖拽和属性设计窗口。
如果第一次使用visual studio 开发WPF,或者没使用过winfrom或那样的拖拽式UI设计,建议阅读下这个:
使用 Visual Studio XAML 设计器 - Visual Studio (Windows) | Microsoft Docs
这篇文章介绍如何使用工具,和VS中各个窗口介绍的,即讲解工作区,工作环境,算是基础。
XAML标记
XAML (Extensible Application Markup Language)是一种基于 XML 的标记语言,以声明形式实现应用程序的外观。 通常用它创建窗口、对话框、页和用户控件,并填充控件、形状和图形。熟悉web前端开发的,这里可以理解成XAML就是HTML+CSS,和HTML一样,wpf中的XAML也规定了自己的标签(控件),但是样式是通过属性设置的,没有专门的CSS语法。
Windows Presentation Foundation (WPF) 实现 XAML 处理器实现并提供 XAML 语言支持。(注意:XAML 本身是一个比 WPF 更大的语言概念。)
以文本表示时,XAML 文件是通常具有 .xaml
扩展名的 XML 文件。
WPF中的xaml文件,每个标签或元素,都对应一个WPF程序集的类型。
属性元素语法
对于对象元素的某些属性,无法使用特性语法(比如:Background="Blue"),因为无法在特性语法的引号和字符串限制内充分地表达提供属性值所必需的对象或信息。 对于这些情况,可以使用另一个语法,即属性元素语法。下面举例两种写法,二者在UI效果上是等效的:
<!--特性语法(属性)-->
<Button Background="Blue" Foreground="Red" Content="This is a button"/>
<!--属性元素语法-->
<Button>
<Button.Background>
<SolidColorBrush Color="Blue"/>
</Button.Background>
<Button.Foreground>
<SolidColorBrush Color="Red"/>
</Button.Foreground>
<Button.Content>
This is a button
</Button.Content>
</Button>
属性元素开始标记的语法为 <TypeName.PropertyName>
,结束标记的语法为 </TypeName.PropertyName>
。
元素事件
特性语法还可用于事件成员,而非属性成员。 在这种情况下,特性的名称为事件的名称。 在 XAML 事件的 WPF 实现中,特性的值是实现该事件的委托的处理程序的名称。
<Button Click="Button_Click" >Click Me!</Button>
在标记中指定事件名称以及要使用的处理程序的名称,而在代码隐藏中定义实现处理程序的代码。
这点跟web开发很像,处理程序只不过不是JS,而是c#写的一个函数。
扩展标记
标记扩展是一个 XAML 语言概念。 用于提供特性语法的值时,大括号({
和 }
)表示标记扩展用法。 此用法指示 XAML 处理不要像通常那样将特性值视为文本字符串或者可转换为字符串的值。就是类似于值用变量的意思。
WPF 应用编程中最常用的标记扩展是 Binding
(用于数据绑定表达式)以及资源引用 StaticResource
和 DynamicResource
。 通过使用标记扩展,即使属性通常不支持特性语法,也可以使用特性语法为属性提供值。
<Border Style="{StaticResource PageBackground}">
这句代码中,表示style的值要用变量PageBackground表示的内容,大概可以这么理解。
XAML根元素和命名空间
PS:这一小节还不太清楚,可以先跳过,影响不大
一个 XAML 文件只能有一个根元素,这样才能同时作为格式正确的 XML 文件和有效的 XAML 文件。 对于典型 WPF 方案,可使用在 WPF 应用模型中具有突出意义的根元素(例如,页面的 Window 或 Page、外部字典的 ResourceDictionary 或应用定义的 Application)。
根元素还包含特性 xmlns
和 xmlns:x
。 这些特性向 XAML 处理器指示哪些 XAML 命名空间包含标记将其作为元素引用的后备类型的类型定义。 xmlns
特性明确指示默认的 XAML 命名空间。 在默认的 XAML 命名空间中,可以不使用前缀指定标记中的对象元素。 对于大多数 WPF 应用程序方案以及 SDK 的 WPF 部分中给出的几乎所有示例,默认的 XAML 命名空间均映射到 WPF 命名空间 http://schemas.microsoft.com/winfx/2006/xaml/presentation
。 xmlns:x
特性指示另一个 XAML 命名空间,该命名空间映射 XAML 语言命名空间http://schemas.microsoft.com/winfx/2006/xaml
。
下面列出了最常用的 x:
前缀编程构造:
- x:Key:为 ResourceDictionary(或其他框架中的类似字典概念)中的每个资源设置唯一的键。 在典型的 WPF 应用标记中的所有
x:
用法中,x:Key
可能占到 90%。 - x:Class:向为 XAML 页提供代码隐藏的类指定 CLR 命名空间和类名。 必须具有这样一个类才能支持每个 WPF 编程模型的代码隐藏,因此即使没有资源,也几乎总是能看到映射的
x:
。 - x:Name:处理对象元素后,为运行时代码中存在的实例指定运行时对象名称。 通常,经常为 x:Name 使用 WPF 定义的等效属性。 此类属性特定映射到 CLR 后备属性,因此更便于进行应用编程,在应用编程中,经常使用运行时代码从初始化的 XAML 中查找命名元素。 最常见的此类属性是 FrameworkElement.Name。 在特定类型中不支持等效的 WPF 框架级 Name 属性时,仍然可以使用 x:Name。 某些动画方案中会发生这种情况。
- x:Static:启用一个返回静态值的引用,该静态值不是与 XAML 兼容的属性。
- x:Type:根据类型名称构造 Type 引用。 用于指定采用 Type(例如 Style.TargetType)的特性,但属性经常具有本机的字符串到 Type 的转换功能,因此使用 x:Type 标记扩展用法是可选的。
附加属性和附加事件
XAML 指定了一个语言功能,该功能允许对任何元素指定某些属性或事件,而不管要设置属性或事件的元素的类型定义中是否存在该属性或事件。 该功能的属性版本称为附加属性,事件版本称为附加事件。
即,可以自定义属性和事件,具体怎么用,什么情况下用还太清楚
WPF内置控件
下面列出了内置的 WPF 控件:
- 按钮: Button 和 RepeatButton 。
- 数据显示: DataGrid 、 ListView 和 TreeView 。
- 日期显示和选择: Calendar 和 DatePicker 。
- 对话框: OpenFileDialog 、 PrintDialog 和 SaveFileDialog 。
- 数字墨迹: InkCanvas 和 InkPresenter 。
- 文档: DocumentViewer 、 FlowDocumentPageViewer 、 FlowDocumentReader 、 FlowDocumentScrollViewer 和 StickyNoteControl 。
- 输入: TextBox 、 RichTextBox 和 PasswordBox 。
- 布局: Border 、 BulletDecorator 、 Canvas 、 DockPanel 、 Expander 、 Grid 、 GridView 、 GridSplitter GroupBox Panel ResizeGrip Separator ScrollBar ScrollViewer StackPanel Thumb Viewbox VirtualizingStackPanel Window 、、、、 WrapPanel 、、、、、、、和。
- 媒体: Image 、 MediaElement 和 SoundPlayerAction 。
- 菜单: ContextMenu 、 Menu 和 ToolBar 。
- 导航: Frame 、 Hyperlink 、 Page 、 NavigationWindow 和 TabControl 。
- 选项: CheckBox 、 ComboBox 、 ListBox 、 RadioButton 和 Slider 。
- 用户信息: AccessText 、 Label 、 Popup 、 ProgressBar 、 StatusBar 、 TextBlock 和 ToolTip 。
很明显,这些东西跟HTML的标签是同一类东西。具体的标签都有哪些,参考:控件库 - WPF .NET Framework | Microsoft Docs
有些标签没有展示效果图,或者具体的使用示例,那这只有官方demo库搜下或者网上搜下了。
另外样式方面,标签有哪些适用的样式属性呢?然而,wpf官方文档并没有一个统一的介绍,只是在具体的控件介绍里,有列举了具体的属性列表,至于属性值可以有哪些?这些也可能根本没介绍。这点文档有点扯。
WPF Windows 概述
用户通过窗口与 Windows Presentation Foundation (WPF) 独立应用程序进行交互。 窗口的主要用途是承载可视化数据并使用户可以与数据进行交互的内容。独立 WPF 应用程序使用 Window 类来提供它们自己的窗口。
请必须阅读官方介绍:WPF Windows 概述 | Microsoft Docs
窗口和对话框
为了方便起见,还为了在应用程序中获得可重用性并保持一致的用户体验,WPF 公开了三个常用的 Windows 对话框:OpenFileDialog、SaveFileDialog 和 PrintDialog。
消息框是一种特殊的对话框,用于向用户显示重要的文本信息,并询问简单的“是/否/确定/取消”问题。 可以使用 MessageBox 类创建并显示消息框。
有关更多信息,请参见对话框概述。
导航
这里其实还不太清楚,估计控件库里有相关答案,比如类似web中的a标签啥的
为了便于导航,WPF 实现了下列功能:
- NavigationService,用于处理导航请求的共享导航引擎,由 Frame、NavigationWindow 和 XBAPs 使用以支持应用程序内部的导航。
- 用于启动导航的导航方法。
- 用于跟踪导航的生命周期并与之交互的导航事件。
- 使用日记记住后退和前进导航,也可以对日记进行检查和操作。
有关信息,请参见导航概述。
为了将用于导航的内容打包,WPF 提供了 Page 类。 可以通过使用 Hyperlink 以声明方式或通过使用 NavigationService 以编程方式从一个 Page 导航到另一个。WPF 使用日志记忆已从其进行导航的页面以及导航回到这些页面。
对于具有导航功能(使用 NavigationWindow 和 Frame)的独立应用程序或 XBAPs,Application 检测应用程序内的任何导航操作,并在适当的时候引发下列事件:
- Navigating
- Navigated
- NavigationProgress
- NavigationFailed
- NavigationStopped
- LoadCompleted
- FragmentNavigation
此外,Application 使任何类型的应用程序都能够使用 GetCookie 和 SetCookie 来创建、保存和检索 Cookie。
有关更多信息,请参见导航概述。
应用程序关闭
为了帮助您管理应用程序关闭,Application 提供了 Shutdown 方法、ShutdownMode 属性以及 SessionEnding 和 Exit 事件。
只能从具有 UIPermission 的应用程序调用 Shutdown。独立 WPF 应用程序始终具有该权限。但是,在 Internet 区域中的部分信任安全沙盒中运行的 XBAPs 不具有该权限。
布局
WPF布局控件
布局是调整元素在 UI 中的大小和位置的过程。创建用户界面时,按照位置和大小排列控件以形成布局。布局提供了放置 UI 元素的有序方式,还可在调整 UI 大小时管理这些元素的大小和位置。任何布局的一项关键要求都是适应窗口大小和显示设置的变化。 WPF 为你提供一流的可扩展布局系统,而不强制你编写代码以适应这些情况下的布局。
该布局系统通过基 WPF 类公开给子控件。 对于通用的布局(如网格、堆叠和停靠),WPF 包括若干布局控件:
Panel | 布局类型 | 说明 |
---|---|---|
Grid | 动态 | 定义一个区域,在此区域内,您可以在行和列中定位子元素。 |
DockPanel | 动态 | 定义一个区域,在此区域内,您可以在上、下、左、右各边缘排列和叠放子元素。 |
WrapPanel | 动态 | 自动按顺序排列子元素,在父容器的边缘处将内容移到下一行。 排序按照从上至下或从左至右的顺序进行,具体取决于方向是设置为水平还是垂直。 |
StackPanel | 动态 | 自动将子元素排列成一行,可沿水平或垂直方向。 |
UniformGrid | 动态 | 自动将子元素排列在行和列中。 行和列是均匀分布的。 如果元素无法容纳在一个单元格中,那么它会被截断。 |
Canvas | 绝对 | 定义一个区域,在此区域内,您可以使用坐标显式定位子元素。 |
以上控件请牢记。默认情况下,Grid
面板用作页面或窗体中的顶级布局容器。 可在顶级页面布局内添加布局面板、控件或其他元素。
使用什么控件布局,对性能是有影响的,毕竟布局系统涉及到元素位置大小的计算。相对简单的布局,Canvas性能明显高于更复杂的Panel如:Grid。
使用绝对定位和动态定位进行布局
在应用程序中创建窗口后,必须决定如何在该窗口上对控件进行布局。 您还必须决定当用户调整窗口的大小时,窗口上的控件的行为方式。 这些是绝对定位和动态定位的问题。
在应用程序中创建窗口后,您会设置它的大小以及该窗口上的控件的大小。 您必须决定当窗口和控件的内容发生更改时它们的行为方式。 例如,如果您向窗口中添加了一个标签控件,您可以指定当文本被翻译成另一种语言时标签的行为方式。 这些是动态调整大小的问题。
请必须阅读:使用绝对定位和动态定位进行布局 | Microsoft Docs
上面这篇文档,介绍了WPF中可用的布局控件,以及布局类型,以及布局相关的控件属性。
布局之可页面内横向或纵向调整大小
页面内创建可拖拽调整大小的效果,类似于表格的列宽可左右增大减小。
如何:用 GridSplitter 创建用户可调整大小的应用程序 | Microsoft Docs
样式
Style标签
图形与分辨率和设备均无关。 WPF 图形系统中的基本度量单位是与设备无关的像素(即 1/96 英寸),且不考虑实际屏幕分辨率,并为实现与分辨率和设备无关的呈现提供了基础。 每个与设备无关的像素都会自动缩放,以匹配呈现它的系统的每英寸点数 (dpi) 设置。
通过样式功能,开发人员和设计人员能够对其产品的特定外观进行标准化。 WPF 提供了一个强样式模型,其基础是 Style 元素。 下面的示例创建一个样式,该样式将窗口上每个 Button 的背景色设置为 Orange
:
<Window.Resources>
<!-- Style that will be applied to all buttons for this window -->
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Orange" />
<Setter Property="BorderBrush" Value="Crimson" />
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Margin" Value="5" />
</Style>
</Window.Resources>
在App.xaml中的的Application.Resources节点中的<Sytle>
标签,定义了应用于全局的元素的样式,即在此位置中,这些样式将应用到应用程序中的所有元素。
如何更改控件的外观
更改控件的外观以适应应用程序的外观,这是很常见的操作。 可以根据要达到的效果,通过执行以下操作之一来更改控件的外观:
- 更改控件的属性值。
- 为控件创建或应用 Style。
- 为控件新建 ControlTemplate。
下面介绍如何通过style标签来定义一组样式,具体如下
1、相当于CSS中的标签类型选择器(对某一类标签设置样式)
<!--A Style that affects all Label,相当于CSS中的标签类型选择器(对某一类标签设置样式)-->
<Style TargetType="Label">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="微软雅黑"/>
<Setter Property="FontSize" Value="12"/>
</Style>
2、相当于CSS的类型选择器组合类名选择器(如对,div.box 设置样式)
<Style BasedOn="{StaticResource {x:Type Label}}"
TargetType="Label"
x:Key="TitleText">
<Setter Property="FontSize" Value="18"/>
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
注意,里面的BaseOn
属性,表示该style中的样式结合了该属性值中指定的元素样式,即二者并集的意思。
3、定义一个统一的样式规则,但不指定元素类型,相当于CSS的类选择器(对应用某class的元素设置样式)
<Style x:Key="style1">
<Setter Property="Control.Background" Value="Yellow"/>
</Style>
注意:
如果 setter 集合中有多个具有相同 Property 属性值的 setter,则使用最后声明的 setter。 同样,如果为样式中的相同属性和直接在元素上设置了值,则直接在元素上设置的值优先。
这点和web中的HTML元素的CSS取值逻辑是相同的。
WPF样式中,具体都有哪些属性名称,以及属性相应的属性值可以是什么?
类别CSS,即都有哪些CSS属性,以及CSS属性可以对应哪些值?请接着往后看
别看了,其实官方文档没有一个对应表的,只能从标签介绍里找,或者直接在VS的属性窗口来看,这有点难受。
部署 WPF 应用程序 (WPF)
最最简单无脑的,直接右击启动项目,选择发布菜单,然后把目标文件夹压缩就好了。解压缩后,点击里面的EXE文件就安装运行了。
疑问点
- 新建项:窗口、页,二者的区别是什么
- 如何又在一个单独的窗口或页面写只适用于当前窗口或页面的样式??类似于HTML里的styel标签的作用
- 页面元素的事件名都有哪些?统一的有哪些?文档介绍在哪里?
- XAML元素能自定义属性和事件??像H5那样的自定义属性??
- 窗口间的切换传值是怎么搞的?或者它就最好知识单窗口程序?
学习过程记录—关键文档阅读记录
首先读了WPF介绍:WPF 介绍 | Microsoft Docs
第一个跟着做的教程:在 Visual Studio 2019 中创建第一个 WPF 应用-.NET Framework | Microsoft Docs
看了窗口介绍的文化:WPF Windows 概述 | Microsoft Docs
请必须阅读:使用绝对定位和动态定位进行布局 | Microsoft Docs
看了对控件设置样式的方法:控件 - WPF .NET Framework | Microsoft Docs