天天看點

WPF入門03之布局元素

WPF布局原則—不應顯示設定大小

為了控件的大小可以自适應容器,控件不應該顯示設定寬高。比如這裡的

<Grid></Grid>

标簽就沒有設定寬高(為了友善觀察,設定了灰色的背景),當我們拖大拖小視窗時,可以看到grid元素也是跟随視窗變化而變化

<Window x:Class="ControlExercise.Window2"
        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:ControlExercise"
        mc:Ignorable="d"
        Title="Window2" Height="450" Width="800">
    <Grid Background="Gray">
        
    </Grid>
</Window>
           
WPF入門03之布局元素

反之,如果我們設定了寬高,不管怎麼拖動視窗,Grid都是固定大小的。

<Grid Width="100" Height="100" Background="Gray">
        
    </Grid>
           
WPF入門03之布局元素

布局容器之Grid

Grid控件為WPF中最重要的布局容器

  • 通過

    Grid.RowDefinitions

    來定義行,

    Grid.ColumnDefinitions

    來定義列

以下代碼定義了兩行,兩列,是以Grid被分割成了四個部分

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
    </Grid>
           
WPF入門03之布局元素
  • Grid定義寬度高度的三種方式
  1. 指定數值:(不建議)

    Width=50

2)等比例設定:

<ColumnDefinition Width="1*"></ColumnDefinition> <ColumnDefinition Width="2*"></ColumnDefinition> <ColumnDefinition Width="3*"></ColumnDefinition>

WPF入門03之布局元素

3)自适應 :

Width="Auto"

該單元格适應内部控件大小

  • 元素的跨行或跨列安放
WPF入門03之布局元素
  • GridSplitter 控件就是用來分割Grid控件的,必須放在Grid裡面

    GridSplitter的作用是可以讓使用者拖動來改變grid行或列的寬度或高度,使用起來非常簡單,把它加到Grid裡的某一行或者某一列,再配置設定合适的空間如5個像素這樣就可以了

<Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="5" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <TextBlock FontSize="55" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap">Left side</TextBlock>
        <GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" />
        <TextBlock Grid.Column="2" FontSize="55" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap">Right side</TextBlock>
           
WPF入門03之布局元素
  • 共享尺寸組

SharedSizeGroup屬性允許相同名的元素具有等大的效果

<!--定義一個父容器,Grid.IsSharedSizeScope="True"是必須的-->
    <Grid ShowGridLines="True" Grid.IsSharedSizeScope="True">
        
        <!--在父容器中定義了兩行-->
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>

        <!--在父容器的第一行定義一個子容器-->
        <Grid ShowGridLines="True" Name="grid_1" Background="blue" Grid.Row="0">
            <Grid.ColumnDefinitions>
                <!--第一個子容器的第一列指定了SharedSizeGroup屬性-->
                <ColumnDefinition  Width="50" SharedSizeGroup="A" ></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
        </Grid>

        <!--在父容器的第二行定義一個子容器-->
        <Grid ShowGridLines="True" Name="grid_2" Background="Green" Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition></ColumnDefinition>
                <!--第二個子容器的第二列指定了SharedSizeGroup屬性-->
                <ColumnDefinition  SharedSizeGroup="A" ></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
        </Grid>

    </Grid>
           
WPF入門03之布局元素

布局容器之StackPanel控件

堆棧面闆:在單行或單列中放置子元素

在視窗中放

<StackPanel></StackPanel>

标簽,stackPanel中放置3個button,1個Label,效果如下;可以看出,StackPanel預設會将子元素垂直排列

WPF入門03之布局元素

可以通過Orientation屬性來控制子元素排列方向

Orientation="Horizontal"

表示水準排列

Orientation="Vertical"

表示垂直排列,它是預設的

WPF入門03之布局元素

Margin

屬性為元素添加外邊距

Margin="10,15,20,25"的四個值分别表示左、上、右、下的位置,如下圖

WPF入門03之布局元素

MinWidth

屬性可以控制元素的最小尺寸,也就是說該元素不可以小于設定的最小寬度值

MaxWidth

屬性可以控制元素的最大尺寸,也就是說該元素不可以大于設定的最大寬度值

布局容器之WrapPanel控件

WrapPanel容器将子元素按行或列一個接一個進行排列,如果一行或一列放不下,元素會被擠到下一行或一列;同一行元素的高度一樣(水準排列),同一列元素的寬度是一樣的(豎直排列)

<WrapPanel>
            <Button Content="Button" />
            <Button Content="Button" />
            <!--這裡隻設定了一個button的高度,與它同一行的元素都變成了一樣的高度-->
            <Button Content="Button" Height="50" />
            <Button Content="Button" />
            <Button Content="Button" />
            <Button Content="Button" />
            <Button Content="Button" />
            <Button Content="Button" />
    </WrapPanel>
           
