WPF學(xué)習(xí)之深入淺出話模板_第1頁
WPF學(xué)習(xí)之深入淺出話模板_第2頁
WPF學(xué)習(xí)之深入淺出話模板_第3頁
WPF學(xué)習(xí)之深入淺出話模板_第4頁
WPF學(xué)習(xí)之深入淺出話模板_第5頁
已閱讀5頁,還剩67頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、WPF學(xué)習(xí)之深入淺出話模板 圖形用戶界面應(yīng)用程序較之控制臺(tái)界面應(yīng)用程序最大的好處就是界面友好、數(shù)據(jù)顯示直觀。CUI程序中數(shù)據(jù)只能以文本的形式線性顯示,GUI程序則允許數(shù)據(jù)以文本、列表、圖形等多種形式立體顯示。用戶體驗(yàn)在GUI程序設(shè)計(jì)中起著舉足輕重的作用-用戶界面設(shè)計(jì)成什么樣看上去才足夠的漂亮?控件如何安排才簡(jiǎn)單易用并且少犯錯(cuò)誤?這些都是設(shè)計(jì)師需要考慮的問題。WPF系統(tǒng)不但支持傳統(tǒng)的Winfrom編程的用戶界面和用戶體驗(yàn)設(shè)計(jì),更支持使用專門的設(shè)計(jì)工具Blend進(jìn)行專業(yè)設(shè)計(jì),同時(shí)還推出了以模板為核心的新一代設(shè)計(jì)理念。1.1     模板的內(nèi)涵從字面上看,模板就是“具有一定規(guī)格的

2、樣板”,有了它,就可以依照它制造很多一樣是實(shí)例。我們常把看起來一樣的東西稱為“一個(gè)模子里面刻出來的。”就是這個(gè)道理。然而,WPF中的模板的內(nèi)涵遠(yuǎn)比這個(gè)深刻。Binding和基于Binding數(shù)據(jù)驅(qū)動(dòng)UI是WPF的核心部分,WPF最精彩的部分是什么呢?依我看,既不是美輪美奐的3D圖形,也不是炫目多彩的動(dòng)畫,而是默默無聞的模板(Template)。實(shí)際上,就連2D/3D繪圖也常常是為它錦上添花。Templdate究竟有什么能力能夠使得它在WPF體系中獲此殊榮呢?這還要從哲學(xué)談起,“形而上者謂之道,形而下者謂之器”,這句話出自易經(jīng),大意是我們能夠觀察到的世間萬物形象之上的抽象的結(jié)果就是思維,而形象之

3、下掩蓋的就是其本質(zhì)。顯然,古人已經(jīng)注意到“形”是連接本質(zhì)和思維的樞紐,讓我們把這句話引入計(jì)算機(jī)世界。“形而上者謂之道”指的就是基于現(xiàn)實(shí)世界對(duì)萬物進(jìn)行抽象封裝,理順?biāo)鼈冎g的關(guān)系,這個(gè)“道”不就是面向?qū)ο笏枷雴?!如果再把面向?qū)ο筮M(jìn)一步提升、總結(jié)出最優(yōu)的對(duì)象組合關(guān)系,“道”就上升為設(shè)計(jì)模式思想?!靶味抡咧^之氣”指的是我們能夠觀察到的世間萬物都是物質(zhì)類容的本質(zhì)表現(xiàn)形式?!氨举|(zhì)與表現(xiàn)”或者說“類容與形式”是哲學(xué)范疇內(nèi)的一對(duì)矛盾體。軟件之道并非本書研究的主要類容,本書研究的是WPF。WPF全稱Windows Presentation Foundation,Presentation一詞的意思就是外觀,呈

