深入浅出WPF学习笔记

深入浅出WPF学习笔记深入浅出 WPF 学习笔记

第一部分 深入浅出话XAML

第3章 系统学习XAML语法

3.2 XAML中为对象属性赋值的语法

3.2.4 标记扩展(Markup Extensions)
Text="{Binding ElementName=slider1,Path=Value,Mode=OneWay}" 

这句就是标记扩展

  • 当编译器看到这句代码时就会把花括号里的内容解析成相应的对象。
  • 对象的数据类型名是紧邻左花括号的字符串。
  • 对象的属性由一串以逗号连接的子字符串负责初始化(注意,属性值不再加引号)。
    尽管标记扩展的语法简洁方便,但并不是所有对象都能用标记扩展的语法来书写,只有MarkupExtension类的派生类(直接或间接均可)才能使用标记扩展语法来创建对象。MarkupExtension的直接派生类并不多,它们是:
    在这里插入图片描述
    在这里插入图片描述






第5章 控件与布局

5.1 控件与布局

日常工作做打交道最多的控件无外乎6类

名称 解释
布局控件 可以容纳多个控件或嵌套其他布局控件,用于在UI上组织和排列控件。Grid、StackPanel、DockPanel等控件都属此类,它们拥有共同的父类 Panel。
内容控件 只能容纳一个其他控件或布局控件作为它的内容。Window、Button等控件属于此类,因为只能容纳一个控件作为其内容,所以经常需要借助布局控件来规划其内容。它们的共同父类是ContentControl。
带标题内容控件 相当于一个内容控件,但可以加一个标题(Header),标题部分亦可容纳一个控件或布局。GroupBox、TabItem等是这类控件的典型代表。它们的共同父类是HeaderedContentControl。
条目控件 可以显示一列数据,一般情况下这列数据的类型相同。此类控件包括ListBox、ComboBox等。它们的共同基类是ItemsControl。此类控件在显示集合类型数据方面功能非常强大。它们的共同父类是ItemsControl。
带标题条目控件 相当于一个条目控件加上一个标题显示区。TreeViewItem、Menultem都属于此类控件。这类控件往往用于显示层级关系数据,结点显示在其Header区域,子级结点则显示在其条目控件区域。此类控件的共同基类是HeaderedItemsControl.
特殊内容控件 比如TextBox容纳的是字符串、TextBlock可以容纳可自由控制格式的文本、Image容纳图片类型数据……这类控件相对比较独立。

6类控件的派生关系如下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oYZymf4t-1639874773551)(C:/Users/gaoji/AppData/Roaming/Typora/typora-user-images/image-20211219084451897.png)]

5.2 WPF的内容模型

5.3 各类内容模型详解

我们把符合某类内容模型的UI元素称为一个族,每个族用它们共同基类来命名。

5.3.1 ContentControl 族

特点如下:

  • 均派生自ContentControl类
  • 他们都是控件(Control)
  • 内容属性的名称为Content
  • 只能由单一元素充当其内容
    在这里插入图片描述

5.3.2 HeaderedContentControl族

特点如下:

  • 它们都派生自HeaderedContentControl类,
    HeaderedContentControl是ContentControl类的派生类。

  • 它们都是控件,用于显示带标题的数据。
  • 除了用于显示主体内容的区域外,控件还具有一个显示标题(Header)的区域。
  • 内容属性为Content和 Header 。
  • 无论是 Content还是Header都只能容纳一个元素作为其内容。
    在这里插入图片描述

5.3.3 ItemsControl族

特点如下:

  • 均派生自ItemsControl类。
  • 它们都是控件,用于显示列表化的数据。
  • 内容属性为 Items或ItemsSource。
  • 每种ItemsControl都对应有自己的条目容器( Item Container)。
    在这里插入图片描述
    在这里插入图片描述




5.3.4 HeaderedItemsControl族

特点如下:

  • 均派生自HeaderedItemsControl类。
  • 它们都是控件,用于显示列表化的数据,同时可以显示一个标题。
  • 内容属性为Items、ItemsSource和 Header。
    本组控件只有三个:MenuItem、TreeViewItem、ToolBar

5.3.5 Decorator族
  • 均派生自Decorator类。
  • 起UI装饰作用。
  • 内容属性为Child。
  • 只能由单一元素充当内容。
    在这里插入图片描述

5.3.6 TextBlock和TextBox

