WPF中控件和布局_第1頁
WPF中控件和布局_第2頁
WPF中控件和布局_第3頁
WPF中控件和布局_第4頁
WPF中控件和布局_第5頁
已閱讀5頁,還剩13頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、WPF控件和布局WPF控件和布局,根據劉鐵猛深入淺出WPF書籍講解內容,主要記錄控件和布局的原理,如果有不足的地方,請大牛們鍵盤下留情-輕噴!如果還算有用,請給點動力,支持一把!一、WPF里的控件1.1 控件的實質我們先從UI上分析,UI的功能是讓用戶觀察和操作數據,為了能顯示數據和響應用戶的操作通知程序(通過事件來通知,如何處理事件又是一系列的算法),所以控件就是顯示數據和響應用戶操作的UI元素,也即:控件就是數據和行為的載體。 1.2 WPF中的一個重要概念-數據驅動UI什么是數據驅動UI呢?我們知道傳統的GUI界面都是由windows消息通過事件傳遞給程序,程序根據不同的操作來表達出不同

2、的數據體現在UI界面上,這樣數據在某種程度上來說,受到很大的限制。WPF中是數據驅動UI,數據是核心,處于主動的,UI從屬于數據并表達數據,是被動的。因為以后的章節會重點介紹,在此不做過多的說明,只要記著,WPF數據第一,控件第二。1.3 WPF中控件的知多少雖然控件沒有數據重要,但是還是比較重要的,畢竟是門面啊,只是在數據面前,它比較"有禮貌"。控件有很多,但是如果仔細去分析,也是有規律可循的,根據其作用,我們可以把控件分為6類:· 布局控件:是可以容納多個控件或者嵌套其他布局的控件,用于在UI上組織和排列控件。其父類為Panel。· 內容控件:只能容

3、納一個控件或者布局控件作為他的內容。所以經常借助布局控件來規劃其內容。其父類為ContentControl。· 帶標題內容控件:相當于一個內容控件,但是可以加一個標題,標題部分也可以容納一個控件或者布局,其父類為HeaderedContentControl。· 條目控件:可以顯示一列數據,一般情況下,是數據的類型是相同的。其共同的基類為ItemsControl。· 帶標題的條目控件:和上面的帶標題內容控件類同,其基類為HeaderdeItemsControl。· 特殊內容控件:這類控件比較獨立,但也比較常用,如TextBox,TextBlock,Imag

4、e等(由于其常用性和相對比較簡單,本篇筆記不做說明)。上面的控件的派生關系如圖1:圖1二、各類控件模型詳解2.1 WPF中的內容模型為了理解各個控件的模型,還是先了解一下WPF中的內容模型。在上述各類控件里,至少可以容納一個內容,主要原因是由于每個控件對象都會有一個重要又不常寫出來的屬性-Content Property(有Content,Child,Items,Children幾個屬性,如Grid可以容納多個控件,用的是Children)。內容模型就是每一族的控件都含有一個或者多個元素作為其內容(其下面的元素可能是其他控件)。為什么可以不常寫出來呢?先讓我們看下面兩段代碼:XAML Code

5、<Window x:Class="Chapter_03.MainWindow" xmlns=" xmlns:x=" Title="內容屬性測試" Height="350" Width="525"> <Grid> <Grid.Children> <Button Content="1" Margin="120,146,0,146" HorizontalAlignment="Left" Width=&

6、quot;82" /> <Button Content="2" x:Name="btn2" Margin="0,146,142,145" HorizontalAlignment="Right" Width="82" /> </Grid.Children> </Grid></Window>XAML<Window x:Class="Chapter_03.MainWindow" xmlns=" xmln

7、s:x=" Title="內容屬性測試" Height="350" Width="525"> <Grid> <Button Content="1" Margin="120,146,0,146" HorizontalAlignment="Left" Width="82" /> <Button Content="2" x:Name="btn2" Margin="0,

8、146,142,145" HorizontalAlignment="Right" Width="82" /> </Grid></Window>運行兩段代碼效果一樣。充分說明了重要而有不常見的原因。因為省略的省時,而且簡潔明了。所以多數引用時都省去了。2.2ContentControl族先說一下其特點:他們內容屬性的名稱為Content,只能有單一元素充當其內容。下面通過例子說明其特點: <Button Margin="120,146,0,76" HorizontalAlignment=&q

9、uot;Left" Width="100"> <TextBox Text="測試"/> <TextBox Text="測試"/> <TextBox Text="測試"/> </Button>上面的會報錯,原因是Button里面只能有單一元素充當其內容。去掉后面的兩個TextBox,效果如圖2:圖2發現button里面不僅可以顯示文字還可以用一個控件來當其內容。其他的控件不在一一舉例。在此列出此類的主要控件:Button、ButtonBase、Check