WPF入門03之布局元素

布局容器之DockPanel控件

DockPanel支援讓元素簡單地停靠在整個面闆的某一條邊上,然後拉伸元素以填滿全部寬度或高度。它也支援讓一個元素填充其他已停靠元素沒有占用的剩餘空間

DockPanel有一個Dock附加屬性,是以子元素用4個值來控制她們的停靠:Left、Top、Right、Bottom。Dock 沒有Fill值。作為替代,最後的子元素将加入一個DockPanel并填滿所有剩餘的空間,除非DockPanel的LastChildFill屬性為false,它将朝某個方向停靠

<DockPanel>
        <Button Content="Button"/>
        <Button Content="Button"/>
        <Button Content="Button"/>
        <Button Content="Button"/>
        <Button Content="Button"/>
    </DockPanel>
           
WPF入門03之布局元素

預設情況下,元素會依次橫向排列,并填充整個空間

<DockPanel>
        <!--DockPanel.Dock屬性可控制元素在DockPanle中依靠的位置-->
        <Button Content="Button" DockPanel.Dock="Top" />
        <Button Content="Button" DockPanel.Dock="Bottom"/>
        <Button Content="Button" DockPanel.Dock="Left"/>
        <Button Content="Button" DockPanel.Dock="Right"/>
        <Button Content="Button"/>
    </DockPanel>
           
WPF入門03之布局元素

布局容器之Canvas面闆

Canvas面闆是基于坐标的布局容器;Canvas中的子元素的位置是需要顯性設定的固定位置,通過Canvas的屬性Left/Rigth/Top/Bottom來設定子元素相對位置

下例是一個距離下邊界20、左邊界20位置的一個按鈕

<Canvas>
        <Button Canvas.Bottom="20" Canvas.Left="20">Hello</Button>
    </Canvas>
           
WPF入門03之布局元素

下例中定義了三個圖形,一個圓,三個矩形,它們之間的重疊是按預設的順序疊加的(未定義過Z坐标的,其Z坐标是0),可以通過設定Canvas.ZIndex屬性值或Panel.ZIndex來調整元素的重疊順序,值越大的越靠前

<Canvas>
        <Ellipse Fill="Gainsboro" Canvas.Left="25" Canvas.Top="25" Width="200" Height="200" />
        <Rectangle Canvas.ZIndex="3"  Fill="LightBlue" Canvas.Left="25" Canvas.Top="25" Width="50" Height="50" />
        <Rectangle Panel.ZIndex="2" Fill="LightCoral" Canvas.Left="50" Canvas.Top="50" Width="50" Height="50" />
        <Rectangle Panel.ZIndex="1" Fill="LightCyan" Canvas.Left="75" Canvas.Top="75" Width="50" Height="50" />
    </Canvas>
           
WPF入門03之布局元素

當然也可以調整Z軸順序,效果如下

WPF入門03之布局元素

布局容器之InkCavas

InkCavas是一個畫圖控件,它允許在它之上加載其它控件,比如加載一個按鈕;可以通過InkCanvas的Right/Left/Bottom/Top屬性來指定元素的位置

<InkCanvas>
        <Button Content="Hello" InkCanvas.Bottom="50" InkCanvas.Left="30" />
    </InkCanvas>
           

運作程式後,可發現,當滑鼠移動到InkCanvas區域時,滑鼠會變成一個黑點,按下滑鼠左鍵移動會畫出線條

InkCanvas

EditingMode

的屬性可根據不同的值,設定圖畫的不同功能

EditingMode="EraseByPoint"

表示滑鼠變成一個可擦除點的工具

EditingMode="EraseByStroke"

表示滑鼠變成一個可橡皮擦

EditingMode="GestureOnly"

表示按下滑鼠可畫線,滑鼠松開後所畫的線條将消失

EditingMode="Ink"

表示按下滑鼠可畫出墨線,本屬性值是預設的

EditingMode="InkAndGesture"

與Ink功能類似,但同時可以識别使用者的手勢

EditingMode="None"

表示沒有任何反應

EditingMode="Select"

表示可以選擇一個元素,可以移動它、删除它,改變形狀等

下面通過将這些屬性動态的加載到下拉框中,通過選擇不同的屬性值來體驗不同的畫圖效果

其中我感覺Select很有用,基于此可以實作讓客戶拖動縮放控件的效果。關鍵是不需要任何代碼,運作狀态控件的選中,拖動,縮放都已經實作了,非常友善

WPF入門03之布局元素
<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>

        <InkCanvas  Grid.Row="1" Name="incas">
            <Button Content="Hello" InkCanvas.Bottom="50" InkCanvas.Left="30" />
        </InkCanvas>

        <ComboBox Grid.Row="0" Name="cmb_model" SelectionChanged="cmb_model_SelectionChanged" />
    </Grid>