这两个控件最主要的功能是显示文本。

  1. TextBlock 只能显示文本,不能编辑,所以又称静态文本。
  2. TextBox 则允许用户编辑其中的内容。TextBlock 虽然不能编辑内容,但可以使用丰富的印刷级的格式控制标记显示专业的排版效果。
  • TextBox不需要太多的格式显示,所以它的内容是简单的字符串,内容属性为Text。
  • TextBlock 由于需要操纵格式,所以内容属性是Inlines(印刷中的“行”),同时,TextBlock也保留一个名为Text的属性,当简单地显示一个字符串时,可以使用这个属性。
5.3.7 Shape族元素
  • 均派生自Shape类。
  • 用于2D图形绘制。
  • 无内容属性。
  • 使用Fill属性设置填充,使用Stroke属性设置边线。
5.3.8 Panel族元素
  • 均派生自Panel抽象类。
  • 主要功能是控制UI布局。
  • 内容属性为Children。
  • 内容可以是多个元素,Panel元素将控制它们的布局。
    在这里插入图片描述

5.4 UI布局(Layout)

5.4.1 布局元素
5.4.2 Gird
  • 可以定义任意数量的行和列,非常灵活。
  • 行的高度和列的宽度可以使用绝对数值、相对比例或自动调整的方式进行精确设定,并可设置最大和最小值。
  • 内部元素可以设置自己的所在的行和列,还可以设置自己纵向跨几行、横向跨几列。
  • 可以设置Children元素的对齐方向。

基于这些特点,Grid适用的场合有:

  • UI布局的大框架设计。
  • 大量UI元素需要成行或者成列对齐的情况。
  • UI整体尺寸改变时,元素需要保持固有的高度和宽度比例。
  • UI后期可能有较大变更或扩展。
1. 定义Gird的行与列
2. 使用Gird进行布局
<Window x:Class="demo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 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:local="clr-namespace:demo" mc:Ignorable="d" Title="留言板" Height="240" Width="400" MinHeight="200" MinWidth="340" MaxHeight="400" MaxWidth="600"> <Grid Margin="10"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" MinWidth="120"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="80"/> <ColumnDefinition Width="4"/> <ColumnDefinition Width="80"/>  
     Grid.ColumnDefinitions> <Grid.RowDefinitions > <RowDefinition Height="25"/> <RowDefinition Height="4"/> <RowDefinition Height="*"/> <RowDefinition Height="4"/> <RowDefinition Height="25"/>  
      Grid.RowDefinitions> <TextBlock Text="请选择您的部门并留言:" Grid.Column="0" Grid.Row="0" VerticalAlignment="Center"/> <ComboBox Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="4"/> <TextBox Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="5" BorderBrush="Black"/> <Button Content="提交" Grid.Column="2" Grid.Row="4" /> <Button Content="清除" Grid.Column="4" Grid.Row="4" />  
       Grid>  
        Window> 
5.4.3 StackPanel

StackPanel可以把内部元素在纵向或横向上紧凑排列、形成栈式布局,通俗地讲就是把内部元素像垒积木一样“撂起来”。垒积木大家都玩过,当把排在前面的积木块抽掉之后排在它后面的元素会整体向前移动、补占原有元素的空间。基于这个特点,StackPanel适合的场合有:

  • 同类元素需要紧凑排列(如制作菜单或者列表)。
  • 移除其中的元素后能够自动补缺的布局或者动画。
    StackPanel使用3个属性来控制内部元素的布局,它们是Orientation、HorizontalAlignment和VerticalAlignment,具体如表5-9所示。
    在这里插入图片描述




<Window x:Class="demo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 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:local="clr-namespace:demo" mc:Ignorable="d" Title="选择题" Height="190" Width="300"> <Grid Margin="10"> <GroupBox Header="请选择没有错别字的成语" BorderBrush="Black" Margin="5"> <StackPanel Margin="5" > <CheckBox Content="A. 迫不及待"/> <CheckBox Content="B. 首屈一指"/> <CheckBox Content="C. 陈词滥调"/> <CheckBox Content="D. 唉声叹气"/> <CheckBox Content="E. 不可理喻"/> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> <Button Content="清空" Width="60" Margin="5"/> <Button Content="确定" Width="60" Margin="5"/>       StackPanel>        StackPanel>         GroupBox>          Grid>           Window> 

效果图:在这里插入图片描述

