界面布局

布局原则

不用显式的方式定义元素的尺寸。元素的尺寸尽量不要写死,这样可能更好的满足响应式,例如一下一个例子,我们有个国际化的需求,要求用户名中英文双语展示。如果一开始将用户名的长度设置成100时,用户名展示正常,似乎也没有什么问题。
image
现在将用户名改为国际化的username时,就会发现用户名展示不全的问题,这就是布局显式写死出现的问题。
image
如果未下写死的话,那么用户名就可以根据元素内容的实际长度来扩大缩小元素大小
image
image

布局控件

grid

可以将窗口按指定行和指定列进行切分,RowDefinitions 用于划分行,RowDefinitions中每一个RowDefinition表示一行,ColumnDefinitions表示列,ColumnDefinitions中每一个ColumnDefinition元素表示一列。

    <Grid>
        <Grid.RowDefinitions >
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions >
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
    </Grid>

如上代码就创建了4行4列。
image

还可以根据占比来设置指定行或列的高度宽度,如下所示
将列平均分为1 + 1 + 1 + 3 = 6块,然后前三列每行占一块,最后一列占3块。

        <Grid.RowDefinitions >
            <RowDefinition  Height="1*"/>
            <RowDefinition  Height="1*"/>
            <RowDefinition  Height="1*"/>
            <RowDefinition  Height="3*"/>
        </Grid.RowDefinitions>

设置后的展示效果如下图所示,最后一列明显是前三列的三倍。
image

如果长宽为auto的话,那么格子里的元素最大长宽是多少,那么这个就是多少。如下所示,将第一列设置auto后,按钮001设置宽为30,在单元格中会自动将格子撑开到30.

        <Grid.RowDefinitions >
            <RowDefinition  Height="auto"/>
            <RowDefinition  Height="1*"/>
            <RowDefinition  Height="1*"/>
            <RowDefinition  Height="3*"/>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions >
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Button Content="按钮001" Height="30" Grid.Row="0" />

image
也可以设置一个最小的宽带长度,如果大于这个最小的量那么就会被撑开,如果小于那么单元格大小就是这个最小的量。

如果想要指定元素放到指定格子中可以使用以下属性来指定
Grid.Column: 行
Grid.Row: 列
如果不填默认为0
如果想要放到第一行第一列可以使用以下代码,按钮就会显示在第一行第一列,如下图所示

        <Button Content="123" Grid.Column="1" Grid.Row="1"/>

image

可以设置元素跨行跨列多少个,如下所示将元素的 Grid.ColumnSpan和Grid.RowSpan都是设置成2,那么可以看到button元素行和宽各占了两个单元格

        <Button Content="123" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2" Grid.RowSpan="2"/>

image

StackPanel

可以将StackPanel中的元素按顺序从上到下或者从左到右进行排序
Orientation: 排序方式
- Vertical: 从上到下
- Horizontal: 从左到右
如下所示,如果我们将Orientation设置为Horizontal,那么就可以看到两个元素从左到右进行排序,如果未设置高度,那么默认占用整个高

        <StackPanel Orientation="Horizontal" >
            <TextBlock Text="用户名:" />
            <TextBox   Width="157"   />
        </StackPanel>

image

如果设置为Horizontal,那么就变成了从上到下排序了,和Horizontal一样,如果未设置宽度,那么默认占用整个宽度,如下图所示

        <StackPanel Orientation="Vertical" >
            <TextBlock Text="用户名:" />
            <TextBox   />
        </StackPanel>

image

StackPanel可以用来做工具栏,如下图所示,使用StackPanel从左到右排序即可。
image

DockPanel

用于设置DockPanel中的排列停靠位置
DockPanel属性:
- LastChildFill: 最后一个元素是否填充剩余所有空间
DockPanel下元素属性:
- DockPanel.Dock: 元素在DockPanel的停靠位置
- Left: 左
- Botton: 右
- Top: 头
- Right: 右
如下图所示,我想要创建一个按下面布局的管理页面,可以直接将元素停靠在指定位置即可。
image

    <DockPanel LastChildFill="True">
        <Border Height="30" Background="Aquamarine" DockPanel.Dock="Top"  />
        <Border Width="50" Background="BlanchedAlmond" DockPanel.Dock="Left" />
        <Border Height="50" Background="BurlyWood" DockPanel.Dock="Bottom"  />
        <Border Width="50" Background="Gainsboro" DockPanel.Dock="Right" />
        <Border  Background="Salmon" DockPanel.Dock="Bottom"  />
    </DockPanel>

image
需要注意的是需要指定元素的高度宽度才能停靠到指定位置,不然的话元素会占用所有空间。
还有要注意的是元素填充需要指定顺序,先到先得,如果下图所示,下面的border和右边的border替换顺序后它们的占用空间也会发送变化
右边的border在下面的border前设置会占用整个宽

    <DockPanel LastChildFill="True">
        <Border Height="30" Background="Aquamarine" DockPanel.Dock="Top"  />
        <Border Width="50" Background="BlanchedAlmond" DockPanel.Dock="Left" />
        <Border Width="50" Background="Gainsboro" DockPanel.Dock="Right" />
        <Border Height="50" Background="BurlyWood" DockPanel.Dock="Bottom"  />
        <Border  Background="Salmon" DockPanel.Dock="Bottom"  />
    </DockPanel>

image
如果调换顺序的话,那么下面的border则会占用右边border的宽

    <DockPanel LastChildFill="True">
        <Border Height="30" Background="Aquamarine" DockPanel.Dock="Top"  />
        <Border Width="50" Background="BlanchedAlmond" DockPanel.Dock="Left" />
        <Border Height="50" Background="BurlyWood" DockPanel.Dock="Bottom"  />
        <Border Width="50" Background="Gainsboro" DockPanel.Dock="Right" />
        <Border  Background="Salmon" DockPanel.Dock="Bottom"  />

    </DockPanel>

image

WrapPanel

可以按顺序从左往右排列或者从上往下排列,如果在进行排列时尺寸不够了,那么会进行换行

  • Orientation: 排列属性
    • Horizontal: 从左往右
    • Vertical: 从上到下、
      如下代码所示,我们在一个WrapPanel中新建了一批按钮列表,当第8个按钮放不下时,会自动换行放到第二行。
       <WrapPanel Orientation="Horizontal" >
           <Button Content="123" Width="100" />
           <Button Content="123" Width="100" />
           <Button Content="123" Width="100" />
           <Button Content="123" Width="100" />
           <Button Content="123" Width="100" />
           <Button Content="123" Width="100" />
           <Button Content="123" Width="100" />
           <Button Content="123" Width="100" />
           <Button Content="123" Width="100" />
           <Button Content="123" Width="100" />
           <Button Content="123" Width="100" />
       </WrapPanel>

image

UniformGrid

可以自动生成活指定一行行列数

  • Columns: 行
  • Rows: 列
    如果不指定行列,那么会自动按规则平均划分行列的,如下图所示,有16个按钮就会自动生成一个四行四列的表格
        <UniformGrid>
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
            <Button Height="100" Content="button" />
        </UniformGrid>

image
也可以指定每行和列要展示多少个元素,如下所示,指定2*5的顺序进行排列

        <UniformGrid Columns="2" Rows="5">
            <Button />
            <Button />
            <Button />
            <Button />
            <Button />
            <Button />
            <Button />
            <Button />
            <Button />
        </UniformGrid>

image
需要注意的是,如果指定的格子小于我们的元素数的话是会有部分元素无法展示的,
如下所示,我们设置的是2*2四个格子,在展示的时候只能展示4个格子,其余5个就没办法展示出来了

        <UniformGrid Columns="2" Rows="2">
            <Button />
            <Button />
            <Button />
            <Button />
            <Button />
            <Button />
            <Button />
            <Button />
            <Button />
        </UniformGrid>

image

Canvas

Canvas可以将元素设置到指定位置中指定位置中,如果不设置的话就是固定在0中,如下所示,在canvas中设置了三个button,但是他们都重合在了一起:

      <Canvas>
          <Button Content="btn1" />
          <Button Content="btn2" />
          <Button Content="btn3" />
      </Canvas>

image
可以使用Canvas.Bottom、Canvas.left、Canvas.right、Canvas.top来设置元素要设置到什么位置中,这个和margin类似,如果Canvas.top等于20的话,那么就是上空20个然后展示元素,其他也是一样,如下所示,在按钮中设置了 Canvas.Top="20" Canvas.Left="20"就会自动从上到下和从左到右各空20个空间。

        <Canvas>
            <Button Content="btn1" Canvas.Top="20" Canvas.Left="20"  />
            <Button Content="btn2" />
            <Button Content="btn3" />
        </Canvas>

image

InkCanvas

画板组件,可以在区域中进行画画或者选择组件拖动放大等功能。其他的top、left、right、bottom功能和Canvas一样不同的是组件前缀是InkCanvas.而不是Canvas.
EditingMode: 画笔模式
- Ink: 画笔,可以在组件上画画
- Select: 选择移动元素
- EraseByStroke: 整笔擦除
- EraseByPoint: 橡皮擦除

Ink画笔,如下所示:

    <Grid>
        <InkCanvas EditingMode="Ink" >
            <Button Content="btn01" />
            <Button Content="btn01" />
            <Button Content="btn01" />
            <Button Content="btn01" />
        </InkCanvas>
    </Grid>

image

Border

装饰控件,块元素,用于绘制边框,例如边框圆角,边框颜色等等。
属性:

  • BorderThickness: 变宽宽度
  • BorderBrush: 边框颜色
  • CornerRadius: 圆角程度
    如下代码所示,我grid创建了一个边框粗细为5,边框颜色为黑色,圆角为50单位的边框。
    <Border BorderThickness="5" BorderBrush="Black" Margin="5" CornerRadius="50" >
        <Grid>

        </Grid>
    </Border>

image

posted @ 2025-08-10 17:43  RainbowMagic  阅读(12)  评论(0)    收藏  举报