其他分享
首页 > 其他分享> > WPF 深入浅出 第一部分

WPF 深入浅出 第一部分

作者:互联网

WPF 深入浅出

目录

1 XAML概览

1.1 什么是XAML?

XAML是 WPF 技术中专门用于设计UI的语言

1.2 XAML 的优点

2 从零起步认识XAML

2.1 新建WPF项目

image-20220719161821473

​ 创建一个WPF桌面应用程序 会自动生成一些列文件 如下:

2.2 解析最简单的XAML代码

MainWindow.xaml 代码:

<Window x:Class="_001_xmal的认识.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:_001_xmal的认识"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" AutomationProperties.Name="MyFirstWpfApplication">
    <Grid>
        
    </Grid>
</Window>

写法: XAML 是 XML派生的,很多概念都通用 如果使用一个标签声明一个元素 如果标签没有内容可以 这样写

​ 为了表示同类标签中的某个标签与众不同,可以给他的特征(Attribute)赋值, 为特征赋值如下:

​ 在这里 有必要吧 Attribute 和 property 这两个词分辨一下 property 属于面向对象理论范畴 Attribute 是语言上的东西相关 ...

​ 他的总体结构是包裹 且里面有个 或者说 Grid标签是Window标签的内容,代表着一个窗口对象内嵌套这一个Grid对象

<Window>
	<Grid>
    
    </Grid>
</Window>

XAML是一种声明示语言,当你见到一个标签,就意味着声明了一个对象,对象之间的层级关系要么是并列,要么是包含

下面这些代码就是的标签的Attribute

<Window x:Class="_001_xmal的认识.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:_001_xmal的认识"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" AutomationProperties.Name="MyFirstWpfApplication">
</Window>

其中 Height Width Title AutomationProperties.Name 就是与Window 对象的 Property 相对应的

xmlns 是 (XML Namespace ) 的缩写, 作用是定义名称空间, 好处是 不同类重名时可以加名称空间来区分 xmlns特征的语法格式如下:

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

xmlns 后可以跟一个可选的映射前缀,之间用冒号隔开

如果没写映射前缀的话,那就意味着所有来自这个名称空间的标签 都不用加前缀,称为"默认名称空间"---- 默认名称空间只能有一个!!!! (应该使用 使用最频繁的标签命名空间作为默认命名空间)

上面例子中, 都是来自于第二行的命名空间

而第一行中的Class 特征则来自于第三行的x:前缀对应的名称空间

实验:我们把xmlns加个前缀n 然后添加标签

<n:Window x:Class="_001_xmal的认识.MainWindow"
        xmlns:n="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:_001_xmal的认识"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" n:AutomationProperties.Name="wqe" >
    <n:Grid>
        
    </n:Grid>
</n:Window>

重点: XAML 中引用外来程序集 和 c# 是不一样的 c# using就行 但是XAML需要添加到引用中,然后通过 xmlns:前缀="clr-namespace: 命名空间;assembly=xxx"

例如使用 button 类

<Window
        xmlns:b="clr-namespace:System.Window.Controls;assembly=PresentationFramework">
</Window>

默认引进的名称空间: http://schemas.microsoft.com/winfx/2006/xaml/presentation

 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 x:Class="_001_xmal的认识.MainWindow

上面的 xmlns 对应的名称空间 对应XAML语言解析处理相关的程序集

如果将 x:Class 改为其他类 或者 该XAML下同名.cs文件的 InitializeComponent() 注释 可能会出问题

但是App.xaml中 定义了 StartupUri="MainWindow.xaml" 他是在告诉编译器 吧MainWindow.xaml作为主窗体 ,只要能解析成一个窗体,那么程序就可以正常运行

如果注释 InitializeComponent() 修改 x:class="名称空间.其他类" 使用中间语言反编译器 可以看到 项目编译的程序集包含一个名为 其他类的类

重点: 这说明,x:Class 这个Attribute 的作用是当XAML 解析器 将包含他的标签解析成 c#类后,这个类的类名是啥

但是出现了一个问题 两个类重名了 注意看 partial 关键字 目的可以将 不同方法放到不同类中!将这个类一份为二 所以我们可以将 UI 和 逻辑分开