5.4.4 Canvas
  • 一经设计基本上不会再有改动的小型布局(如图标)。
  • 艺术性比较强的布局。
  • 需要大量使用横纵坐标进行绝对点定位的布局。
  • 依赖于横纵坐标的动画
5.4.5 DockPanel
5.4.6 WrapPanel

WrapPanel内部采用的是流式布局。WrapPanel使用Orientation属性来控制流延伸的方向,使用HorizontalAlignment 和VerticalAlignment两个属性控制内部控件的对齐。在流延伸的方向上,WrapPanel会排列尽可能多的控件,排不下的控件将会新起一行或一列继续排列。

第二部分 游历WPF内部世界

第6章 深入浅出话Binding

6.2 Binding基础

public class Student: { 
    private string _name; public string Name { 
    get { 
    return _name; } set { 
    _name = value; } } } 

实现接口的Student类:

public class Student:INotifyPropertyChanged { 
    public event PropertyChangedEventHandler PropertyChanged; private string _name; public string Name { 
    get { 
    return _name; } set { 
    _name = value; //激发事件 if(this.PropertyChanged!=null) { 
    this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name")); } } } } 

经过这样一升级,当Name属性的值发生变化时 PropertyChanged事件就会被激发,Binding接收到这个事件后发现事件的消息告诉它是名为Name的属性发生了值的改变,于是就会通知Binding目标端的UI元素显示新的值。

public partial class MainWindow : Window { 
    Student stu; public MainWindow() { 
    InitializeComponent(); //准备数据源 stu = new Student(); //准备 Binding Binding binding = new Binding(); binding.Source = stu; binding.Path = new PropertyPath("Name"); //使用Binding连接数据源与Binding目标 BindingOperations.SetBinding(this.textBoxName, TextBox.TextProperty, binding); } private void Button_Click(object sender, RoutedEventArgs e) { 
    stu.Name += "Name"; } } 
  • 第一个参数用于指定 Binding的目标,本例中是this.textBoxName。
  • 与数据源的Path原理类似,第二个参数用于为 Binding 指明把数据送达目标的哪个属性。只是你会发现在这里用的不是对象的属性而是类的一个静态只读( static readonly)的DependencyProperty类型成员变量!这就是我们后面要详细讲述的与Binding 息息相关的依赖属性。其实很好理解,这类属性的值可以通过 Binding 依赖在其他对象的属性值上,被其他对象的属性值所驱动。
  • 第三个参数很明了,就是指定使用哪个Binding 实例将数据源与目标关联起来。
    在这里插入图片描述

6.3 Binding的源与路径

6.3.1 把控件作为Binding源与Binding标记扩展

下面的代码是把一个TextBox 的 Text 属性关联在了Slider 的 Value属性上。

<Window x:Class="demo_02.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 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:local="clr-namespace:demo_02" mc:Ignorable="d" Title="MainWindow" Height="110" Width="300"> <StackPanel> <TextBox x:Name="textBox1" Text="{Binding Path=Value, ElementName=slider1}" BorderBrush="Black" Margin="5"/> <Slider x:Name="slider1" Maximum="100" Minimum="0" Margin="5"/>  
     StackPanel>  
      Window> 

在这里插入图片描述

6.3.2 控制Binding的方向及数据更新
6.3.3 Binding的路径(Path)

尽管在XAML代码中或者Binding类的构造器参数列表中我们以一个字符串来表示 Path,但Path 的实际类型是PropertyPath。下面让我们看看如何创建Path 来应对各种情况。

  1. 最简单的情况就是直接把 Binding 关联在 Binding源的属性上。语法如下:
 
   
  

等效的C#代码

Binding binding =new Binding({ 
   Path=new PropertyPath("Value"), Source = this.sliderl}; this.textBox1.SetBinding(TextBox.TextProperty,binding); 

或者使用Binding的构造器简写为:

Binding binding - new Binding("Value""){ 
    Source = this.slider1}; this.textBox1.SetBinding(TextBox.TextProperty, binding); 
  1. Binding还支持多级路径(通俗地讲就是一路“点”下去)。比如,如果我们想让一个 TextBox显示另外一个TextBox的文本长度,我们可以写:
<StackPanel> <TextBox x:Name="textBox1" BorderBrush="Black" Margin="5"/> <TextBox x:Name="textBox2" Text="{Binding Path=Text.Length, ElementName=textBox1, Mode=OneWay)" BorderBrush="Black" Margin="5"/>  
     StackPanel> 

等效的C#代码

this.textBox2.SetBinding(TextBox.TextProperty, new Binding("Text.[3]"){ 
    Source = this.textBoxl,ModeBindingMode.OneWay }); 
6.3.4 “没有Path”的Binding

Binding源本身就是数据且不需要Path来说明。典型的string、int,无法指出通过哪个属性来访问这个数据,只需要将Path的值设置为“.”或干脆不写(在XAML中可以),在C#中不能省略

6.3.5 为Binding指定源(Source)的几种方法
6.3.6 没有Source的Binding—使用DataContext作为Binding的源
6.3.7 使用集合对象作为列表控件的ItemsSource

附:常用的方法属性

名称 含义
VerticalAlignment 竖直对齐方式枚举类型
HorizontalAlignment 水平对齐方式枚举
BorderBrush 边框颜色枚举类型
Visibility 可见性枚举
Opacity 不透明度,接受数值在0.0到1.0间
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/203295.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午10:08
下一篇 2026年3月19日 下午10:08


相关推荐

  • Java实现动态规划经典题目

    Java实现动态规划经典题目动态规划入门请看 DP 动态规划专题 一 动态规划基本模型前言 说明 关于动态规划的见解 动规和递归有很多相似的地方 最显著的特征可以说是阶段性 二者都有很明显的阶段划分 所以 声明好每一个阶段所需要做的事情以及阶段与阶段之间的转移可以说是重中之重了 这就涉及几个问题 第一 需要声明好方法 递归 或者数组 动规 具体的意义 所代表的作用 第二 需要说明好递归处理数据的方式 递归 或者是阶

    2026年3月16日
    1
  • redis 时间范围查询

    redis 时间范围查询这算是一种变相的在redis上面实现时间范围查询。我的使用场景介绍一下:redis在我们的项目里面是用来存储实体映射关系,比如user&gt;pc这种一度关联,会统计某一个用户在一段时间内总共有多少个关联关系;当前事件携带的关联关系是否是新的。…

    2022年6月18日
    29
  • java对sha1的解密_java 加密解密算法MD5/SHA1,DSA

    java对sha1的解密_java 加密解密算法MD5/SHA1,DSA通常 使用的加密算法比较简便高效 密钥简短 加解密速度快 破译极其困难 本文介绍了 MD5 SHA1 DSA DESede DES Diffie Hellman 的使用 第 1 章基础知识 1 1 单钥密码体制单钥密码体制是一种传统的加密算法 是指信息的发送方和接收方共同使用同一把密钥进行加解密 通常 使用的加密算法比较简便高效 密钥简短 加解密速度快 破译极其困难 但是加密的安全性依靠密钥保管的安全

    2026年3月17日
    2
  • 温度传感器 JUMO芯片铂电阻各型号优点

    温度传感器JUMO芯片铂电阻德国久茂Jumo品牌介绍:德国JUMOGmbH&KG公司成立于1948年,位于德国中部城市Fulda。公司经过六十多年的发展,已经成为欧洲著名的仪表制造厂商,公司主要致力于生产高质量的传感器、变送器及控制器,可提供工业温度、压力、湿度、液位、流量、pH值、电导率、氧化还原值的测量、控制及记录产品。坦泼秋尔(TPQE):德国久茂Jumo中国区唯…

    2022年4月6日
    44
  • freemarker的使用_freemarker

    freemarker的使用_freemarker相同的环境,jsp可以,Freemarker报错我的代码是:&lt;@ec.tableitems="moduleList"action="listModule.do"imagePath="../styles/system/&lt;@bean.messagekey=’SYSTEM.CSS’/&gt;/eXtremeComponents/images/*.gif"&gt;  …

    2022年8月20日
    10
  • 以太网帧格式及例子

    以太网帧格式及例子nbsp 很多人将局域网 LocalAreaNet LAN 和以太网 Ethernet 混为一谈 这个误解大概是因为和其他局域网技术比较起来 以太网技术使用得是如此普遍 发展得是如此地迅速 以至于人们将 以太网 当作了 局域网 的代名词 本节将讨论 局域网 和 以太网 二者之间的关系以及相关的一些基础知识 1 以太网概述 1973 年 施乐公司 Xerox 开发出了一个设备互连技术并将这项技术命名

    2026年3月18日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号