10、Box、ComboBoxItem、ContentControl、Frame、GridViewColumnHeader、GropItem、Label、ListBoxItem、ListViewItem、NavigationWindow、RadioButton、ScrollViewer、StatusBarItem、ToggleButton、ToolTip、UserControl、Window。2.3 HeaderedContentControl族特點:可以顯示帶標題的數據,內容屬性為Content和Header,其這兩個屬性都只能容納一個元素。在此舉例說明GroupBox的用法,然后列出其他屬于此類

11、的控件。XAML代碼為:View Code <Window x:Class="Chapter_03.MainWindow" xmlns=" xmlns:x=" Title="內容屬性測試" Height="200" Width="300"> <Grid Background="Gold"> <GroupBox Margin="42,0,96,26"> <GroupBox.Header> <Label C

12、ontent="我是標題"/> </GroupBox.Header> <Button HorizontalAlignment="Left" Width="117" Height="45"> <TextBox Text="測試"/> </Button> </GroupBox> </Grid></Window>效果圖如圖3:圖3是不是看著很還好呢?現在列出同類主要的控件:Expender,GroupBox,He

13、aderedContentControl,TabItem。2.4 ItemsControl族特點:該類控件用于顯示列表化的數據,內容屬性為Items或ItemsSource,每種ItemsControl都對應有自己的條目容器(Item Container)。本類元素可能會用的比較多些,也比較靈活,所以這里不做過多記錄,以后的記錄會經常用到,具體的再詳細說明。下面就用一個ListBox控件來小試牛刀吧!XAML代碼、Cs代碼如下:XAML<Window x:Class="Chapter_03.MainWindow" xmlns=" xmlns:x="

14、 Title="內容屬性測試" Height="260" Width="408"> <Grid Background="Gold"> <ListBox x:Name="listbox" Margin="0,0,198,55"> <CheckBox x:Name="cb1" Content="選擇"/> <CheckBox x:Name="cb2" Content=&qu

15、ot;選擇"/> <CheckBox x:Name="cb3" Content="選擇"/> <CheckBox x:Name="cb4" Content="選擇"/> <Button x:Name="btn1" Content="按鈕1"/> <Button x:Name="btn2" Content="按鈕1"/> <Button x:Name="btn

16、3" Content="按鈕1"/> </ListBox> </Grid></Window>CSusing System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input

17、;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;namespace Chapter_03 / <summary> / MainWindow.xaml 的交互邏輯 / </summary> public partial class MainWindow : Window public MainWindow() InitializeComponent(); Button btn=

18、new Button(); btn.Content="另外添加一個" btn.Click += new RoutedEventHandler(btn_Click); this.listbox.Items.Add(btn); btn3.Click+=new RoutedEventHandler(btn_Click); / <summary> / 用來找到button的父級元素類型 / </summary> / <param name="sender"></param> / <param name=&qu

19、ot;e"></param> void btn_Click(object sender, RoutedEventArgs e) Button btn=(sender) as Button; DependencyObject level1 = VisualTreeHelper.GetParent(btn); DependencyObject level2 = VisualTreeHelper.GetParent(level1); DependencyObject level3 = VisualTreeHelper.GetParent(level2); if (btn

