這一周章老師又講解了許多內容,本次學習記錄就選取我非常感興趣且實驗需要的重要知識-WPF以及與它緊密聯系的XAML進行探究。
首先介紹一下基本知識。
WPF(Windows Presentation Foundation),中文譯名“Windows呈現基礎”是微軟推出的基於Windows Vista的用戶界面框架,屬於.NET Framework 3.0的一部分。它提供了統一的編程模型、語言和框架,真正做到了分離界面設計人員與開發人員的工作;同時它提供了全新的多媒體交互用戶圖形界面。WPF是微軟新一代圖形系統,運行在.NET Framework 3.0及以上版本下,為用戶界面、2D/3D 圖形、文檔和媒體提供了統一的描述和操作方法。基於DirectX 9/10技術的WPF不僅帶來了前所未有的3D界面,而且其圖形向量渲染引擎也大大改進了傳統的2D界面,比如Vista中的半透明效果的窗體等都得益於WPF。 程序員在WPF的幫助下,要開發出媲美Mac程序的酷炫界面已不再是遙不可及的奢望。 WPF相對於Windows客戶端的開發來說,向前跨出了巨大的一步,它提供了超豐富的.NET UI 框架,集成了矢量圖形,豐富的流動文字支持(flow text support),3D視覺效果和強大無比的控件模型框架。如下面這些漂亮的應用界面:



在WPF編程中,用戶界面實際上完全是由XAML(Extensible Application Markup Language),即“可擴展應用程序標記語言”來編寫的。它是微軟公司為構建應用程序用戶界面而創建的一種新的描述性語言。XAML提供了一種便於擴展和定位的語法來定義和程序邏輯分離的用戶界面,而這種實現方式和ASP.NET中的"代碼后置"模型非常類似。XAML是一種解析性的語言,盡管它也可以被編譯。它的優點是簡化編程式上的用戶創建過程,應用時要添加代碼等。還有一點是需要反復強調的,XAML並不是HTML。盡管XAML在元素的聲明、程序樣式的設置和指定事件處理程序上都和HTML非常類似,但是XAML是基於XML的,它是WPF的外在表現形式。而HTML只是一種標記語言,僅僅是用來為瀏覽器呈現頁面內容。XAML除了用來呈現信息和請求用戶輸入等基本的功能外,它還包含了一些高級的特性,例如它提供了對動畫和3D眾多方面的支持。XAML是可擴展的,正如它的名字指明的那樣。開發人員可以創建自定義的控件、元素和函數來擴展XAML。而且由於XAML各元素在本質上就是WPF類的映射,所以開發人員可以很輕松地使用面向對象的技術對XAML元素進行擴展。也就是說我們可以開發一些自定義控件和組合元素,並將它公開給用戶界面設計人員和其它的開發人員使用。
下面先介紹一下XAML的一些基礎知識。
先附上一段簡單的XAML代碼以及詳細注釋:
1 <Window x:Class="WPFTest.MainWindow" <!-- 類名 --> 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" <!-- WPF的默認·命名空間,聲明了許多可能用到的控件--> 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" <!-- 聲明XAML語言本身--> 4 Title="MainWindow" Height="350" Width="525"> <!-- Title是界面窗口左上角的標題,Height與Width代表整個窗口的高度與寬度--> 5 <Grid> <!-- Grid控件 --> 6 <Button Content="Hello World" <!-- 按鈕控件,Content表示按鈕上的文本--> 7 HorizontalAlignment="Left" <!-- 設置指定對象的水平對齊方式,此處表示向左對齊--> 8 Margin="200,143,0,0" <!-- 控件距離窗口四邊的距離,向左向上的優先級較高--> 9 VerticalAlignment="Top" <!-- 設置指定對象的垂直對齊方式,此處表示向上對齊--> 10 Width="100" <!-- 寬度--> 11 Height="40"/> <!-- 長度--> 12 </Grid> <!-- 結束標記--> 13 </Window>
運行結果如下:
是不是既漂亮又簡單?更炫酷的是用VS2013開發WPF的時候可以自由拖拽控件,自動生成相應的XAML代碼,從而輕易達到自己想要的排版效果。
下面介紹一下XAML中的布局控件。
先介紹一下主要布局元素的特性:
- Grid:網格。可以自定義行和列,並通過行列的數量、行高和列寬來調整控件的布局,有點類似於html中的Table。
- StackPanel:棧式面板。可以將包含元素排成一條直線,當添加或移除包含元素時,后面的元素會自動向下或向上移動。
- Canvas:畫布。可以指定包含元素的絕對坐標位置。
- DockPanel:泊靠式面板。內部元素可以選擇泊靠方式。
- WarpPanel:自動折行面板。當一行元素排滿后會自動換行。類似html中的流式布局。
Grid的特點如下:
- 可以定義任意數量的行和列
- 行高與列寬可以使用絕對值,相對比以及最大值和最小值
- 內部元素可以設置自己的所在列和行,還可以設置自己跨幾列和行。
- 可以設置Children元素的對齊方式
下面是一個比較炫酷的Grid布局的示例,代碼及運行效果如下:
1 <Window x:Class="WPFTest.Grid" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="Grid" Height="300" Width="300" MinHeight="300" MaxWidth="500"> 5 <!--MinHeight="300" MaxWidth="500"限制窗口的最小高度和最大寬度--> 6 <Grid x:Name="grid"> 7 <!--定義行--> 8 <Grid.RowDefinitions> 9 <RowDefinition Height="25" ></RowDefinition> 10 <RowDefinition Height="50"/> 11 <RowDefinition Height="1*"/> 12 <RowDefinition Height="*"/> 13 <RowDefinition Height="auto"> 14 </RowDefinition> 15 </Grid.RowDefinitions> 16 <!--定義列--> 17 <Grid.ColumnDefinitions> 18 <ColumnDefinition Width="25" ></ColumnDefinition> 19 <ColumnDefinition Width="50"/> 20 <ColumnDefinition Width="1*"/> 21 <ColumnDefinition Width="*"/> 22 <ColumnDefinition Width="auto"/> 23 </Grid.ColumnDefinitions> 24 <!--在指定的行列中布置控件--> 25 <TextBox Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="2" Text="布局" Background="Gray"/> 26 </Grid> 27 </Window>
在后台代碼上加上 this.grid.ShowGridLines=true便可顯示下列結果:
StackPanel可以把內部的元素在縱向或者橫向上緊密排列,形成棧式布局。先介紹一下其三個屬性:
- Orientation 決定內部元素是橫向還是縱向累積。可取值為Horizontal,Vertical。
- HorizontalAlignment 決定內部元素水平方向上的對齊方式。可取值Left,Center,Right,Stretch。
- VerticalAlignment 決定內部元素豎直方向上的對齊方式。可取Top,Center,Bottom,Stretch。
簡單示例如下:
1 <Window x:Class="WPFTest.StackPanels" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="StackPanels" Height="300" Width="300"> 5 <Grid> 6 <StackPanel HorizontalAlignment="Left" Height="128" VerticalAlignment="Top" Width="284" Orientation="Horizontal"> 7 <Button Content="Button" Height="128" VerticalAlignment="Top" Width="75"/> 8 <Button Content="Button" Height="128" VerticalAlignment="Top" Width="75"/> 9 <Button Content="Button" Height="128" VerticalAlignment="Top" Width="75"/> 10 </StackPanel> 11 <StackPanel HorizontalAlignment="Left" Height="128" VerticalAlignment="Top" Width="284" Margin="0,128,0,0" Orientation="Vertical"> 12 <Button Content="Button" HorizontalAlignment="Left" Width="284"/> 13 <Button Content="Button" HorizontalAlignment="Left" Width="284"/> 14 <Button Content="Button" HorizontalAlignment="Left" Width="284"/> 15 </StackPanel> 16 </Grid> 17 </Window>
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Data; 9 using System.Windows.Documents; 10 using System.Windows.Input; 11 using System.Windows.Media; 12 using System.Windows.Media.Imaging; 13 using System.Windows.Navigation; 14 using System.Windows.Shapes; 15 16 namespace WPFTest 17 { 18 /// <summary> 19 /// MainWindow.xaml 的交互邏輯 20 /// </summary> 21 public partial class StackPanel : Window 22 { 23 public StackPanel() 24 { 25 InitializeComponent(); 26 } 27 28 private void InitializeComponent() 29 { 30 throw new NotImplementedException(); 31 } 32 } 33 }
也是非常漂亮!
Canvas(畫布):內容控件可以准確定位到指定坐標,但是不足的地方是,如果要修改的話可能會關系到很多的控件,所以如果不需要經常修改的窗體,使用該控件布局,或者是藝術性比較強(用來實現依賴於橫縱坐標的動畫等功能)的布局使用此控件布局。
下面是一個登陸頁面示例來介紹Canvas.Left與Canvas.Top的用法:
1 <Window x:Class="WPFTest.Canvas" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="登陸" Height="145" Width="300"> 5 <Canvas Background="Sienna"> <!-- 設置背景--> 6 <TextBlock Canvas.Left="0" Canvas.Top="13" Margin="5" Text="用戶名:"/> 7 <TextBox Canvas.Left="50" Canvas.Top="13" Width="160" /> 8 <TextBlock Canvas.Left="0" Canvas.Top="47" Margin="5" Text="密 碼:"/> 9 <TextBox Canvas.Left="50" Canvas.Top="47" Width="160" /> 10 <Button Content="確定" Canvas.Left="70" Canvas.Top="77" Width="63" Height="22" /> 11 <Button Canvas.Left="150" Canvas.Top="77" Content="清除" Width="63" Height="22" /> 12 </Canvas> 13 </Window>
代碼簡單明了,就不多加注釋了,如圖所示效果也是十分炫酷!
顧名思義,DockPanel控件允許將控件貼靠在某條邊上。DockPanel具有一個能讓子控件用來指定停靠邊緣的附加屬性,即DockPanel.Dock,可將該屬性的值設為Left,Right,Top或Bottom。DockPanel中控件的堆疊順序非常重要,因為每當一個控件停靠在某個邊緣上后,其他子控件的可占用空間就會減少。例如,把一個工具條停靠在DockPanel的頂部,再把第二個工具條停靠在DockPanel的左邊。第一個控件會延伸到DockPanel顯示區域的整個頂部,但第二個控件只能從第一個工具條的底部開始沿着DockPanel的左邊界延伸到DockPanel的底部。在前面的子控件都定位好后,最后一個指定的控件通常會占據剩余的空間(可以控制這個行為)。
下面是一個DockPanel布局示例:
1 <Window x:Class="WPFTest.DockPanels" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="DockPanels" Height="300" Width="300"> 5 <DockPanel Background="AliceBlue"> 6 <Border DockPanel.Dock="Top" Padding="10" Margin="5" <!--第一個Border控件停靠在頂部,未指定width,故占滿所停靠邊緣的整個可用區域--> 7 Background="Aquamarine" Height="45"> 8 <Label>1) DockPanel.Dock="Top"</Label> 9 </Border> 10 <Border DockPanel.Dock="Top" Padding="10" Margin="5" <!--第二個Border控件也停靠在DockPanel的頂部,這個Border控件還包含Width屬性,使Border僅占據DockPanel的部分寬度。它位於中心,因為DockPanel中的HorizontalAlignment的默認值是Center--> 11 Background="PaleVioletRed" Height="45" Width="200"> 12 <Label>2) DockPanel.Dock="Top"</Label> 13 </Border> 14 <Border DockPanel.Dock="Left" Padding="10" Margin="5" <!--第三個Border控件停靠在DockPanel的左邊,占據顯示區域左邊的210個像素--> 15 Background="Bisque" Width="200"> 16 <Label>3) DockPanel.Dock="Left"</Label> 17 </Border> 18 19 <Border DockPanel.Dock="Bottom" Padding="10" Margin="5" <!--第四個Border控件停靠在DockPanel的底部,Border控件鎖定在DockPanel的右下角,因為它的HorizontalAlignment為Right--> 20 Background="Ivory" Width="200" HorizontalAlignment="Right"> 21 <Label>4) DockPanel.Dock="Bottom"</Label> 22 </Border> 23 <Border Padding="10" Margin="5" Background="BlueViolet"> <!--第五個也是最后一個Border控件填滿了剩余的空間--> 24 <Label Foreground="White">5) Last control</Label> 25 </Border> 26 </DockPanel> 27 </Window>
效果是不是特別棒?
WrapPanel控件基本上可以認為是StackPanel的一個擴展版本,其中"不合適"的控件會移動到附加的行或列上。示例代碼如下:
1 <Window x:Class="WPFTest.WrapPanel" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="WrapPanel" Height="300" Width="300"> 5 <WrapPanel Background="AliceBlue"> 6 <Rectangle Fill="#FF000000" Height="50" Width="50" Stroke="Black" 7 RadiusX="10" RadiusY="10" /> 8 <Rectangle Fill="#FF111111" Height="50" Width="50" Stroke="Black" 9 RadiusX="10" RadiusY="10" /> 10 <Rectangle Fill="#FF222222" Height="50" Width="50" Stroke="Black" 11 RadiusX="10" RadiusY="10" /> 12 <Rectangle Fill="#FFFFFFFF" Height="50" Width="50" Stroke="Black" 13 RadiusX="10" RadiusY="10" /> 14 </WrapPanel> 15 </Window>
縮小之后如下所示:
非常好玩。總之WrapPanel控件是創建動態布局的一種好方法,允許我們控制內容的顯示方式。
本次學習記錄就先到此為止,以后有機會會補上UI控件的有關內容以及更加高級一些的WPF桌面編程。
望各位老師大牛不吝賜教!