WPF面板布局介紹Grid、StackPanel、DockPanel、WrapPanel


回顧

        上一篇,我們介紹了基本控件及控件的重要屬性和用法,我們本篇詳細介紹WPF中的幾種布局容器及每種布局容器的使用場景,當然這些都是本人在實際項目中的使用經驗,可能還存在錯誤之處,還請大家指出。

本文大綱

1、Grid

2、StackPanel

3、DockPanel

4、WrapPanel

Grid

1、Row和Column

我們下面來介紹Grid的行的用法,及我們在UI設計過程中需要注意的細節。

由於前面我們在第一章中已經介紹了基本的關於Grid的表格行和列的定義及相關屬性,為了防止大家遺忘,我們這里再次介紹下:

image

為了加深大家對Grid布局的印象,我們這里加入控件來展示效果。

下面在每個單元格都加入子控件

image

上面指定了控件在Grid表格中的哪一行那一列,如果我們的某個控件跨行或者跨列如何做呢?

image

關於跨行和跨列一樣,只不過將Grid.ColumnSpan換成Grid.RowSpan。

下面介紹,在Grid如何將控件設置為自適應寬度和高度,或者是固定寬度或固定高度時,應該注意的細節。

image

1、自適應區域:

image

2、頂部對齊或底部對齊

image

對於頂部對齊和底部對齊,相對來說都一樣。

3、左右對齊時:

image

4、下面來舉個例子,我們來如何分析,根據原型來使用Grid布局來達到要求和目標:

例如下圖:

image

我們以博客園為例,可能例子不太合適,但是如果我們想做一個博客園的桌面版,保持風格一致的情況下,如果我們使用Grid布局如何來布局呢?

A、有Logo圖片,上面還有設置等菜單,所以,我們可以吧這塊設置為二行,這樣比較容易區分頁面的布局和設置

B、下面有幾個二級菜單,新聞、博問等 一行

C、左側有網站分類。必須1列

D、右側有內容區。上面有區分首頁、精華、候選、新聞、關注等、1列

E、右側有找找看、還有最新新聞等 1列。

F、最下面,肯定還有狀態欄,如果我們開發桌面系統。1行

 

根據上面的分析,我們的Grid表格至少5行、3列

關於其他的設計,我們通過Grid表格的組合來進行控制。

下面我們就來實現下:

先設置大體布局如下:

image

關於上述布局的具體實現如下:

<Window x:Class="Samples.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="600" Width="800">
    <Grid >
        <Grid.RowDefinitions>
            <RowDefinition Height="20"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="200"/>
        </Grid.ColumnDefinitions>
        <Grid Grid.Column="1" Grid.ColumnSpan="2">
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                <Button Content="何戈洲" Margin="5,0,0,0"/>
                <Button Content="我的博客" Margin="5,0,0,0"/>
                <Button Content="短消息" Margin="5,0,0,0"/>
                <Button Content="設置" Margin="5,0,0,0"/>
                <Button Content="退出" Margin="5,0,0,0"/>
            </StackPanel>
        </Grid>
        <Grid Grid.Column="0" Grid.Row="1">
            <Image Source="/Samples;Component/Images/logo_small.gif" />
        </Grid>
        <Grid Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="2">
            <StackPanel Orientation="Horizontal">
                <Button Margin="5,0,0,0">園子</Button>
                <Button Margin="5,0,0,0">新聞</Button>
                <Button Margin="5,0,0,0">博問</Button>
                <Button Margin="5,0,0,0">閃存</Button>
                <Button Margin="5,0,0,0">網摘</Button>
                <Button Margin="5,0,0,0">招聘</Button>
                <Button Margin="5,0,0,0">專題</Button>
                <Button Margin="5,0,0,0">知識</Button>
            </StackPanel>
        </Grid>
        <Grid Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="3">
            <Image Source="/Samples;Component/Images/main.png" />
        </Grid>
        <Grid Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="4">
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                <Button Margin="5,0,0,0">關於我們</Button>
                <Button Margin="5,0,0,0">聯系我們</Button>
                <Button Margin="5,0,0,0">廣告服務</Button>
                <Button Margin="5,0,0,0">人才服務</Button>
                <Button Margin="5,0,0,0">版權</Button>
            </StackPanel>
        </Grid>
    </Grid>