// 标注重点:
/*
	1.标签的定义
		空标签 和 非空标签 标签的Attribute 每一个标签代表一个对象
	2.名称空间
		xmlns="" 默认名称空间 只能有一个
		xmlns:x= "" 映射前缀
		xmlns:前缀="clr-namespace: 命名空间;assembly=xxx"  程序集的引入
		http://schemas.microsoft.com/winfx/2006/xaml/presentation 默认名称空间
		http://schemas.microsoft.com/winfx/2006/xaml  XMAL的解析 以及 x:Class 的解释
		partial 关键字
*/

3 系统学习 XAML语法

3.1 XAML 文档的树形结构

和 html 一样 是树形机构

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

在编译过程中 XAML 会为每个标签创建一个与之对应的对象,对象创建出来之后需要对他的属性初始化之后才更有意义

XAML 中为对象属性赋值共有两种语法:

下面我们以一个 标签的 Fill 为例 介绍两种方法

3.2.1 使用标签的 Attribute 为对象属性赋值

通过MSDN文档库可以查到,Rectangle.Fill 的类型是 Brush Brush是一个抽象类, 凡是以Brush为基类的类都可以为Fill进行赋值

Brush的派生类:

<Grid VerticalAlignment="Center" HorizontalAlignment="Center">
    <Rectangle x:Name="rectangle" Width="100" Height="100" Fill="Blue"/>
</Grid>
SolidColorBrush brush = new SolidColorBrush();
brush.Color = Colors.Orange;
this.rectangle.Fill = brush;

有个案例 我把XMAL改为c#了

// 渐变
LinearGradientBrush linearGradient = new LinearGradientBrush();

linearGradient.StartPoint = new Point(0, 1);
linearGradient.EndPoint = new Point(1, 1);

linearGradient.GradientStops.Add(new GradientStop(Colors.LightBlue, 0.2));
linearGradient.GradientStops.Add(new GradientStop(Colors.Blue, 0.7));
linearGradient.GradientStops.Add(new GradientStop(Colors.DarkBlue, 1.0));
this.rectangle.Fill = linearGradient;
    <Grid VerticalAlignment="Center" HorizontalAlignment="Center">
        <Rectangle x:Name="rectangle" Width="100" Height="100">
            <Rectangle.Fill>
                <LinearGradientBrush>
                    <LinearGradientBrush.StartPoint>
                        <Point X="0" Y="0"/>
                    </LinearGradientBrush.StartPoint>
                    <LinearGradientBrush.EndPoint>
                        <Point X="1" Y="1"/>
                    </LinearGradientBrush.EndPoint>

                    <LinearGradientBrush.GradientStops>
                        <GradientStopCollection>
                            <GradientStop Offset="0.2" Color="LightBlue"/>
                            <GradientStop Offset="0.7" Color="Blue"/>
                            <GradientStop Offset="1.2" Color="DarkBlue"/>
                        </GradientStopCollection>
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>
    </Grid>

LinearGradientBrush 的 GradientStops属性是一个 GradientStop的集合(GradientStopCollection) 即一系列的矢量渐变填充点,在这填充点之间,系统会自动进行差值预算,计算过度的彩色 填充矢量渐变的方向是 StartPoint 和 endPoint 两个属性 都是 Point 类型

3.2.2 标记扩展

有时候你会发现 你想给某Attribute 赋值 都会创建一个新的对象 但是如果使用的对象一样 或 一个对象赋值给两个属性,还有的时候需要给属性赋值Null 怎么搞?

所谓标记扩展 ,实际上是一种特殊的Attribute = Value 语法,其特殊的地方在于Value字符串是有一对 花括号及其括起来的内容组成

<StackPanel Background="LightSlateGray">
    <TextBox Text="{Binding ElementName=slider1,Path=Value,Mode=OneWay}" Margin="5"/>
    <Slider x:Name="slider1" Margin="5"/>
</StackPanel>

其中 Text="{Binding ElemnetName=slider1,path=Value,Mode=OneWay}" 就是标记扩展了

我们分析下这句代码:

Binding binding = new Binding(){Source=slider1,Mode=BindingMode.OneWay}

下面使用属性标签替换标记扩展

<StackPanel Background="LightSlateGray">
    <TextBox Margin="5">
        <TextBox.Text>
            <Binding ElementName="slider1" Path="Value" Mode="OneWay"/>
        </TextBox.Text>
    </TextBox>
    <Slider x:Name="slider1" Margin="5"/>
</StackPanel>

​ 不是所有类都能使用标记扩展 ,只有MarkupExtension的派生类可以使用 他的派生类不多:

注意:

标记扩展是可以嵌套的,例如 Text="{Binding Source={StaticResource myDataSource},Path=PersonName}" 是正确的语法

标记有简写语法 如: {Binding Value ...} === {Binding Path=Value}

标记扩展类的类名以 Extension 结尾 带有的可以省略不写 如: Text="{x:Static...}"

3.3 事件处理器与代码后置

XAML标签的 Attribute 对应着 Property 但是有些对应着 对象事件 Event

事件处理器

WPF支持在XAML里面为对象的事件指定处理器, 方法是使用事件处理器的函数名为对应的对象事件的Attribute进行赋值:

<ClassName EventName="EventHandlerName"></ClassName>

例如按钮:

<Button Content="事件" Click="Button_Click"/> 

如果翻译成c#代码

Button btn = new Button();
btn.Click += Btn_Click;

代码后置的意思就是 逻辑和ui分开

补充:如果想在XAML中用c#代码 可以使用 x:Code 标签 但是 x:Code的内容一定要使用XML的<![CATA[....]]>

<Button Content="事件" Click="Button_Click"/>
<x:Code>
    <![CDATA[
                private void Button_Click(object sender,RoutedEventArgs e){
                    MessageBox.Show("asdfasdf");
                }
            ]]>
</x:Code>

3.4 导入程序集和引用其中的名称空间

把类库引用到项目中是引用其中名称空间的物理基础,无论是c#还是XAML都是这样

一旦引入成功,就能使用其名称空间

架设我们使用类库程序集为 MyLibray.dll 其中包括 Common和 Controls两个名称空间 那么XAML中引用语法是:

xmlns:映射前缀="clr-namespace=:名称空间,assembly=类库名"
xmlns:Common="clr-namespace=:Common,assembly=MyLibray"
xmlns:Controls="clr-namespace=:Controls,assembly=MyLibray"

一旦引入成功 就可以使用其语法

<映射名:类名></映射名:类名>
<Common:MessagePanel/>

c# 也可以像xaml一样引用 using Cmn = Common;

3.5 XAML的注释

<!---->
/*
总结:
	xaml 标签的两种给属性值的方式 一个是对象 一个是字符串 对象的时候需要在 父标签内容中写属性的标签
	扩展标记 {}   
	事件 EventName=""  例如 click="函数名"
	程序集的引用   xmlns:映射前缀="clr-namespace:名称空间,assembly=程序集" 前提先引入
	xaml的注释 <!---->
*/

4 x名称空间的详解

x字符可以随便改,只是我们修改的名称罢了 ,x名称空间里的成员(如 x:Class x:Name) 是专门给xaml编译器看的,用来引导xaml编译器把xaml代码转换为CLR代码

4.1 x名称空间里都有什么

x包含的均匀解释XAML语言相关,所以可以称之为XAML名称空间

x里面的参数可以告诉 编译器 编译结果与那个c#类结合,访问级别等

我们可以看到 分为三大类: Atterbute 标签扩展 XAML指令元素 下面我们分别说下他们

4.2 x名称空间中Attribute

4.2.1 x:Class

这个Atttribute的作用是告诉XAML编译器将XAML标签的编译结果与后台代码中指定类合并,使用注意事项:

4.2.2 x:ClassModifier

这个Attribute的作用是告诉XAML编译由标签编译生成的类具有怎样的访问控制级别

注意:

4.2.3 x:Name

x:Name的作用有两个:

当一个 标签有 Name(FrameworkElement)的时候 Name 和 x:Name 都是一样的

4.2.4 x:FieldModifier

用于改变 x:Name 对应的 访问级别

<StackPanel x:Name="stackPanel" x:FieldModifier="public" Background="LightSlateGray">

只能改变变量的访问级别,前提要有一个x:Name

4.2.5 x:Key

最自然的检索方式莫过于使用"Key-Value"对的形式了, 在XAML文件中,我们可以把很多需要多次使用的内容提取出来放在资源字典中(Resource Dictionary)里,需要这个资源的时候可以 用key提取出来

例如我们在资源字典添加一个字符串

<Window x:Class="_002_标记扩展.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:_002_标记扩展"
        mc:Ignorable="d"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <sys:String x:Key="myString">
            Hello WPF Resource!
        </sys:String>
    </Window.Resources>
    <StackPanel x:Name="stackPanel" x:FieldModifier="public" Background="LightSlateGray">
        <TextBlock Text="{StaticResource ResourceKey=myString}" Margin="5"/>
    </StackPanel>