4、現(xiàn),表現(xiàn),也就是說,在WIndows GUI程序這個(gè)尺度上,WPF扮演的就是“形”的角色、是程序的外在形式,而程序的內(nèi)容仍然是由數(shù)據(jù)和算法構(gòu)成的業(yè)務(wù)邏輯。與WPF類似,Winform和A也都是內(nèi)容的表現(xiàn)形式。讓我們把尺度縮小到WPF內(nèi)部。這個(gè)系統(tǒng)與程序內(nèi)容(業(yè)務(wù)邏輯)的邊界是Binding,Binding把數(shù)據(jù)源源不斷從程序內(nèi)部送出來交由界面元素來顯示,又把從界面元素搜集到的數(shù)據(jù)傳回程序內(nèi)部。界面元素間的溝通則依靠路由事件來完成。有時(shí)候路由事件和附加事件也會(huì)參與到數(shù)據(jù)的傳輸中。讓我們思考一個(gè)問題:WPF作為Windows的表示方式,它究竟表示的是什么?換句話說,WPF作為一種“形式”,它表現(xiàn)的

5、內(nèi)容到底是什么?答案是程序的數(shù)據(jù)和算法-Binding傳遞的是數(shù)據(jù),事件參數(shù)攜帶的也是數(shù)據(jù);方法和委托的調(diào)用是算法,事件傳遞消息也是算法-數(shù)據(jù)在內(nèi)存里就是一串串字符或字符。算法是一組組看不見摸不著的抽象邏輯,如何恰如其分的把它們展現(xiàn)給用戶呢?加入想表達(dá)一個(gè)bool類型,同時(shí)還想表達(dá)用戶可以在這兩個(gè)值之間自由切換這樣一個(gè)算法,你會(huì)怎么做?你一定會(huì)想使用一個(gè)CheckBox控件來滿足要求;再比如顏色值實(shí)際上是一串?dāng)?shù)字,用戶基本上不可能只看數(shù)字就能想象出真正的顏色,而且用戶也不希望只靠輸入字符來表示顏色值,這時(shí),顏色值這一“數(shù)據(jù)內(nèi)容”的恰當(dāng)表現(xiàn)形式就是一個(gè)填充著真實(shí)顏色的色塊。,而用戶即可以輸入值又

6、可以用取色吸管取色來設(shè)置值的“算法內(nèi)容”恰當(dāng)?shù)谋磉_(dá)方式是創(chuàng)建一個(gè)ColorPicker控件。相信你已經(jīng)發(fā)現(xiàn),控件(Control)是數(shù)據(jù)內(nèi)容表現(xiàn)形式的雙重載體。換句話說,控件即是數(shù)據(jù)的表現(xiàn)形式讓用戶可以直觀的看到數(shù)據(jù),又是算法的表現(xiàn)形式讓用戶方便的操作邏輯。作為表現(xiàn)形式,每個(gè)控件都是為了實(shí)現(xiàn)某種用戶操作算法和直觀顯示某種數(shù)據(jù)而生,一個(gè)控件看上去是什么樣子由它的“算法內(nèi)容”和“數(shù)據(jù)內(nèi)容決定”,這就是內(nèi)容決定形式,這里,我們引入兩個(gè)概念:控件的算法內(nèi)容:值控件能展示哪些數(shù)據(jù)、具有哪些方法、能相應(yīng)哪些操作、能激發(fā)什么事件,簡(jiǎn)而言之就是控件的功能,它們是一組相關(guān)的算法邏輯??丶臄?shù)據(jù)內(nèi)容:控件具體展示

7、的數(shù)據(jù)是什么。以往的GUI開發(fā)技術(shù)(ASP.NET+Winform)中,控件內(nèi)部邏輯和數(shù)據(jù)是固定的,程序員不能改變;對(duì)于控件的外觀,程序員能做的改變也非常的有限,一般也就是設(shè)置控件的屬性,想改變控件的內(nèi)部結(jié)構(gòu)是不可能的。如果想擴(kuò)展一個(gè)控件的功能或者更改器外觀讓其更適應(yīng)業(yè)務(wù)邏輯,哪怕只是一丁點(diǎn)的改變,也需要?jiǎng)?chuàng)建控件的子類或者創(chuàng)建用戶控件。造成這個(gè)局面的根本原因是數(shù)據(jù)和算法的“形式”和“內(nèi)容”耦合的太緊了。在WPF中,通過引入模板微軟將數(shù)據(jù)和算法的內(nèi)容與形式接耦合了。WPF中的Template分為兩大類:ControlTemplate:是算法和內(nèi)容的表現(xiàn)形式,一個(gè)控件怎么組織其內(nèi)部結(jié)構(gòu)才能讓它更符

8、合業(yè)務(wù)邏輯、讓用戶操作起來更舒服就是由它來控制的。它決定了控件“長(zhǎng)成什么樣子”,并讓程序員有機(jī)會(huì)在控件原有的內(nèi)部邏輯基礎(chǔ)上擴(kuò)展自己的邏輯。DataTemplate:是數(shù)據(jù)內(nèi)容的展示方式,一條數(shù)據(jù)顯示成什么樣子,是簡(jiǎn)單的文本還是直觀的圖形就由它來決定了。Template就是數(shù)據(jù)的外衣-ControlTemplate是控件的外衣,DataTemplate是數(shù)據(jù)的外衣。下面讓我們欣賞兩個(gè)例子:WPF中控件不在具有固定的形象,僅僅是算法內(nèi)容或數(shù)據(jù)內(nèi)容的載體。你可以把控件理解為一組操作邏輯穿上了一套衣服,換套衣服就變成了另外一個(gè)模樣。你看到的控件默認(rèn)形象實(shí)際上就是出廠時(shí)微軟為它穿上的默認(rèn)衣服??吹较旅鎴D

9、中的溫度計(jì),你是不是習(xí)慣性的猜到是由若干控件和圖形拼湊起來的UserControl呢?實(shí)際上它是一個(gè)ProgressBar控件,只是我們的設(shè)計(jì)師為其設(shè)計(jì)了一套新衣服-這套衣服改變了其一些顏色、添加了一些裝飾品和刻度線并清除了脈搏動(dòng)畫,效果如下圖:WPF中數(shù)據(jù)顯示成什么樣子可以由自己來決定。比如下面這張圖,只是為數(shù)據(jù)條目準(zhǔn)備了一個(gè)DataTemplate,這個(gè)DataTemplate中用binding把一個(gè)TextBlock的Text屬性值關(guān)聯(lián)到數(shù)據(jù)對(duì)象的Year屬性上、把一個(gè)Rectangle的Width屬性和另外一個(gè)TextBlock的Text屬性關(guān)聯(lián)到數(shù)據(jù)對(duì)象的Price屬性上,并使用St

10、ackPanel和Grid為這幾個(gè)控件布局。一旦應(yīng)用了這個(gè)DataTemplate,單調(diào)的數(shù)據(jù)就變成了直觀的柱狀圖,如下圖所示。以往這項(xiàng)工作不但需要先創(chuàng)建用于展示數(shù)據(jù)的UserControl,還要為UserControl添加顯示/回寫數(shù)據(jù)的代碼。如果別的項(xiàng)目中也需要用到這個(gè)柱狀圖,你要做的事情只是將這個(gè)XAML代碼發(fā)給他們。其代碼如下:html view plain copy print?<DataTemplate>       <Grid>     

11、      <StackPanel Orientation="Horizontal">               <Grid>                 &#

12、160; <Rectangle Stroke="Yellow" Fill="Orange" Width="Binding Price"></Rectangle>                   <TextBlock Text="Binding&#

13、160;Year"></TextBlock>               </Grid>               <TextBlock Text="Binding Price" Margin=&quo

14、t;5,0"></TextBlock>           </StackPanel>       </Grid>   </DataTemplate>   <DataTemplate> <Grid> <StackPanel Orientation="Horizont

15、al"> <Grid> <Rectangle Stroke="Yellow" Fill="Orange" Width="Binding Price"></Rectangle> <TextBlock Text="Binding Year"></TextBlock> </Grid> <TextBlock Text="Binding Price" Margin="5,0"></

16、TextBlock> </StackPanel> </Grid> </DataTemplate>我想,盡管你還沒有學(xué)習(xí)什么DataTempldate,但借助前面學(xué)習(xí)的基礎(chǔ)一樣可以看個(gè)八九不離十了。1.2       數(shù)據(jù)的外衣DataTemplate“橫看成嶺側(cè)成峰,遠(yuǎn)近高低各不同”廬山的美景如此,數(shù)據(jù)又何嘗不是這樣呢?同樣一條數(shù)據(jù),比如具有ID、Name、PhoneNumber、Address等Student的實(shí)例,放在GridView里面有時(shí)可能是簡(jiǎn)單的文本、每個(gè)單元格只顯示一個(gè)屬性;放在ListBox里面有時(shí)為了避免

17、單調(diào)可以在最左端顯示一個(gè)64*64的小圖像,再將其它信息分兩行顯示在其后面;如果單獨(dú)顯示一個(gè)學(xué)生信息則可以用類似簡(jiǎn)歷的復(fù)雜格式來展現(xiàn)學(xué)生的全部數(shù)據(jù)。一樣的內(nèi)容可以用不同的形式來展現(xiàn),軟件設(shè)計(jì)稱之為“數(shù)據(jù)-視圖”模式。以往的開發(fā)技術(shù),如MFC、Winform、A等,視圖要靠UserControl來實(shí)現(xiàn)。WPF不但支持UserControl還支持DataTemplate為數(shù)據(jù)形成視圖。不要以為DataTempldate有多難!從Control升級(jí)到DataTemplate一般就是復(fù)制,粘貼一下再改幾個(gè)字符的事兒。DataTempldate常用的地方有三處,分別是:ContentControl的Co

18、ntentTempldate屬性,相當(dāng)于給ContentControl的內(nèi)容穿衣服。ItemControl的ItemTemplate,相當(dāng)于給ItemControl的數(shù)據(jù)條目穿衣服。GridViewColumn的CellTempldate屬性,相當(dāng)于給GridViewColumn的數(shù)據(jù)條目穿衣服。讓我們用一個(gè)例子對(duì)比UserControl和DataTemplate的使用。例子實(shí)現(xiàn)的需求是這樣的:有一列汽車數(shù)據(jù),這列數(shù)據(jù)顯示在ListBox里面,要求ListBox的條目顯示汽車的廠商圖標(biāo)和簡(jiǎn)要參數(shù),單擊某個(gè)條目后在窗體的詳細(xì)內(nèi)容區(qū)顯示汽車的圖片和詳細(xì)參數(shù)。無論是使用UserControl還是Da

19、taTemplate,廠商的Logo和汽車的照片都是要用到的,所以先在項(xiàng)目中建立資源管理目錄并把圖片添加進(jìn)來。Logo文件名與廠商的名稱一致,照片的名稱則與車名一致。組織結(jié)構(gòu)如圖:首先創(chuàng)建Car數(shù)據(jù)類型:csharp view plain copy print?public class Car                public string AutoMark  get

20、; set;           public string Name  get; set;           public string Year  get; set;        &

21、#160;  public string TopSpeed  get; set;         public class Car public string AutoMark get; set; public string Name get; set; public string Year get; set; public string TopSpeed get; set; 為了在ListBox里面顯示Car類型的數(shù)據(jù),我們需要準(zhǔn)備一

22、個(gè)UserControl。命名為CarListItemView。這個(gè)UserControl由一個(gè)Car類型實(shí)例在背后支持,當(dāng)設(shè)置這個(gè)實(shí)例的時(shí)候,界面元素將實(shí)例的屬性值顯示在各個(gè)控件里。CarListItemView的XAML代碼如下:html view plain copy print?<UserControl x:Class="WpfApplication1.CarListViewItem"              

23、 xmlns="             xmlns:x="    <Grid Margin="2">          <StackPanel Orientation="Horizontal"> 

24、0;            <Image x:Name="igLogo" Grid.RowSpan="3" Width="64" Height="64"></Image>              

25、;<StackPanel Margin="5,10">                  <TextBlock x:Name="txtBlockName" FontSize="16" FontWeight="Bold"></TextBlock> 

26、0;                <TextBlock x:Name="txtBlockYear" FontSize="14"></TextBlock>              </StackPanel&g

27、t;          </StackPanel>      </Grid>  </UserControl>  <UserControl x:Class="WpfApplication1.CarListViewItem" xmlns=" xmlns:x=" <Grid Margin="2"&

28、gt; <StackPanel Orientation="Horizontal"> <Image x:Name="igLogo" Grid.RowSpan="3" Width="64" Height="64"></Image> <StackPanel Margin="5,10"> <TextBlock x:Name="txtBlockName" FontSize="16" FontW

29、eight="Bold"></TextBlock> <TextBlock x:Name="txtBlockYear" FontSize="14"></TextBlock> </StackPanel> </StackPanel> </Grid></UserControl>CarlistItemView用于支持前臺(tái)顯示屬性C#代碼為:csharp view plain copy print?/ <summary> &#

30、160;/ CarListViewItem.xaml 的交互邏輯  / </summary>  public partial class CarListViewItem : UserControl        public CarListViewItem()          

31、;      InitializeComponent();              private Car car;        public Car Car          

32、;      get  return car;           set                        car = val

33、ue;              this.txtBlockName.Text = car.Name;              this.txtBlockYear.Text = car.Year;       

34、;       this.igLogo.Source = new BitmapImage(new Uri("Resource/Image/"+car.AutoMark+".png",UriKind.Relative);                   &#

35、160; / <summary> / CarListViewItem.xaml 的交互邏輯 / </summary> public partial class CarListViewItem : UserControl public CarListViewItem() InitializeComponent(); private Car car; public Car Car get return car; set car = value; this.txtBlockName.Text = car.Name; this.txtBlockYear.Text = car.Y

36、ear; this.igLogo.Source = new BitmapImage(new Uri("Resource/Image/"+car.AutoMark+".png",UriKind.Relative); 類似的原理,我們需要為Car類型準(zhǔn)備一個(gè)詳細(xì)信息視圖。UserControl名稱為CarDetailView,XAML部分代碼如下:html view plain copy print?<UserControl x:Class="WpfApplication1.CarDetailView" 

37、0;             xmlns="             xmlns:x="    <Border BorderBrush="Black" BorderThickness="1" Corner

38、Radius="6">          <StackPanel>              <Image x:Name="imgPhoto" Width="400" Height="250"></Image>

39、;              <StackPanel Orientation="Horizontal" Margin="5,0">                  <TextBlock Te

40、xt="Name:" FontSize="20" FontWeight="Bold"></TextBlock>                  <TextBlock x:Name="txtBlockName" FontSize="20" Mar

41、gin="5,0"></TextBlock>              </StackPanel>              <StackPanel Orientation="Horizontal" Margin="

42、;5,0">                  <TextBlock Text="AutoMark:" FontWeight="Bold"></TextBlock>             

43、     <TextBlock x:Name="txtBlockAutoMark" Margin="5,0"></TextBlock>                  <TextBlock Text="Year:" FontWeight=

44、"Bold">                                        </TextBlock>   

45、0;                  <TextBlock x:Name="txtBlockYear" Margin="5,0">                  

46、  </TextBlock>                  <TextBlock Text="Top Speed:" FontWeight="Bold">            &#

47、160;                           </TextBlock>                  <Text

48、Block x:Name="txtTopSpeed" Margin="5,0">                                      

49、;  </TextBlock>              </StackPanel>          </StackPanel>      </Border>  </UserControl>

50、0; <UserControl x:Class="WpfApplication1.CarDetailView" xmlns=" xmlns:x=" <Border BorderBrush="Black" BorderThickness="1" CornerRadius="6"> <StackPanel> <Image x:Name="imgPhoto" Width="400" Height="250&

51、quot;></Image> <StackPanel Orientation="Horizontal" Margin="5,0"> <TextBlock Text="Name:" FontSize="20" FontWeight="Bold"></TextBlock> <TextBlock x:Name="txtBlockName" FontSize="20" Margin="5,0&q

52、uot;></TextBlock> </StackPanel> <StackPanel Orientation="Horizontal" Margin="5,0"> <TextBlock Text="AutoMark:" FontWeight="Bold"></TextBlock> <TextBlock x:Name="txtBlockAutoMark" Margin="5,0"></Text

53、Block> <TextBlock Text="Year:" FontWeight="Bold"> </TextBlock> <TextBlock x:Name="txtBlockYear" Margin="5,0"> </TextBlock> <TextBlock Text="Top Speed:" FontWeight="Bold"> </TextBlock> <TextBlock x:N

54、ame="txtTopSpeed" Margin="5,0"> </TextBlock> </StackPanel> </StackPanel> </Border></UserControl>后臺(tái)支持?jǐn)?shù)據(jù)大同小異:csharp view plain copy print?/ <summary>  / CarDetailView.xaml 的交互邏輯  / </summary> 

55、 public partial class CarDetailView : UserControl        public CarDetailView()                InitializeComponent();    

56、0;         private Car car;        public Car Car                get  return car;   &

57、#160;       set                        car = value;              

58、this.txtBlockName.Text = car.Name;              this.txtBlockAutoMark.Text = car.AutoMark;              this.txtBlockYear.Text = c

59、ar.Year;              this.txtTopSpeed.Text = car.TopSpeed;              this.imgPhoto.Source = new BitmapImage(new Uri("Reso

60、urce/Image/" + car.Name + ".jpg", UriKind.Relative);                     / <summary> / CarDetailView.xaml 的交互邏輯 / </summary> public partial class Ca

61、rDetailView : UserControl public CarDetailView() InitializeComponent(); private Car car; public Car Car get return car; set car = value; this.txtBlockName.Text = car.Name; this.txtBlockAutoMark.Text = car.AutoMark; this.txtBlockYear.Text = car.Year; this.txtTopSpeed.Text = car.TopSpeed; this.imgPhot

62、o.Source = new BitmapImage(new Uri("Resource/Image/" + car.Name + ".jpg", UriKind.Relative); 最后把它們組裝到窗體上:html view plain copy print?<Window x:Class="WpfApplication1.Window35"          xmlns="  

63、0;     xmlns:x="        Title="Window35" Height="350" Width="623" xmlns:my="clr-namespace:WpfApplication1">      <StackPanel Orientati

64、on="Horizontal" Margin="5">          <my:CarDetailView x:Name="carDetailView1" />          <ListBox x:Name="listBoxCars" Wi

65、dth="180" Margin="5,0" SelectionChanged="listBoxCars_SelectionChanged">                        </ListBox>    &#

66、160; </StackPanel>  </Window>  <Window x:Class="WpfApplication1.Window35" xmlns=" xmlns:x=" Title="Window35" Height="350" Width="623" xmlns:my="clr-namespace:WpfApplication1"> <StackPanel Orient

67、ation="Horizontal" Margin="5"> <my:CarDetailView x:Name="carDetailView1" /> <ListBox x:Name="listBoxCars" Width="180" Margin="5,0" SelectionChanged="listBoxCars_SelectionChanged"> </ListBox> </StackPanel>

68、;</Window>窗體的后臺(tái)代碼如下:csharp view plain copy print?using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.Windows;  using System.Windows.Controls;  using 

69、;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 WpfAppl

70、ication1        / <summary>      / Window35.xaml 的交互邏輯      / </summary>      public partial class Window35 : Win

71、dow                public Window35()                        InitializeComponent();  &

72、#160;           InitialCarList();                      private void listBoxCars_SelectionChanged(object sender, Sel

73、ectionChangedEventArgs e)                        CarListViewItem viewItem = e.AddedItems0 as CarListViewItem;       

74、;       if(viewItem!=null)                                carDetailView1.Car = viewItem.Car;

75、60;                                   private void InitialCarList()        

76、                List<Car> infos = new List<Car>()                new Car() AutoMark="Aodi&quo

77、t;, Name="Aodi", TopSpeed="200", Year="1990",              new Car() AutoMark="Aodi", Name="Aodi", TopSpeed="250", Year="1998

78、",              new Car() AutoMark="Aodi", Name="Aodi", TopSpeed="300", Year="2002",            

79、0; new Car() AutoMark="Aodi", Name="Aodi", TopSpeed="350", Year="2011",              new Car() AutoMark="Aodi", Name="Aodi",&

80、#160;TopSpeed="500", Year="2020"                            foreach (Car item in infos)    

81、0;                           CarListViewItem viewItem = new CarListViewItem();           &

82、#160;      viewItem.Car = item;                  this.listBoxCars.Items.Add(viewItem);              

83、                        public class Car                public string AutoMark&#

84、160; get; set;           public string Name  get; set;           public string Year  get; set;      

85、     public string TopSpeed  get; set;           using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows;using System.Windows.Controls;using System.

86、Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Shapes;namespace WpfApplication1 / <summary> / Window35.xaml 的交互邏輯 / </summary> public partial class Window35 : Window public Window35

87、() InitializeComponent(); InitialCarList(); private void listBoxCars_SelectionChanged(object sender, SelectionChangedEventArgs e) CarListViewItem viewItem = e.AddedItems0 as CarListViewItem; if(viewItem!=null) carDetailView1.Car = viewItem.Car; private void InitialCarList() List<Car> infos = n

88、ew List<Car>() new Car() AutoMark="Aodi", Name="Aodi", TopSpeed="200", Year="1990", new Car() AutoMark="Aodi", Name="Aodi", TopSpeed="250", Year="1998", new Car() AutoMark="Aodi", Name="Aodi", T

89、opSpeed="300", Year="2002", new Car() AutoMark="Aodi", Name="Aodi", TopSpeed="350", Year="2011", new Car() AutoMark="Aodi", Name="Aodi", TopSpeed="500", Year="2020" ; foreach (Car item in infos) CarLi

90、stViewItem viewItem = new CarListViewItem(); viewItem.Car = item; this.listBoxCars.Items.Add(viewItem); public class Car public string AutoMark get; set; public string Name get; set; public string Year get; set; public string TopSpeed get; set; 運(yùn)行并單擊Item項(xiàng),運(yùn)行效果如下圖:很難說這樣做是錯(cuò)的,但是WPF里面如此實(shí)現(xiàn)需求真的是浪費(fèi)了數(shù)據(jù)驅(qū)動(dòng)界面這

91、一重要功能。我們常說把WPF當(dāng)作Winform來用指的就是這種實(shí)現(xiàn)方法。這種做法對(duì)WPF最大的曲解就是沒有借助Binding來實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)界面,并且認(rèn)為L(zhǎng)istBoxItem里面放置的控件-這種曲解迫使數(shù)據(jù)在界面元數(shù)據(jù)間交換并且程序員只能通過事件驅(qū)動(dòng)方式來實(shí)現(xiàn)邏輯-程序員必須借助處理ListBox的SelecttionChanged事件來推動(dòng)DetaIlView來顯示數(shù)據(jù),而數(shù)據(jù)又是由CarListItemView控件轉(zhuǎn)交給CarDetailView的,之間還做了一次類型轉(zhuǎn)換。下圖用于說明事件驅(qū)動(dòng)模式與期望中數(shù)據(jù)驅(qū)動(dòng)界面模式的不同:顯然,事件驅(qū)動(dòng)是控件和控件之間溝通或者說是形式和形式之間的溝通

92、,數(shù)據(jù)驅(qū)動(dòng)則是數(shù)據(jù)與控件之間的溝通,是內(nèi)容決定形式。使用DataTemplate就可以方便的把事件驅(qū)動(dòng)模式轉(zhuǎn)換為數(shù)據(jù)驅(qū)動(dòng)模式。你是不是擔(dān)心前面寫的代碼會(huì)被刪掉呢?不會(huì)的!由UserControl升級(jí)為DataTemplate時(shí)90%的代碼是Copy,10%的代碼可以方向刪除,再做一點(diǎn)點(diǎn)改動(dòng)就可以了。讓我們來試試看。首先把連個(gè)UserControl的芯剪切出來,用DataTempldate進(jìn)行包裝,再放到主窗體的資源字典里。最重要的是為DataTemplate里面的每一個(gè)控件設(shè)置Binding,告訴各個(gè)控件應(yīng)該關(guān)注的是數(shù)據(jù)的哪個(gè)屬性。因?yàn)槭褂肂Inding在控件和數(shù)據(jù)間建立關(guān)聯(lián),免去了在C#代碼中訪問界面元素,所以XAML代碼中的大部分x:Name

溫馨提示

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

評(píng)論

0/150

提交評(píng)論