日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

WPF控件和布局

發(fā)布時間:2023/12/2 asp.net 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WPF控件和布局 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  WPF控件和布局,根據(jù)劉鐵猛《深入淺出WPF》書籍講解內(nèi)容,主要記錄控件和布局的原理,如果有不足的地方,請大牛們鍵盤下留情--輕噴!如果還算有用,請給點動力,支持一把!

一、WPF里的控件

1.1 控件的實質(zhì)

  我們先從UI上分析,UI的功能是讓用戶觀察和操作數(shù)據(jù),為了能顯示數(shù)據(jù)和響應(yīng)用戶的操作通知程序(通過事件來通知,如何處理事件又是一系列的算法),所以控件就是顯示數(shù)據(jù)和響應(yīng)用戶操作的UI元素,也即:控件就是數(shù)據(jù)和行為的載體。?

1.2 WPF中的一個重要概念--數(shù)據(jù)驅(qū)動UI

  什么是數(shù)據(jù)驅(qū)動UI呢?我們知道傳統(tǒng)的GUI界面都是由windows消息通過事件傳遞給程序,程序根據(jù)不同的操作來表達出不同的數(shù)據(jù)體現(xiàn)在UI界面上,這樣數(shù)據(jù)在某種程度上來說,受到很大的限制。WPF中是數(shù)據(jù)驅(qū)動UI,數(shù)據(jù)是核心,處于主動的,UI從屬于數(shù)據(jù)并表達數(shù)據(jù),是被動的。因為以后的章節(jié)會重點介紹,在此不做過多的說明,只要記著,WPF數(shù)據(jù)第一,控件第二。

1.3 WPF中控件的知多少

  雖然控件沒有數(shù)據(jù)重要,但是還是比較重要的,畢竟是門面啊,只是在數(shù)據(jù)面前,它比較"有禮貌"。控件有很多,但是如果仔細去分析,也是有規(guī)律可循的,根據(jù)其作用,我們可以把控件分為6類:

  • 布局控件:是可以容納多個控件或者嵌套其他布局的控件,用于在UI上組織和排列控件。其父類為Panel。
  • 內(nèi)容控件:只能容納一個控件或者布局控件作為他的內(nèi)容。所以經(jīng)常借助布局控件來規(guī)劃其內(nèi)容。其父類為ContentControl。
  • 帶標題內(nèi)容控件:相當(dāng)于一個內(nèi)容控件,但是可以加一個標題,標題部分也可以容納一個控件或者布局,其父類為HeaderedContentControl。
  • 條目控件:可以顯示一列數(shù)據(jù),一般情況下,是數(shù)據(jù)的類型是相同的。其共同的基類為ItemsControl。
  • 帶標題的條目控件:和上面的帶標題內(nèi)容控件類同,其基類為HeaderdeItemsControl。
  • 特殊內(nèi)容控件:這類控件比較獨立,但也比較常用,如TextBox,TextBlock,Image等(由于其常用性和相對比較簡單,本篇筆記不做說明)。

上面的控件的派生關(guān)系如圖1:

圖1

二、各類控件模型詳解

2.1 WPF中的內(nèi)容模型  

  為了理解各個控件的模型,還是先了解一下WPF中的內(nèi)容模型。在上述各類控件里,至少可以容納一個內(nèi)容,主要原因是由于每個控件對象都會有一個重要又不常寫出來的屬性--Content Property(有Content,Child,Items,Children幾個屬性,如Grid可以容納多個控件,用的是Children)。內(nèi)容模型就是每一族的控件都含有一個或者多個元素作為其內(nèi)容(其下面的元素可能是其他控件)。為什么可以不常寫出來呢?先讓我們看下面兩段代碼:

XAML Code <Window x:Class="Chapter_03.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="內(nèi)容屬性測試" Height="350" Width="525"><Grid><Grid.Children><Button Content="1" Margin="120,146,0,146" HorizontalAlignment="Left" Width="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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="內(nèi)容屬性測試" 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,146,142,145" HorizontalAlignment="Right" Width="82" /></Grid> </Window>

運行兩段代碼效果一樣。充分說明了重要而有不常見的原因。因為省略的省時,而且簡潔明了。所以多數(shù)引用時都省去了。

2.2ContentControl族

  先說一下其特點:他們內(nèi)容屬性的名稱為Content,只能有單一元素充當(dāng)其內(nèi)容。下面通過例子說明其特點:

<Button Margin="120,146,0,76" HorizontalAlignment="Left" Width="100"><TextBox Text="測試"/><TextBox Text="測試"/><TextBox Text="測試"/></Button>

上面的會報錯,原因是Button里面只能有單一元素充當(dāng)其內(nèi)容。去掉后面的兩個TextBox,效果如圖2:

?

圖2

發(fā)現(xiàn)button里面不僅可以顯示文字還可以用一個控件來當(dāng)其內(nèi)容。其他的控件不在一一舉例。在此列出此類的主要控件:

Button、ButtonBase、CheckBox、ComboBoxItem、ContentControl、Frame、GridViewColumnHeader、GropItem、Label、ListBoxItem、ListViewItem、NavigationWindow、RadioButton、ScrollViewer、StatusBarItem、ToggleButton、ToolTip、UserControl、Window。

2.3 HeaderedContentControl族

  特點:可以顯示帶標題的數(shù)據(jù),內(nèi)容屬性為Content和Header,其這兩個屬性都只能容納一個元素。在此舉例說明GroupBox的用法,然后列出其他屬于此類的控件。XAML代碼為:

View Code <Window x:Class="Chapter_03.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="內(nèi)容屬性測試" Height="200" Width="300"><Grid Background="Gold"><GroupBox Margin="42,0,96,26"><GroupBox.Header><Label Content="我是標題"/></GroupBox.Header><Button HorizontalAlignment="Left" Width="117" Height="45"><TextBox Text="測試"/></Button></GroupBox></Grid> </Window>

效果圖如圖3:

圖3

是不是看著很還好呢?現(xiàn)在列出同類主要的控件:Expender,GroupBox,HeaderedContentControl,TabItem。

2.4 ItemsControl族

  特點:該類控件用于顯示列表化的數(shù)據(jù),內(nèi)容屬性為Items或ItemsSource,每種ItemsControl都對應(yīng)有自己的條目容器(Item Container)。本類元素可能會用的比較多些,也比較靈活,所以這里不做過多記錄,以后的記錄會經(jīng)常用到,具體的再詳細說明。下面就用一個ListBox控件來小試牛刀吧!XAML代碼、Cs代碼如下:

XAML <Window x:Class="Chapter_03.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="內(nèi)容屬性測試" 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="選擇"/><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="btn3" Content="按鈕1"/></ListBox></Grid> </Window> CS using 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.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=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="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 != null)MessageBox.Show(level3.GetType().ToString());else MessageBox.Show("無找到!");}} }

效果圖如圖4:

圖4

?  先來說明一下代碼:在listBox里面放了幾個checkbox和button,說明ListBoxI的Item不僅支持類型相同的元素,還支持類型不同的元素。這是因為,Listbox的每一項都是經(jīng)過“ListBoxItem”加工廠處理的,最終放入當(dāng)做自己的內(nèi)容--放入自己的容器內(nèi)。這里通過后臺代碼說明了每一個條目都被ListboxItem包裝過了,完全沒有必要每一個條目都在xmal文件按照如下寫法:

<ListBoxItem><Button x:Name="btn3" Content="按鈕1"/></ListBoxItem>

  在實際項目中,很少像上面那樣把代碼寫死,可以動態(tài)的綁定ListBox。把數(shù)據(jù)源賦給ListBox的ItemsSource,通過DisplayMemberPath屬性來顯示string類型的數(shù)據(jù)源里面的字段條目(如果想顯示復(fù)雜的數(shù)據(jù)的話,要使用DataTemplate,具體在模板再記錄,在此知道有這么一回事就好了);通過SelectedItem和SelectionChanged來觀察選中的項。下面的例子實現(xiàn)在listbox上綁定指定數(shù)據(jù),然后彈出選中人的年齡。直接給出代碼:

XAML <Window x:Class="Chapter_03.ListBoxTest"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="ListBoxTest" Height="300" Width="300"><Grid><ListBox x:Name="listbox1" Margin="0,0,60,31" SelectionChanged="listbox1_SelectionChanged"></ListBox></Grid> </Window> CS using 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.Imaging; using System.Windows.Shapes;namespace Chapter_03 {/// <summary>/// ListBoxTest.xaml 的交互邏輯/// </summary>public partial class ListBoxTest : Window{public ListBoxTest(){InitializeComponent();InitData();}protected void InitData(){List<People> peopleList = new List<People>(){new People(){Id=1,Name="Tim",Age=30},new People(){Id=2,Name="Tom",Age=30},

顯示結(jié)果如圖5:

圖5

  下面列出屬于ItemsControl族元素和其對應(yīng)的Item Container有ComboBox——ComboBoxItem,ContextMenu——MenuItem,ListBox——ListBoxItem,ListView——ListViewItem,Menu——MenuItem,StatusBar——StatusBarItem,TabControl——TabItem,TreeView——TreeViewItem.

  由于已經(jīng)演示了HeaderedContentControl和ItemsControl的功能,另外HeaderedItemsControl的用法就不再記錄了,僅僅列出屬于其族的控件:

  MemuItem、TreeViewItem、TooBar。

三、?UI布局

  在介紹布局之前還是先記錄一下布局控件的特點與屬于Panel族的控件。

  panel族控件內(nèi)容屬性為Children,所以內(nèi)容可以是多個元素,這對布局來說是很重要的特征。布局控件與ItemControl的區(qū)別是:前者強調(diào)的是對元素的布局,后者強調(diào)的是條目。屬于Panel類的控件有:Canvas,DockPanel,Grid,TabPanel,ToolBarOverflowPanel,StackPanel,ToolBarPanel,UniformGrid,VirtualizingPanel,VirtualizingStackPanel,WrapPanel。這么多控件不可能一個個去介紹,找?guī)讉€比較重要的實踐一下。回頭如果有用到的話再逐一研究。

3.1 主要布局控件的特性

  在WPF里面控件與控件的關(guān)系除了相鄰和重疊(用Opacity來控制哪個控件在上面,哪個在下面),還有一個包含。正因為如此,才有了以window為根的樹形結(jié)構(gòu)的XAML。下面介紹一下主要布局元素的特性:

  • Grid:網(wǎng)格。可以自定義行和列,并通過行列的數(shù)量、行高和列寬來調(diào)整控件的布局,有點類似于html中的Table。
  • StackPanel:棧式面板。可以將包含元素排成一條直線,當(dāng)添加或移除包含元素時,后面的元素會自動向下或向上移動。
  • Canvas:畫布。可以指定包含元素的絕對坐標位置。
  • DockPanel:泊靠式面板。內(nèi)部元素可以選擇泊靠方式。
  • WarpPanel:自動折行面板。當(dāng)一行元素排滿后會自動換行。類似html中的流式布局。

3.2 Grid

  Grid的特點如下:

  • 可以定義任意數(shù)量的行和列
  • 行高與列寬可以使用絕對值,相對比以及最大值和最小值
  • 內(nèi)部元素可以設(shè)置自己的所在列和行,還可以設(shè)置自己跨幾列和行。
  • 可以設(shè)置Children元素的對齊方式

  現(xiàn)在給出定義行與列的代碼(記得在后臺代碼上加上 this.grid.ShowGridLines=true以便顯示出網(wǎng)格):

XAML <Window x:Class="Chapter_03.Grid"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="Grid" Height="300" Width="300" MinHeight="300" MaxWidth="500"><!--MinHeight="300" MaxWidth="500"限制窗口的最小高度和最大寬度--><Grid x:Name="grid"><!--定義行--><Grid.RowDefinitions><RowDefinition Height="25" ></RowDefinition><RowDefinition Height="50"/><RowDefinition Height="1*"/><RowDefinition Height="*"/><RowDefinition Height="auto"></RowDefinition></Grid.RowDefinitions><!--定義列--><Grid.ColumnDefinitions><ColumnDefinition Width="25" ></ColumnDefinition><ColumnDefinition Width="50"/><ColumnDefinition Width="1*"/><ColumnDefinition Width="*"/><ColumnDefinition Width="auto"/></Grid.ColumnDefinitions><!--在指定的行列中布置控件--><TextBox Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="2" Text="布局" Background="Gray"/></Grid> </Window>

運行效果圖如圖6,可以放大觀察效果(是因為Width="*"的原因,本例子中利用了兩個*其中第三行是一個*,所以占剩余的二分之一,可以試著改成2*,就是三分之二了,可以試著觀察效果):

圖6

?3.3 StackPanel

  StackPanel可以把內(nèi)部的元素在縱向或者橫向上緊密排列,形成棧式布局。先介紹一下其三個屬性:

  • Orientation 決定內(nèi)部元素是橫向還是縱向累積。可取值為Horizontal,Vertical。
  • HorizontalAlignment 決定內(nèi)部元素水平方向上的對齊方式。可取值Left,Center,Right,Stretch。
  • VerticalAlignment 決定內(nèi)部元素豎直方向上的對齊方式。可取Top,Center,Bottom,Stretch。

StackPanel也是布局中比較常見的控件,下面舉例:添加按鈕,其他內(nèi)容控件會自動下移。效果如圖7:

圖7

下面上代碼:

XAML <Window x:Class="Chapter_03.StackPanel"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="StackPanel" Height="338" Width="423"><Grid Height="286" Width="382"><GroupBox Header="測試StackPanel" BorderBrush="Black" Margin="5"><StackPanel Margin="5" x:Name="stackpanel"><StackPanel Orientation="Vertical" x:Name="btnList"></StackPanel><StackPanel Orientation="Horizontal" HorizontalAlignment="Center"><TextBlock Text="填寫添加按鈕名稱: " Height="20" /><TextBox Name="btnName" Width="102" Height="20" /><Button Content="添加" Width="60" Margin="5" Click="Button_Click" /></StackPanel></StackPanel></GroupBox></Grid> </Window> Cs using 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.Imaging; 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.Text)){Button btn = new Button();btn.Content = this.btnName.Text;this.btnList.Children.Add(btn);}elseMessageBox.Show("請輸入按鈕名稱!");}} }

當(dāng)輸入按鈕名稱的話,點擊添加,原有的內(nèi)容會下移。

3.4 Canvas  

  畫布:內(nèi)容控件可以準確定位到指定坐標,但是不足的地方是,如果要修改的話可能會關(guān)系到很多的控件,所以如果不需要經(jīng)常修改的窗體,使用該控件布局,或者是藝術(shù)性比較強(用來實現(xiàn)依賴于橫縱坐標的動畫等功能)的布局使用此控件布局。

  在此制作一個登陸頁面主要來看一下Canvas.Left與Canvas.Top的用法。效果圖如圖8,直接上代碼:

XAML <Window x:Class="Chapter_03.Canvas"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="登陸" Height="145" Width="300"><Canvas Background="Sienna"><TextBlock Canvas.Left="0" Canvas.Top="13" Margin="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.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="22" /></Canvas> </Window>

?圖8

3.5 DockPanel

  這個控件主要有個最后一個內(nèi)容控件實現(xiàn)填充所有剩余部分的功能。主要用到LastChildFill=True屬性。下面給出一個例子,先看一下把LastChildFill分別設(shè)置為True和False的結(jié)果對比圖如圖9:

圖9

XAML代碼給出:?

XAML <Window x:Class="Chapter_03.DockPanel"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="DockPanel" Height="300" Width="300"><DockPanel Name="dockpanel" LastChildFill="True"><Button Name="button1" DockPanel.Dock="Top">1</Button><Button Name="button2" DockPanel.Dock="Bottom" >2</Button><Button Name="button3" DockPanel.Dock="Left">3</Button><Button Name="button4" DockPanel.Dock="Right">4</Button><Button DockPanel.Dock="Top">剩余空間</Button></DockPanel></Window>

  在此說明一下,如果LastChildFill=True,最后一個元素?<Button >剩余空間</Button>就會充滿其剩余部分。上面的只能填充,但是不能通過拖拽的方式改變控件的寬度。下面給出一個實現(xiàn)拖拽功能的代碼。不過是在Grid里面的通過GridSplitter(可以改變Grid初始設(shè)置的行高或列寬)控件實現(xiàn)。直接給出代碼:

XAML <Window x:Class="Chapter_03.GridSplitter"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="GridSplitter" Height="300" Width="300"><Grid><Grid.RowDefinitions><RowDefinition Height="5"/><RowDefinition/></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="150"/><ColumnDefinition Width="Auto"/><ColumnDefinition/></Grid.ColumnDefinitions><TextBox Grid.ColumnSpan="3" BorderBrush="Black"/><TextBox Grid.Row="1" BorderBrush="Black"/><GridSplitter Grid.Row="1" Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Center"Width="5" Background="Gray" ShowsPreview="True"/><TextBox Grid.Row="1" Grid.Column="2" BorderBrush="Black"/></Grid> </Window>

具體的GridSplitter的屬性見http://www.cnblogs.com/luluping/archive/2011/08/26/2155218.html。

3.6 WrapPanel

  此控件會根據(jù)布局的大小來控制內(nèi)容元素的排列。不會因為窗體沒有放大,影響到其他內(nèi)容的顯示。在此只舉一個例子,來理解WrapPanel。上代碼了:

XAML <Window x:Class="Chapter_03.WrapPanel"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="WrapPanel" Height="300" Width="300"><WrapPanel><Button Width="50" Height="50"/><Button Width="50" Height="50"/><Button Width="50" Height="50"/><Button Width="50" Height="50"/><Button Width="50" Height="50"/><Button Width="50" Height="50"/><Button Width="50" Height="50"/></WrapPanel> </Window>

效果圖如圖10:

  圖10

四、總結(jié)

  布局一直是自己的弱項,所以可能這篇記錄的會比較差點,但是重在理解控件的作用以及能舉一反三。?雖然控件沒有一一列出,但是對于每一族的控件都給出了一個實例,可以通過實例加深對各個控件的理解,具體的運用還需多加強練習(xí)和查閱msdn。下一篇:深入淺出話Binding。?

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/lzhp/archive/2012/09/05/2669764.html

總結(jié)

以上是生活随笔為你收集整理的WPF控件和布局的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。