</Window>

c# 也能拿到资源

private void Button_Click(object sender, RoutedEventArgs e)
{
    string str = this.FindResource("myString") as String;
    this.button.Content = str;
}

4.2.6 x:Shared

当我们把某些对象当做资源放进去 取出来的时候是对象本身还是对象副本呢

4.3 x名称空间中的标记扩展

4.3.1 x:Type

MyButton xaml

<Window x:Class="_002_标记扩展.MyWindow"
        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:_002_标记扩展"
        mc:Ignorable="d"
        Title="MyWindow" Height="170" Width="200">
    <StackPanel>
        <TextBox Margin="5"/>
        <TextBox Margin="5"/>
        <TextBox Margin="5"/>
        <Button Content="OK" Margin="5"/>
    </StackPanel>
</Window>

MyWindow

public class MyButton:Button{

    public Type userWindowType { get; set; }

    protected override void OnClick()
    {
        base.OnClick();
        Window win = Activator.CreateInstance(this.userWindowType) as Window;
        win?.ShowDialog();
    }
}

主窗口

<local:MyButton userWindowType="{x:Type TypeName=local:MyWindow}" Margin="5" Content="show2" Click="MyButton_Click"/>

x:Type 标记扩展具有与 C# 中的 typeof() 运算符或 Microsoft Visual Basic 中的 GetType 运算符类似的功能。

userWindowType 通过x:type 修改了 类型为 MyWindow 所以显示的也是MyWindow

然后点击click后处理代码 代码显示窗口... x:type 标记扩展获取数据类型

4.3.2 x:Null *

重点是 key的访问方式

在xaml中 用来表示空值的是x:Null

<Window x:Class="WpfApp1.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:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
            <Setter Property="Width" Value="60"/>
            <Setter Property="Height" Value="36"/>
            <Setter Property="Margin" Value="5"/>
        </Style>
    </Window.Resources>
    <StackPanel>
        <Button Content="OK"/>
        <Button Content="OK"/>
        <Button Content="OK"/>
        <Button Content="OK" Style="{x:Null}"/>
    </StackPanel>
</Window>

<Button>
    <Button.Style>
    	<x:Null/>
    </Button.Style>
</Button>

4.3.4 x:Array

如果想在XAML文档里声明一个包含数据的X:array实例,必须使用标签声明才能做到

x:Array的作用就是通过他的Items属性向使用者暴露一个类型已知的 ArrayList实例,ArrayList内成员类型由: x:Array 的type指明

在WPF中把包含数据的对象称为 Data Source 如果想把 x:Array 当做一个数据向一个ListBox提供数据

<Window x:Class="WpfApp1.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:sys="clr-namespace:System;assembly=mscorlib" 
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>

        <ListBox Margin="5" Height="300">
            <ListBox.ItemsSource>
                <x:Array Type="sys:String">
                    <sys:String>hello</sys:String>
                    <sys:String>hello</sys:String>
                    <sys:String>hello</sys:String>
                    <sys:String>hello</sys:String>
                </x:Array>
            </ListBox.ItemsSource>
        </ListBox>
        
        
    </StackPanel>
</Window>

4.3.5 x:Static

他的功能是在xaml文档中使用数据类型的static成员

4.4 XAML指令元素

有一个类叫做 xmlDataProvider实例

<Window.Resources>
    <XmlDataProvider x:Key="InventoryData" XPath="?">
        <x:XData>
            <supermaket xmlns="">
                <Fruits>
                    ...
                    ..
                </Fruits>
            </supermaket>
        </x:XData>
    </XmlDataProvider>
</Window.Resources>

5 控件与布局

5.1 控件

日常我们打交道最多的控件无外乎6类,即

image-20220725092651160

5.2 WPF的内容模型

WPF UI元素可以分为: 11个

名称 注释
ContentControl 单一内容控件
HeaderedContentControl 带标题的单一内容控件
ItemsControl 以条目集合为内容的控件
HeaderedItemsControl 带标题的以条目集合为内容的控件
Decorator 控件装饰元素
Panel 面板类元素
Adorner 文字点缀元素
Flow Text 流式文本元素
TextBox 文本输入框
TextBlock 静态文字
Shape 图形元素

5.3 各类内容模型详解

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

5.3.1 ContentControl 族

本族元素的特点如下:

如何理解 只能由单一元素充其当内容 这句话? 就是内容只能有一个 ..... 但是内容也可以是控件...