</Window>

 

從上面的代碼可以看出來,非常的簡單,Grid特別適合軟件系統的整體布局,在實際的項目中通過Grid與其他的布局控件相結合一起完成頁面的整體布局。

StackPanel

StackPanel 適合水平或者垂直方向的布局,在上面的例子中我們大量的使用該種布局方式。適合局部區域的布局。比如博客園中的如下區域就可以采用StackPanel進行布局。

image

image

image

對於這類的固定的區域,我們可以不適用Grid來進行布局,使用StackPanel也可以達到目標。

我們來使用StackPanel來進行布局

<StackPanel Orientation="Vertical" VerticalAlignment="Stretch">
                <GroupBox Header="網站分類" Height="Auto">
                    <StackPanel Orientation="Vertical">
                        <Button Content=".NET技術(16)"/>
                        <Button Content="編程語言(13)"/>
                        <Button Content="軟件設計(3)"/>
                        <Button Content="Web前端(16)"/>
                        <Button Content="軟件工程(26)"/>
                    </StackPanel>
                </GroupBox>
                <GroupBox Header="鏈接" Height="Auto">
                    <StackPanel Orientation="Vertical">
                        <Button Content="反饋和建議"/>
                        <Button Content="官方博客"/>
                        <Button Content="電子期刊" />
                        <Button Content="人才服務"/>
                        <Button Content="博客模板"/>
                    </StackPanel>
                </GroupBox>
            </StackPanel>

運行效果如下:

image

與預期的效果相同,對於其他的模塊,我們也可以在局部,對於水平或者垂直方向要求進行布局的,我們都可以采用StackPanel來進行布局。

下面我們來看看橫向布局的例子:

image

我們通過表格中的使用對StackPanel的停靠定位,進而通過Stackpanel對內部的子控件的停靠方向設置,我們通過如下代碼實現上述效果:

<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
               <Button Content="何戈洲" Margin="5,0,0,0"/>
               <Button Content="我的博客" Margin="5,0,0,0"/>
               <Button Content="短消息" Margin="5,0,0,0"/>
               <Button Content="設置" Margin="5,0,0,0"/>
               <Button Content="退出" Margin="5,0,0,0"/>
</StackPanel>

StackPanel在父容器中是右對齊的。

然后再StackPanel容器中,如果也采用內容右對齊,會有什么效果呢?

<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                <Button Content="何戈洲" Margin="5,0,0,0" HorizontalAlignment="Right"/>
                <Button Content="我的博客" Margin="5,0,0,0"  HorizontalAlignment="Right"/>
                <Button Content="短消息" Margin="5,0,0,0"  HorizontalAlignment="Right"/>
                <Button Content="設置" Margin="5,0,0,0"  HorizontalAlignment="Right"/>
                <Button Content="退出" Margin="5,0,0,0"  HorizontalAlignment="Right"/>
</StackPanel>

設置子控件的停靠方式時,不會起到任何作用,默認情況下,Stack的水平布局時,從左至右。

<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" FlowDirection="RightToLeft">
                <Button Content="何戈洲" Margin="5,0,0,0" HorizontalAlignment="Right"/>
                <Button Content="我的博客" Margin="5,0,0,0"  HorizontalAlignment="Right"/>
                <Button Content="短消息" Margin="5,0,0,0"  HorizontalAlignment="Right"/>
                <Button Content="設置" Margin="5,0,0,0"  HorizontalAlignment="Right"/>
                <Button Content="退出" Margin="5,0,0,0"  HorizontalAlignment="Right"/>
</StackPanel>

修改了FlowDirection設置了StackPanel的方向后,所有的子控件,都是從右向左方向進行繪制和顯示,效果如下:

image

所以對於StackPanel我們基本上是用上述的屬性和對StackPanel的停靠方式進行設置后,即可滿足布局的要求。

DockPanel

DockPanel停靠容器,專門負責自適應窗口的布局,之前我們介紹了DockPanel的布局設置,這里再回顧下:

<DockPanel>
                <StackPanel DockPanel.Dock="Top" Height="0">
                </StackPanel>
                <StackPanel DockPanel.Dock="Left" Height="0">
                </StackPanel>
                <StackPanel DockPanel.Dock="Bottom" Height="0">
                </StackPanel>
                <StackPanel DockPanel.Dock="Right" Orientation="Vertical" Width="200">
                    <GroupBox Header="最新新聞" Height="160">
                        <StackPanel Orientation="Vertical">
                            <Button Content="宅急送近日宣布降價搶"/>
                            <Button Content="騰訊聯手華為操盤四核手機"/>
                            <Button Content="Windows 8各版本區別與售價"/>
                            <Button Content="數方程將無線網絡帶寬提高一個數量級"/>
                            <Button Content="中移動:Lumia 920T將於11月上市"/>
                            <Button Content="Windows 8下一站:10月25日紐約"/>
                        </StackPanel>
                    </GroupBox>
                    <GroupBox Header="48小時閱讀排行榜" Height="160">
                        <StackPanel Orientation="Vertical">
                            <Button Content="子用戶-角色-權限-菜單 淺談:子賬戶設計方案"/>
                            <Button Content="網站已恢復正常,讓大家久等了"/>
                            <Button Content="拿什么拯救你,我的51Job簡歷?——UBB漏洞"/>
                            <Button Content="這些年我們沒用過的JS"/>
                            <Button Content="多少錢才可讓人重拾理想"/>
                            <Button Content="准備購買的Dell服務器的硬件配置"/>
                        </StackPanel>
                    </GroupBox>
                </StackPanel>
                <StackPanel >

                      <Button Content=" 我鋪滿"/>

                </StackPanel>
</DockPanel>

上面的DockPanel在進行自適應布局時,默認最后的一個區域時默認填充,可以理解為fill。而必須制定其他的區域后,該設置才有效,所以,我們上面設置了top,left,bottom 占用的空間都是0,這樣,系統會將最后的一個子區域填充。

上面設置后的效果如下。

image

當然,這個頁面的整體,我們也可以采用DockPanel進行布局,布局的效果,完全可以達到上述效果,下面我們來使用DockPanel來對整體進行布局吧。

最終的代碼如下:

<DockPanel>
          <StackPanel DockPanel.Dock="Top" Height="100">
              <Grid>
                  <Grid.RowDefinitions>
                      <RowDefinition Height="20"/>
                      <RowDefinition Height="50"/>
                      <RowDefinition Height="30"/>
                  </Grid.RowDefinitions>
                  <Grid >
                      <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" FlowDirection="RightToLeft">
                          <Button Content="何戈洲" Margin="5,0,0,0" HorizontalAlignment="Right"/>
                          <Button Content="我的博客" Margin="5,0,0,0"  HorizontalAlignment="Right"/>
                          <Button Content="短消息" Margin="5,0,0,0"  HorizontalAlignment="Right"/>
                          <Button Content="設置" Margin="5,0,0,0"  HorizontalAlignment="Right"/>
                          <Button Content="退出" Margin="5,0,0,0"  HorizontalAlignment="Right"/>
                      </StackPanel>
                  </Grid>
                  <Grid  Grid.Row="1">
                      <Image Source="/Samples;Component/Images/logo_small.gif" HorizontalAlignment="Left"/>
                  </Grid>
                  <Grid  Grid.Row="2">
                      <StackPanel Orientation="Horizontal">
                          <Button Margin="5,0,0,0">園子</Button>
                          <Button Margin="5,0,0,0">新聞</Button>
                          <Button Margin="5,0,0,0">博問</Button>
                          <Button Margin="5,0,0,0">閃存</Button>
                          <Button Margin="5,0,0,0">網摘</Button>
                          <Button Margin="5,0,0,0">招聘</Button>
                          <Button Margin="5,0,0,0">專題</Button>
                          <Button Margin="5,0,0,0">知識</Button>
                      </StackPanel>
                  </Grid>
              </Grid>
          </StackPanel>
          <StackPanel DockPanel.Dock="Bottom" Height="30" Orientation="Horizontal" HorizontalAlignment="Center">
              <Button Margin="5,0,0,0">關於我們</Button>
              <Button Margin="5,0,0,0">聯系我們</Button>
              <Button Margin="5,0,0,0">廣告服務</Button>
              <Button Margin="5,0,0,0">人才服務</Button>
              <Button Margin="5,0,0,0">版權</Button>
          </StackPanel>
          <StackPanel DockPanel.Dock="Left" Width="150">
              <StackPanel Orientation="Vertical" VerticalAlignment="Stretch">
                  <GroupBox Header="網站分類" Height="Auto">
                      <StackPanel Orientation="Vertical">
                          <Button Content=".NET技術(16)"/>
                          <Button Content="編程語言(13)"/>
                          <Button Content="軟件設計(3)"/>
                          <Button Content="Web前端(16)"/>
                          <Button Content="軟件工程(26)"/>
                      </StackPanel>
                  </GroupBox>
                  <GroupBox Header="鏈接" Height="Auto">
                      <StackPanel Orientation="Vertical">
                          <Button Content="反饋和建議"/>
                          <Button Content="官方博客"/>
                          <Button Content="電子期刊" />
                          <Button Content="人才服務"/>
                          <Button Content="博客模板"/>
                      </StackPanel>
                  </GroupBox>
              </StackPanel>
          </StackPanel>
          <StackPanel DockPanel.Dock="Right" Orientation="Vertical" Width="200">
              <GroupBox Header="最新新聞" Height="160">
                  <StackPanel Orientation="Vertical">
                      <Button Content="宅急送近日宣布降價搶"/>
                      <Button Content="騰訊聯手華為操盤四核手機"/>
                      <Button Content="Windows 8各版本區別與售價"/>
                      <Button Content="數方程將無線網絡帶寬提高一個數量級"/>
                      <Button Content="中移動:Lumia 920T將於11月上市"/>
                      <Button Content="Windows 8下一站:10月25日紐約"/>
                  </StackPanel>
              </GroupBox>
              <GroupBox Header="48小時閱讀排行榜" Height="160">
                  <StackPanel Orientation="Vertical">
                      <Button Content="子用戶-角色-權限-菜單 淺談:子賬戶設計方案"/>
                      <Button Content="網站已恢復正常,讓大家久等了"/>
                      <Button Content="拿什么拯救你,我的51Job簡歷?——UBB漏洞"/>
                      <Button Content="這些年我們沒用過的JS"/>
                      <Button Content="多少錢才可讓人重拾理想"/>
                      <Button Content="准備購買的Dell服務器的硬件配置"/>
                  </StackPanel>
              </GroupBox>
          </StackPanel>
          <StackPanel >
              <Button Content=" 我鋪滿"/>
          </StackPanel>
      </DockPanel>

 

運行上述代碼效果如下:

image

通過DockPanel完成對整體的布局,然后內部結合一些其他的布局控件,完成局部的細節的布局。

 

 

 

WrapPanel

WrapPanel容器我們也介紹過,該容器可以看做自動換行功能的StackPanel容器。下面我們就來分析下該容器的一般應用場景。

image 我們看到了windows8中的如下頁面,如果我們仿制該頁面的時候,其實我們可以采用wrappanel來實現自動的換行,下面我們來試試吧

最終代碼如下:

<Window x:Class="Samples.Window8Window"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window8Window" Height="600" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <Label Content="開始" FontFamily="微軟雅黑" FontSize="30"/>
        </Grid >
        <Grid Grid.Row="1">
            <WrapPanel Orientation="Horizontal" ItemHeight="100" ItemWidth="190">
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
                <Image Source="/Samples;Component/Images/logo_small.gif" />
            </WrapPanel>
        </Grid>
    </Grid>
</Window>

 

運行后,效果如下:

image

當然,我們的界面效果,還打不到美感,但是的確是自動換行。我們將水平方向,修改為垂直方向后,運行:

image

運行查看效果。

image

通過上面的簡單案例,我們基本上知道了wrapPanel的用法。

 

總結

通過上面的介紹和demo的演示,我們知道了如何在項目中什么情況下,使用什么樣的布局容器,通過實際的案例,我們更容易理解和掌握布局的模式。錯誤之處,還請大家反饋,我及時改正,謝謝!

 

參考出處:http://www.cnblogs.com/hegezhou_hot/archive/2012/10/23/2735874.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM