版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 物流倉庫經(jīng)理年度述職報(bào)告
- 智慧教室裝修方案
- 從業(yè)人員安全生產(chǎn)教育培訓(xùn)
- 孕期糖尿病飲食和護(hù)理
- 老年人糖尿病病人的護(hù)理
- 齲齒病的發(fā)展過程圖解
- 2.3.1物質(zhì)的量的單位-摩爾 課件高一上學(xué)期化學(xué)人教版(2019)必修第一冊(cè)
- 吉林省2024七年級(jí)數(shù)學(xué)上冊(cè)第1章有理數(shù)1.10有理數(shù)的除法課件新版華東師大版
- 吉林省2024七年級(jí)數(shù)學(xué)上冊(cè)第1章有理數(shù)全章整合與提升課件新版華東師大版
- 深度學(xué)習(xí)及自動(dòng)駕駛應(yīng)用 課件 第9、10章 生成對(duì)抗網(wǎng)絡(luò)及自動(dòng)駕駛應(yīng)用、強(qiáng)化學(xué)習(xí)理論及自動(dòng)駕駛應(yīng)用實(shí)踐
- 仿制藥一致性與BE試驗(yàn)
- 絕交協(xié)議書模板
- 管理經(jīng)濟(jì)學(xué)課后答案
- 《波特價(jià)值鏈模型》課件
- 學(xué)術(shù)規(guī)范與學(xué)術(shù)道德課件
- 中考數(shù)學(xué)復(fù)習(xí)《圓》專題訓(xùn)練-附帶有答案
- 數(shù)據(jù)倉庫與AI應(yīng)用整合
- 2023年版勞動(dòng)合同法全文
- 《交換機(jī)基礎(chǔ)原理》培訓(xùn)課件
- 人教版-初中-道德與法治-《共圓中國(guó)夢(mèng)》說課稿
- 短視頻的拍攝與剪輯
評(píng)論
0/150
提交評(píng)論