ContentControl族控件包括

1 1 1 1
Button ButtonBase CheckBox ComboBox
ContentControl Frame GridViewColumnHeader GroupItem
Label ListBoxItem ListViewItem NavigationWindow
RadioButton RepeatButton ScrollViewer StatusBarItem
ToggleButton ToolTip UserControl Window

5.3.2 HeaderedContentControl族

本族元素特点如下:

Expander GroupBox HeaderedContentControl TabItem
<GroupBox Margin="10" BorderBrush="Gray" Height="80" Width="200">
    <GroupBox.Header>
        <Image Source="C:\Users\DSF-LSJ\Pictures\logo.ico" Width="20" Height="20"/>

    </GroupBox.Header>

    <TextBlock TextWrapping="WrapWithOverflow" Margin="10" Text="床前明月光,疑是地上霜,举头望明月,低头思故乡"/>
</GroupBox>

5.3.3 ItemsControl族

本族元素特点如下:

1 1 1 1
Menu MenuBase ContextMenu ComboBox
ItemsControl ListBox ListView TabControl
TreeView Selector StatusBar
<ListBox Margin="5">
    <CheckBox Content="Time"/>
    <CheckBox Content="Time"/>
    <CheckBox Content="Time"/>
</ListBox>

书70页有写 怎么获取ui树的

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

        List<student> newList = new List<student>()
        {
            new student(){id=1,name="hello1"},
            new student(){id=2,name="hello2"},
            new student(){id=3,name="hello3"},
            new student(){id=4,name="hello4"}
        };

        this.testListBox.DisplayMemberPath = "name";
        this.testListBox.SelectedValuePath = "id";
        this.testListBox.ItemsSource = newList;
    }
}

public class student
{
    public int id { get; set; }
    public string name { get; set; }
}
 <ListBox x:Name="testListBox"/>

DisplayMemberPath 告诉 listbox显示那条属性

SelectedValuePath listbox.SelectValue 的时候显示

理解了ListBox的自动包装机制后 我把全部ItemsControl 对应的Item Contatiner列在下面

ItemsControl名称 对应的 item Container
ComboBox ComboBoxItem
ContenxtMenu MenuItem
ListBox ListBoxItem
ListView ListViewItem
Menu MenuItem
StatusBar StatusBarItem
TabControl TabItem
TreeView TreeViewItem

5.3.4 HeaderedItemsControl 族

顾名思义,都有itemsControl的特性 但是还可以有标题

只是多个一个 Header属性

MenuItem TreeViewItem ToolBar
MenuItem TreeViewItem ToolBar

5.3.5 Decorator 族

本族中的元素是在UI上起装饰效果,如 可以使用border元素为一些组织在一起的内容添加个边框,如果需要组织在一起的内容能够自由缩放,则可以使用ViewBox元素

ButtonChrome ClassicBorderDecorator ListBoxChrome SystemDropShadowChrome
Border InkPresenter BulletDecorator ViewBox
AdornerDecorator

5.3.6 TextBlock 和 TextBox

TextBlock只能显示文本 不能编辑,所以叫做静态文本,

TextBox 允许用户编辑

5.3.7 Shape族元素

这类元素没有自己的内容,我们可以使用Fill属性为他们的填充效果,还可以使用Stroke 属性设置他们的边界线效果

5.3.8 Panel族元素

Canvas DockPanel Grid TabPanel
ToolBarOverflowPanel StackPanel ToolBarPanel UniformGrid
VirtualizingPanel VirtualizingStackPanel WrapPanel

..

5.4 UI布局(Layout)

WPF布局元素有一下几个:

5.4.2 Grid

使用场合:

  1. 定义Grid的行与列

    Grid 类具有 ColumnDefinitions 和 RowDefinitions 两个属性 他们分别是 ColumnDefinition 和 RowDefinition 的集合,表示了Grid定义了多少列和多少行

    两行三列:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
    </Grid>
    

    设置 行高 和 列宽

    单位:

    英文名称 中文名称 简写 换算
    Pixel 像素 px 默认单位 图像基本单位
    Inch 英寸 in 1inch = 96pixel
    Centimeter 厘米 cm 1cm=(96/2.54)pixel
    Point pt 1pt=(96/72)pixel
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="50px"/>
            <RowDefinition Height="50px"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="40"/>
            <ColumnDefinition Width="1in"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
    </Grid>
    

    他的值我们可以设置三类

    • 绝对值 数值后面加单位
    • 比例值 数值后面加*****号 (他会把所有值加起来当分母 , 然后当个值做分子)
    • 自动类型 填写 Auto字符串
  2. 使用Grid进行布局

    <Window x:Class="_005_布局.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:_005_布局"
            mc:Ignorable="d"
            Title="MainWindow" Height="400" Width="400" >
        <Grid ShowGridLines="False" 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.Row="0" Grid.Column="1" Grid.ColumnSpan="4"/>
            <TextBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="5" BorderBrush="Black"/>
            <Button Content="提交" Grid.Row="4" Grid.Column="2"/>
            <Button Content="取消" Grid.Row="4" Grid.Column="4"/>
        </Grid>
    </Window>
    
    

