WPF 基础 - 控件与布局
阅读原文时间:2023年07月10日阅读:1

1. 数据驱动 UI

WPF 是数据核心、主动的,UI 从属数据并表达数据、是被动的;

不再是 UI 驱动数据,而是数据驱动 UI;

2. 控件的定义

控件、数据内容、行为(控件响应用户操作执行自己的方法或以事件的形式通知应用程序);

1)控件是数据和行为的载体;

2)所以关注控件时应该关注抽象的数据和行为而不是具体的形象,

3)比如符合"能展示内容并相应用户单击"这一抽象概念的 UI 元素都可以是 Button,而具体的样子完全可以通过 Style 和 Template 决定,checkbox 也不是因为有个 box 可以 check 才叫 checkbox。

3. 控件类型

  1. 布局控件:Grid、StackPanel、DockPanel、WarpPanel 等 Panel 的子类;

  2. 内容控件:只能容纳一个其他控件或布局控件作为它的内容。如 Window、Button 等 ContentControl 的子类;

  3. 带标题的内容控件:GroupBox、TabItem 等 HeaderedContentControl 的子类;

  4. 条目控件:显示一列数据,一般这列数据之间的类型一致;ListBox、ComboBox 等 ItemsControl 的子类;

  5. 带标题的条目控件:TreeViewItem、MenuItem 等 HeaderedContentControl 的子类;

    A11 B11

  6. 特殊内容控件:TextBox、TextBlock、Image

graph LR
DependencyObject-->Dispatcher
Visual-->DependencyObject
UIElement-->Visual
FrameworkElement-->UIElement
Panel-->FrameworkElement
Control-->FrameworkElement
TextBlock-->FrameworkElement
Image-->FrameworkElement
ContentControl-->Control
HeaderedContentControl-->ContentControl
ItemsControl-->Control
HeaderedItemsControl-->ItemsControl
TextBox-->Control

2.1 逻辑树、可视元素树

可视树:因为 WPF 有Content 的概念,使控件与控件之间可以存在包含关系,以窗体为根,整个 WPF 的 UI 才形成树形结构。

2.2 内容属性

不同控件的内容属性名称不一:Content、Child、Items、Children、Text;

Button.Content、StackPanel.Children、ListBox.Items。

2.3 各类内容模型详解

2.3.1 ContentControl 族

  • 内容属性:Content

  • 常用:

    Button、Window、Label、UserControl、

    ListBoxItem、ListViewItem、ComboBoxItem、

    RadioButton、ToggleButton、CheckBox、

    ToolTip、ScrollViewer、ContentControl;

  • 不常用:

    ButtonBase、GroupItem、RepeatButton、StatusBarItem、NavigationWindow、Frame、GridViewColumnHeader

2.3.2 HeaderedContentControl

  • 内容属性:Content、Header
  • 常用:TabItem、Expander、HeaderedContentControl
  • 不常用:GroupBox

2.3.3 ItemsControl

  • 内容属性:Items 或 ItemsSource

    每种 ItemsControl 都对应有自己的条目容器 Item Container,如 ListBox 的 Item Container 是 ListBoxItem,关键词:包装机制

  • 常用:

    ListBox、ListView、ComboBox、Menu、ContextMenu、ItemsControl、TabControl、TreeView、StatusBar

  • 不常用:

    MenuBase、Selector(ListBox、ComboBox、TabControl 等的父类)

2.3.3.1 ListBox
  • DisplayMemberPath、SelectedValue、SelectedValuePath、SelectedItem、SelectedItems

ItemsContorl

Item Container

ComboBox

ComboBoxItem

ListBox

ListBoxItem

ListView

ListViewItem

TabControl

TabItem

Menu

MenuItem

ContextMenu

MenuItem

TreeView

TreeViewItem

StatusBar

StatusBarItem

2.3.4 HeaderedItemsControl

内容属性:Items 或 ItemsSource、Header

常用:

MenuItem、TreeViewItem、ToolBar

2.3.5 Decorator 族

  • 内容属性: Child

    起 UI 装饰作用

  • 常用:

    Border、ViewBox

  • 不常用:

    ButtonChrome、ListBoxChrome、BulletDecorator、InkPresenter、AdornerDecorator、ClassicBorderDecorator、SystemDropShadowChome

2.3.6 TextBox、TextBlock

2.3.7 Shape 族

  • Path、Polygon、Polyline 等 Shape 子类;

  • Stroke 设置边线、Fill 设置填充;

  • 无内容属性;

  • 用于 2D 图形绘制。




Path:

起点命令 M,终点命令 Z(让头尾相连)

直线 L,水平直线 H,垂直直线 V,曲线 C、Q、S、T

椭圆 A

2.3.8 Panel 族

  • 内容属性:Children

  • 常用:

    Grid、StackPanel、DockPanel、WrapPanel、Canvas

  • 不常用:

    UniformGrid(Grid 简化版,定义几行几列,每个单元格大小一致)、TabPanel、ToolBarOverflowPanel、ToolBarPanel、VirtualizingPanel、VirtualizingStackPanel

2.3.8.1 Grid
  • Grid 共享尺寸属性 SharedSizeGroup 运用:

    1)将父级 Grid 的 Grid.IsSharedSizeScope 设置为 true;

    2)两个 Grid 各自某一行或某一列的 SharedSizeGroup 设置为同一个字符串,那么这两行或这两列就可以共享空间。

    <Grid x:Name="toolboxLayerGrid" Visibility="Collapsed">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="Auto" SharedSizeGroup="ToolboxGroup" />
        </Grid.ColumnDefinitions>
    &lt;GridSplitter Grid.Column="1" Width="3" HorizontalAlignment="Left" /&gt;
    &lt;Grid x:Name="toolboxGrid" Grid.Column="1" Margin="3,0,0,0"&gt;
    &lt;/Grid&gt;
    </Grid>

    toolboxLayerGrid.Visibility = System.Windows.Visibility.Visible;
    toolboxLayerGrid.SetValue(Grid.ZIndexProperty, 2);
    layer0Grid.ColumnDefinitions.Add(new ColumnDefinition { SharedSizeGroup = "ToolboxGroup" });

  • Grid 宽高接受的尺寸单位:Pixel(像素,默认单位)、Inch(英寸=96 piexl)、Centimeter(厘米=96/2.54 pixel)、Point(=96/72 pixel)

  • 如果把两个元素放在 Grid 的同一个单元格内,则后书写的元素将在先书写的元素之上,可以通过 Panel.ZIndex 值调整,值越大,越靠上。默认为 1.

2.3.8.2 StackPanel
  • Orientation 决定横向排列还是纵向排列;
  • 布局风格:垒积木
2.3.8.3 Canvas
  • Canvas.Top 、Canvas.Left;
  • 用于基本不改动、艺术性比较强、需要大量使用横坐标作为绝对定位、依赖横坐标的动画等场景;
  • 两个元素占据同一个位置时,跟 Grid 一样。
2.3.8.4 DockPanel
  • LastChildFill
2.3.8.5 WrapPanel
  • 流式布局,Orientation 默认 Horizontal:从左到右 从上到下。