20、!= null) MessageBox.Show(level3.GetType().ToString(); else MessageBox.Show("無找到!"); 效果圖如圖4:圖4先來說明一下代碼:在listBox里面放了幾個checkbox和button,說明ListBoxI的Item不僅支持類型相同的元素,還支持類型不同的元素。這是因為,Listbox的每一項都是經過“ListBoxItem”加工廠處理的,最終放入當做自己的內容-放入自己的容器內。這里通過后臺代碼說明了每一個條目都被ListboxItem包裝過了,完全沒有必要每一個條目都在xmal文件按照如下寫法

21、: <ListBoxItem> <Button x:Name="btn3" Content="按鈕1"/> </ListBoxItem>在實際項目中,很少像上面那樣把代碼寫死,可以動態的綁定ListBox。把數據源賦給ListBox的ItemsSource,通過DisplayMemberPath屬性來顯示string類型的數據源里面的字段條目(如果想顯示復雜的數據的話,要使用DataTemplate,具體在模板再記錄,在此知道有這么一回事就好了);通過SelectedItem和SelectionChanged來觀察選中

22、的項。下面的例子實現在listbox上綁定指定數據,然后彈出選中人的年齡。直接給出代碼:XAML<Window x:Class="Chapter_03.ListBoxTest" xmlns=" xmlns:x=" Title="ListBoxTest" Height="300" Width="300"> <Grid> <ListBox x:Name="listbox1" Margin="0,0,60,31" Selection

23、Changed="listbox1_SelectionChanged"></ListBox> </Grid></Window>CSusing System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.W

24、indows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Shapes;namespace Chapter_03 / <summary> / ListBoxTest.xaml 的交互邏輯 / </summary> public partial class ListBoxTest : Window public ListBoxTest() InitializeComponent(); InitData(); protected void I

25、nitData() List<People> peopleList = new List<People>() new People()Id=1,Name="Tim",Age=30, new People()Id=2,Name="Tom",Age=30,顯示結果如圖5:圖5下面列出屬于ItemsControl族元素和其對應的Item Container有ComboBoxComboBoxItem,ContextMenuMenuItem,ListBoxListBoxItem,ListViewListViewItem,MenuMenuIt

26、em,StatusBarStatusBarItem,TabControlTabItem,TreeViewTreeViewItem.由于已經演示了HeaderedContentControl和ItemsControl的功能,另外HeaderedItemsControl的用法就不再記錄了,僅僅列出屬于其族的控件:MemuItem、TreeViewItem、TooBar。三、 UI布局在介紹布局之前還是先記錄一下布局控件的特點與屬于Panel族的控件。panel族控件內容屬性為Children,所以內容可以是多個元素,這對布局來說是很重要的特征。布局控件與ItemControl的區別是:前者強調的是

27、對元素的布局,后者強調的是條目。屬于Panel類的控件有:Canvas,DockPanel,Grid,TabPanel,ToolBarOverflowPanel,StackPanel,ToolBarPanel,UniformGrid,VirtualizingPanel,VirtualizingStackPanel,WrapPanel。這么多控件不可能一個個去介紹,找幾個比較重要的實踐一下。回頭如果有用到的話再逐一研究。3.1 主要布局控件的特性在WPF里面控件與控件的關系除了相鄰和重疊(用Opacity來控制哪個控件在上面,哪個在下面),還有一個包含。正因為如此,才有了以window為根的樹形

28、結構的XAML。下面介紹一下主要布局元素的特性:· Grid:網格。可以自定義行和列,并通過行列的數量、行高和列寬來調整控件的布局,有點類似于html中的Table。· StackPanel:棧式面板。可以將包含元素排成一條直線,當添加或移除包含元素時,后面的元素會自動向下或向上移動。· Canvas:畫布。可以指定包含元素的絕對坐標位置。· DockPanel:泊靠式面板。內部元素可以選擇泊靠方式。· WarpPanel:自動折行面板。當一行元素排滿后會自動換行。類似html中的流式布局。3.2 GridGrid的特點如下:· 可以

29、定義任意數量的行和列· 行高與列寬可以使用絕對值,相對比以及最大值和最小值· 內部元素可以設置自己的所在列和行,還可以設置自己跨幾列和行。· 可以設置Children元素的對齊方式現在給出定義行與列的代碼(記得在后臺代碼上加上 this.grid.ShowGridLines=true以便顯示出網格):XAML<Window x:Class="Chapter_03.Grid" xmlns=" xmlns:x=" Title="Grid" Height="300" Width=&qu

30、ot;300" MinHeight="300" MaxWidth="500"> <!-MinHeight="300" MaxWidth="500"限制窗口的最小高度和最大寬度-> <Grid x:Name="grid"> <!-定義行-> <Grid.RowDefinitions> <RowDefinition Height="25" ></RowDefinition> <RowDe

31、finition Height="50"/> <RowDefinition Height="1*"/> <RowDefinition Height="*"/> <RowDefinition Height="auto"> </RowDefinition> </Grid.RowDefinitions> <!-定義列-> <Grid.ColumnDefinitions> <ColumnDefinition Width=&quo

32、t;25" ></ColumnDefinition> <ColumnDefinition Width="50"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="auto"/> </Grid.ColumnDefinitions> <!-在指定的行列中布置控件-> <TextBox Gri

33、d.Column="1" Grid.Row="2" Grid.ColumnSpan="2" Text="布局" Background="Gray"/> </Grid></Window>運行效果圖如圖6,可以放大觀察效果(是因為Width="*"的原因,本例子中利用了兩個*其中第三行是一個*,所以占剩余的二分之一,可以試著改成2*,就是三分之二了,可以試著觀察效果):圖63.3 StackPanelStackPanel可以把內部的元素在縱向或者橫向

34、上緊密排列,形成棧式布局。先介紹一下其三個屬性:· Orientation 決定內部元素是橫向還是縱向累積。可取值為Horizontal,Vertical。· HorizontalAlignment 決定內部元素水平方向上的對齊方式。可取值Left,Center,Right,Stretch。· VerticalAlignment 決定內部元素豎直方向上的對齊方式。可取Top,Center,Bottom,Stretch。StackPanel也是布局中比較常見的控件,下面舉例:添加按鈕,其他內容控件會自動下移。效果如圖7:圖7下面上代碼:XAML<Window

35、x:Class="Chapter_03.StackPanel" xmlns=" xmlns:x=" Title="StackPanel" Height="338" Width="423"> <Grid Height="286" Width="382"> <GroupBox Header="測試StackPanel" BorderBrush="Black" Margin="5"

36、;> <StackPanel Margin="5" x:Name="stackpanel"> <StackPanel Orientation="Vertical" x:Name="btnList"></StackPanel> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <TextBlock Text="填寫添加按鈕名稱

37、: " Height="20" /> <TextBox Name="btnName" Width="102" Height="20" /> <Button Content="添加" Width="60" Margin="5" Click="Button_Click" /> </StackPanel> </StackPanel> </GroupBox> </

38、Grid></Window>Csusing System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imag

39、ing;using System.Windows.Shapes;namespace Chapter_03 / <summary> / StackPane_.xaml 的交互邏輯 / </summary> public partial class StackPanel : Window public StackPanel() InitializeComponent(); private void Button_Click(object sender, RoutedEventArgs e) if (!string.IsNullOrEmpty(this.btnName.Tex

40、t) Button btn = new Button(); btn.Content = this.btnName.Text; this.btnList.Children.Add(btn); else MessageBox.Show("請輸入按鈕名稱!"); 當輸入按鈕名稱的話,點擊添加,原有的內容會下移。3.4 Canvas畫布:內容控件可以準確定位到指定坐標,但是不足的地方是,如果要修改的話可能會關系到很多的控件,所以如果不需要經常修改的窗體,使用該控件布局,或者是藝術性比較強(用來實現依賴于橫縱坐標的動畫等功能)的布局使用此控件布局。在此制作一個登陸頁面主要來看一下Ca

41、nvas.Left與Canvas.Top的用法。效果圖如圖8,直接上代碼:XAML<Window x:Class="Chapter_03.Canvas" xmlns=" xmlns:x=" Title="登陸" Height="145" Width="300"> <Canvas Background="Sienna"> <TextBlock Canvas.Left="0" Canvas.Top="13" M

42、argin="5" Text="用戶名:"/> <TextBox Canvas.Left="50" Canvas.Top="13" Width="160" /> <TextBlock Canvas.Left="0" Canvas.Top="47" Margin="5" Text="密 碼:"/> <TextBox Canvas.Left="50" Canvas.

43、Top="47" Width="160" /> <Button Content="確定" Canvas.Left="70" Canvas.Top="77" Width="63" Height="22" /> <Button Canvas.Left="150" Canvas.Top="77" Content="清除" Width="63" Height=&

44、quot;22" /> </Canvas></Window>圖83.5 DockPanel這個控件主要有個最后一個內容控件實現填充所有剩余部分的功能。主要用到LastChildFill=True屬性。下面給出一個例子,先看一下把LastChildFill分別設置為True和False的結果對比圖如圖9:圖9XAML代碼給出: XAML<Window x:Class="Chapter_03.DockPanel" xmlns=" xmlns:x=" Title="DockPanel" Heig

45、ht="300" Width="300"> <DockPanel Name="dockpanel" LastChildFill="True"> <Button Name="button1" DockPanel.Dock="Top">1</Button> <Button Name="button2" DockPanel.Dock="Bottom" >2</Button> &

46、lt;Button Name="button3" DockPanel.Dock="Left">3</Button> <Button Name="button4" DockPanel.Dock="Right">4</Button> <Button DockPanel.Dock="Top">剩余空間</Button> </DockPanel></Window>在此說明一下,如果LastChildFill=Tru

47、e,最后一個元素 <Button >剩余空間</Button>就會充滿其剩余部分。上面的只能填充,但是不能通過拖拽的方式改變控件的寬度。下面給出一個實現拖拽功能的代碼。不過是在Grid里面的通過GridSplitter(可以改變Grid初始設置的行高或列寬)控件實現。直接給出代碼:XAML<Window x:Class="Chapter_03.GridSplitter" xmlns=" xmlns:x=" Title="GridSplitter" Height="300" Width="300"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="5"/> <RowDefinition/> </

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論