5.4.3 StackPanel

三个属性:

属性名称 数据类型 可取值 描述
Orientation Orientation枚举 Horizontal
Vertical
决定内部元素是横向累计还是纵向累积
HorizontalAlignment HorizontalAlignment枚举 Left
Center
Right
Stretch
决定内部元素水平方向向上对齐方式
VerticalAlignment VerticalAlignment枚举 Top
Center
Bottom
Stretch
决定垂直方向的对齐方式
<GroupBox Header="test" BorderBrush="Black" Margin="5">
    <StackPanel>
        <CheckBox Content="hello1"/>
        <CheckBox Content="hello1"/>
        <CheckBox Content="hello1"/>
        <CheckBox Content="hello1"/>
        <CheckBox Content="hello1"/>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
            <Button Content="确定" Width="60" Margin="5"/>
            <Button Content="取消" Width="60" Margin="5"/>
        </StackPanel>
    </StackPanel>
</GroupBox>

5.4.4 Canvas

他有 Canvas.XCnavas.Y属性

用处:

<Canvas HorizontalAlignment="Left" Height="270" Margin="36,47,0,0" VerticalAlignment="Top" Width="300">
    <TextBlock Canvas.Left="142" TextWrapping="Wrap" Text="TextBlock" Canvas.Top="100"/>
    <StackPanel Height="100" Canvas.Left="38" Canvas.Top="160" Width="100"/>
    <Label Content="Label" Canvas.Left="56" Canvas.Top="52"/>
</Canvas>

5.4.5 DockPanel

DockPanel内的 元素 会附加上 DockPanel.Dock 这个属性 这个属性的数据类型是 枚举 Left Top Right 和 Bottom ,根据Dock的值,DockPanel内的元素会向指定方向累积,切分DockPanel内部的剩余可用空间,就像船舶靠岸一样

DockPanel还有一个重要属性---bool 类型的 LastChideFill 他默认是 True,当他为True的时候 DockPanel的最后一个元素 DockPanel.Dock 属性会被忽略,这个元素会把剩下的空间填充满

<DockPanel >
    <TextBox BorderBrush="Black" Height="25" Text="123" DockPanel.Dock="Top"/>
    <TextBox BorderBrush="Black" Width="25" Text="123" DockPanel.Dock="Left"/>
    <TextBox BorderBrush="Black"/>
</DockPanel>
<Grid ShowGridLines="False" Margin="10" >
    <Grid.RowDefinitions>
        <RowDefinition Height="25"/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="150"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <TextBox Grid.ColumnSpan="3" BorderBrush="Black"/>
    <TextBox Grid.Row="1" BorderBrush="Black"/>

    <GridSplitter Grid.Row="1" Grid.Column="1"
                  VerticalAlignment="Stretch" HorizontalAlignment="Center"
                  Width="5" Background="Gray" 
                  ShowsPreview="True"/>

    <TextBox Grid.Row="1" Grid.Column="2" BorderBrush="Black"/>

</Grid>

5.4.6 WrapPanel

WrapPanel 内部采用的是流式布局, WrapPanel使用Orientation属性来控制流的延伸方向,使用 HorizontalAlignment和VerticalAlignment两个属性控制内部控件的对齐

在流延伸的方向上,WrapPanel 会排列尽可能多的控件,排不下的会新起一排继续排列

<WrapPanel>
    <Button Width="50" Height="50" Content="OK"/>
    <Button Width="50" Height="50" Content="OK"/>
    <Button Width="50" Height="50" Content="OK"/>
</WrapPanel>

标签:控件,元素,第一,标签,XAML,深入浅出,System,WPF,属性
来源: https://www.cnblogs.com/lddragon/p/16519626.html