【譯】Teach Yourself WPF in 24 Hours(Hour 3)
最近由于項目需要開始學習傳說中的WPF,呃,春哥好像有點生我的氣了,當我用神器Google找學習資料的時候找了好久都沒有找到。后來在電腦上發現了一個不知道什么時候下載下來的關于WPF的書,也就是我準備譯的這一本了。
譯此書有兩個目的:一、主要是學習WPF,完成項目
二、鳥文好久沒有動過了,不知道還能不能玩得動,這里溫習一下
由于不是資深鳥文專家,而且WPF也是新手,譯得不對之處大家多多指正。 呃,廢話就到這里,Let‘s Rock .
呃,還有點廢話,本書前面的二個小時就是對WPF的一些介紹,我就不費神去譯了,直接上第三小時實戰。
第三小時 Font Viewer 介紹
(其實就是做一個Font Viewer 字體查看器)
在這個小時中你將學到什么:
? 怎么建立一個新的WPF工程
? VS的一些基本知識
? 一個WPF工程的結構
? XAML文件
? 后臺代碼文件
在這個小時的課程中我們將打造第一個WPF應用程序——一個用來查看你的系統當前安裝的所有字體的輔助工具。我們也將學會如何在Visual Studio 中建立一個簡單的WPF工程。
建立Font Viewer
讓我們談談我們將建立的應用程序開始本節課程吧。
擁有一個輕量級的可以查看你當前系統所安裝的字體的輔助工具將是一件很方便的事情。另外,我們還可以輸入一些樣本文字來看看他在當前字體下的效果。
為了完成這個輔助工具我們需要:
? 一個ListBox來顯示當前系統安裝的所有字體
? 一個TextBox來輸入示例文字
? 一個可以用當前選中的字體演示樣例文字的地方
在Visual Studio 2008 中建立新的工程
我們將在Microsoft Visual C# 2008 Express Edition (見圖3.1)中進行開發。 這是一個同.Net3.5一起發布的特別版的Visual Studio。它本身就支持WPF程序的開發。如果你擁有的是其它版本的VS2008 ,也是可行的,當然你的步驟和本書也許會有一點點的區別。
下面是建立一個WPF工程的步驟:
1. 打開Visual Studio 。它在你的開始菜單中。
2. 在菜單欄中選擇 文件——新工程。
3. 選擇WPF應用程序模板,如圖3.2所示
4. 把你的應用程序命名為FontViewer然后單擊確定
(怎么感覺作者把讀者當白癡了,呃。。。學WPF的人應該都有這些基礎的吧)
圖3.1 Microsoft Visual C# 2008 Express Edition
圖片3.2 建立一個新的WPF應用程序
基本的工程文件
VS會自動的創建App.xaml,Window1.xaml以及和Window1.xaml相關聯的后臺代碼文件,然后Window1.xaml會顯示在你的IDE中。
XAML文件只包涵一些我們在“第二小時——理解XAML ”中討論過的標記。后臺代碼文件包涵一些額外的與XAML關聯的代碼(在本例中是C#代碼)。
App.xaml代表的是應用程序本身。它不是可視化的,主要用來保存整個應用程序要用到的資源。App.xaml同時還定義了應用程序加載時打開哪個窗體。
Window1.xaml是整個程序的主窗體。它里面的標記包涵了應用程序中所有的可視元素同時還聲明了程序的行為。
什么是后臺代碼?
在WPF應用程序中,每個XAML文件都有一個與之對應的的后臺代碼文件。后臺代碼文件和他的父文件同名并以.cs或.vb做為后綴名。因此Window1.xaml的后臺代碼文件就是Window1.xaml.cs。
在解決方案瀏覽器中,后臺代碼文件是它所關聯的文件的孩子(樹形結構顯示)。它們嵌套在其父文件的下面。
你可以在代碼編輯器中單擊右鍵選擇“查看代碼”或者“視圖設計器”分別在標記語言和代碼之間切換。注意,VS將會為XAML和后臺代碼各打開一個標簽。
分離你的關注點
使用后臺代碼文件的用意是讓開發人員把UI渲染開發和程序行為的開發分離開來,注重到各自的開發工作上去。WPF在這方面的實踐上比Windows Forms 和ASP.NET Web Forms都做得好,盡管這使我們很容易把這些東西混淆。(原句:Although it is still very easy to muddy the waters.不知道怎么翻了,呃。)
例如,假設一個有兩個人的團隊正在開發一個WPF應用程序,其中一個是美工另一個是碼工(呵呵,這樣譯出了我的心聲——都是民工)。碼工想實現一個允許用戶在一個ListBox中選取他最喜歡的顏色的功能。美工想要用一個調色板來展示用戶在ListBox中所選擇的顏色。這種情況下,美工可以編輯XAML文件以創建一個別致的ListBox而不用去改變任何碼工所寫好的代碼,同時也不會破壞整個應用程序。
這僅僅是把UI設計和行為邏輯編寫分開的好處的冰山一角。在本書中我們還將更多的討論這個概念和這么做的好處。
重命名XAML文件
我們剛剛創建的Font Viewer 應用程序現在在VS中打開了。如果我們按F5鍵,就會看見一個可以運行但是沒有任何用處的WPF應用程序。
VS默認提供的文件名并沒有多大的意義。根據其用途來命名文件、類、方法是一個很好的習慣。所以我們將要重命名Window1.xaml來表明它是整個程序的主窗體。
如果不小心的話,重命名VS中的項將會破壞整個應用程序。為了保證重命名窗體時文件間的關聯正確,我們需要這樣做:
1. 在解決方案瀏覽器中選擇Window1.xaml.
2. 按F2(同樣的,你也可以右鍵選擇重命名)。
3. 重命名Window1.xaml為MainWindow.xaml,這時我們會注意到VS自動的把與之關聯的后臺代碼文件也重命名了。但是,VS并沒有正確的重新引用新的文件名,也沒有改變內部類的名字。
4. 在解決方案管理器中雙擊App.xaml以在編輯器中打開它。
5. App.xaml的根標簽是 Application 標簽,Application標簽有一個名為StartUpUri的屬性。StartUpUri屬性指定了應用程序運行時顯示的主窗體。我們可以看見它還指向了舊的文件名Window1.xaml。現在我們把它改來指向MainWindow.xaml,修改后的App.xaml看起來應該是這樣的:
<Application x:Class="FontViewer.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
6. 在代碼編輯器中打開MainWindow.xaml的后臺代碼即MainWindow.xaml.cs。我們注意到類仍然為Window1,重命名XAML文件并沒有改變類名。
7. 為了避免混淆,我們把類名改為和文件名相匹配。右擊類名,選擇重構——重命名,輸入MainWindow做為新的類名,單擊確定然后單擊應用。你也可以在菜單樣中選擇重構——重命名如圖3.3所示。
我們也會注意到VS并沒有把類前的注釋里的類名更正,所以我們把注釋里的類名也改過來——保證注釋與你的代碼同步更新是一個很好的習慣。
8. 最后,在MainWindow.xaml文件的標記中,我們還需要把引用的類改為正確的類。標記語言的根標簽是 Window,它擁有一個屬性x:Class。我們要把這個屬性改為類的全名——包括命名空間,FontViewer.MainWindow.MainWindow.xaml。更正后MainWindow.xaml看起來應該是這樣的:
<Window x:Class="FontViewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Font Viewer"
Height="300"
Width="300">
<Grid>
</Grid>
</Window>
圖3.3在菜單欄中選擇重構
開發這個應用程序
在本小時課程的開始我們說過我們要做什么了——用我們的應用程序來顯示當前系統所安
裝的所有字體列表。我們還想讓程序擁有這樣的功能:在一個列表中選擇某個字體,然后在文本框中輸入一些示例文字看看這些文字在該字體下的效果。
讓一個程序更容易使用也是十分重要的,所以我們還將在程序中加入一些有用的提示性文字以及間隔來提升程序的可用性。
現在,讓我們開始加入這些特性吧:
1. 在代碼編輯器中打開MainWindow.xaml。默認情況下VS會用一個分割窗體顯示XAML文件。窗體中的設計視圖窗格會幾乎實時的顯示XAML文件的預覽效果,而XAML窗格則用來顯示標記語言本身。
2. 首先,讓我們給應用程序命以一個有意義的名字,它將會顯示在應用程序的標題欄中。更改Window標簽的Title屬性為Font Viewer。
3. 窗體的默認大小有些過小了。我們可以通過Window標簽的Height和Width屬性來改變窗體的大小。設置Height為480,Width為600。(單位px)
4. 現在定位到Grid標簽。Grid控件是允許你可視化的安排UI元素的控件之一。這些用于布局的控件被稱為面板——我們將在第四小時的課程“掌握應用程序布局”中詳細的討論它們。刪除Grid標簽。
5. 在剛才刪除了Grid的地方輸入<DockPanel。智能感知功能這時會出現,你可以簡單的從出現的列表中選擇DockPanel。(記住,在使用智能感知功能來輸入XAML標簽時要用<符號開始該標簽。DockPanel是另外一個類似Grid的用來布局UI元素的面板控件。DockPanel在布局類似VS和Microsoft Outlook這樣的應用程序時十分有用——它們當中的大部分UI元素都停靠在主窗體的邊緣上。更改后的XAML應該是這樣的:
<Window x:Class="FontViewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Font Viewer" Height="480" Width="600">
<DockPanel></DockPanel>
</Window>
6. 在DockPanel內輸入以下代碼:
<Border DockPanel.Dock="Top"
CornerRadius="6"
BorderThickness="1"
BorderBrush="Gray"
Background="LightGray"
Padding="8"
Margin="0 0 0 8">
</Border>
在設計視圖中可以看到應用程序的主窗體現在已經包涵了一個淺灰色的擁有圓角的矩形。在編輯XAML文件時記住不時的看看設計視圖,這樣你會更好的理解你正在輸入的標記——它們都實時的展現在了設計窗體中。
7. 給你的用戶一些引導總是十分有用的。所以,讓我們加入一些說明性的文字吧。在新加入的Border內部輸入以下內容:
<TextBlock FontSize="14"
TextWrapping="Wrap">
Select a font to view from the list below.
You can change the text by typing in the region at the bottom.
</TextBlock>
8. 現在我們將會向窗體中加入一個顯示系統當前安裝的所有字體的ListBox。在Border標簽的后面(但仍然在DockPanel標簽內部),加入以下內容:
<ListBox x:Name="FontList"
DockPanel.Dock="Left"
ItemsSource="{x:Static Fonts.SystemFontFamilies}"
Width="160" />
其中的ItemsSource屬性用來告訴ListBox它將要顯示的數據源。在本例中我們想要顯示的數據即當前系統所安裝的所有字體。.NET Framework 中的類 System.Windows.Media.Fonts為我們提供了一個靜態的屬性SystemFontFamilies。默認情況下ListBox會調用SystemFontFamilies集合中的每個FontFamily實例的ToString方法。幸運的是,這個方法返回的正是FontFamily的名字。
在接下來的課程中我們還會更深入的討論關于這些的細節。
完成以上步驟后MainWindow.xaml里的標記語言應該是這樣的:
<Window x:Class="FontViewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Font Viewer" Height="480" Width="600">
<DockPanel>
<Border DockPanel.Dock="Top" CornerRadius="6" BorderThickness="1"
BorderBrush="Gray" Background="LightGray" Padding="8" Margin="0 0 0 8">
<TextBlock FontSize="14" TextWrapping="Wrap">
Select a font to view from the list below.
You can change the text by typing in the region at the bottom.
</TextBlock>
</Border>
<ListBox x:Name="FontList" DockPanel.Dock="Left" ItemsSource="{x:Static Fonts.SystemFontFamilies}" Width="160" />
</DockPanel>
</Window>
9. 現在我們需要一些可以輸入樣例文字和用當前選中的字體來預覽該文字的方法。
在ListBox下面加入下面這些標簽:
<TextBox x:Name="SampleText" DockPanel.Dock="Bottom" MinLines="4" Margin="8 0" TextWrapping="Wrap" ToolTip="Type here to change the preview text.">
The quick brown fox jumps over the lazy dog.
</TextBox>
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" TextWrapping="Wrap" Margin="0 0 0 4" />
TextBox接受用戶的輸入,同時我們還提供了一些默認的文字。TextBlock是一個用來顯示文本的元素。
我們注意到,TextBlock的Text屬性綁定到了TextBox(我們命名為SampleText)的Text屬性上。這將告訴WPF保持這兩個屬性同步——無論什么時候用戶在TextBox中輸入文字TextBlock都會自動的更新以保持與TextBox里的內容相同。
10. 最后,運行你的程序吧。當然,你也可以對程序稍做修改以體驗WPF的更多魅力。
完善一些細節
在玩弄現在的Font Viewer一會兒后你不難發現用多種不同大小的字體來顯示樣例文字將會使程序更有用。讓我們加入一些標簽分別以10pt,16pt,24pt和32pt的大小顯示樣例文字吧。
我們會做以下修改來在四個不同的地方以不同的大小顯示樣例文字。
1. 用以下標記語言來代替綁定到了SampleText的TextBlock:
<StackPanel Margin="8 0 8 8">
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="10" TextWrapping="Wrap" Margin="0 0 0 4" />
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="16" TextWrapping="Wrap" Margin="0 0 0 4" />
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="24" TextWrapping="Wrap" Margin="0 0 0 4" />
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="32" TextWrapping="Wrap" />
</StackPanel>
這將在程序中加入一個StackPanel——另外一種布局控件。StackPanel控件會把他的子元素一個一個的堆疊起來,在本例中它的子元素是四個不同字體大小的TextBolck元素。
我們注意到,四個TextBolck都綁定到了同一個數據源——名為SqmpleText的TextBox的Text屬性。
2. 給DockPanel加上一個8像素大小的外邊距。這樣使得用戶界面看起來不那么擁擠同時也提升了程序的易用性:
<DockPanel Margin=" 8">
完成后的MainWindow.xaml看起來應該同代碼清單3.1相似。
代碼清單3.1 MainWindow.xaml
<Window x:Class="FontViewer.MainWindow2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Font Viewer" Height="480" Width="640">
<DockPanel Margin="8">
<Border DockPanel.Dock="Top" CornerRadius="6" BorderThickness="1" BorderBrush="Gray" Background="LightGray" Padding="8" Margin="0 0 0 8">
<TextBlock FontSize="14" TextWrapping="Wrap">
Select a font to view from the list below.
You can change the text by typing in the region at the bottom.
</TextBlock>
</Border>
<ListBox x:Name="FontList" DockPanel.Dock="Left" ItemsSource="{x:Static Fonts.SystemFontFamilies}" Width="160" />
<TextBox x:Name="SampleText" DockPanel.Dock="Bottom" MinLines="4" Margin="8 0" TextWrapping="Wrap"
ToolTip="Type here to change the preview text.">
The quick brown fox jumps over the lazy dog.
</TextBox>
<StackPanel Margin="8 0 8 8">
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="10" TextWrapping="Wrap" Margin="0 0 0 4" />
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="16" TextWrapping="Wrap" Margin="0 0 0 4" />
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="24" TextWrapping="Wrap" Margin="0 0 0 4" />
<TextBlock Text="{Binding ElementName=SampleText, Path=Text}" FontFamily="{Binding ElementName=FontList,Path=SelectedItem}" FontSize="32" TextWrapping="Wrap" />
</StackPanel>
</DockPanel>
</Window>
圖3.4 我們的第一個WPF應用程序運行效果
注意到了嗎?現在我們的程序擁有了本課程開始時我們所列出的所有功能并且能夠正確的運行了,但是我們并沒有寫一行代碼。
如果我們可以這么做,那后臺代碼存在的作用又是什么呢?我們一點而代碼也沒有寫啊!
事實上,我們故意的以一個十分簡單的應用程序來開始WPF的學習的。當我們要解決的問題變得更復雜的時候編寫后臺代碼就顯得十分必要了。盡管如此這還是證明了WPF的一個有力的特性:你可以做許多事情而不用寫任何代碼!
總結
在這個小時的課程中,我們談到了如何建立一個新的WPF工程、然后我們建立了我們的第一個WPF應用程序:Font Viewer。我們也討論了XAML文件和后臺代碼文件的區別。最后我們在一個較高的層次演示了WPF的一些令人印象深刻的特性——數據綁定、布局和聲明式的編程。
問答
問. 哪些文件是自動的加入到WPF工程中的?
答. App.xaml、Window1.xaml以及它們的后臺代碼文件。前者(App.xaml)表示整個應用程序,后者(Window1.xaml)則表示應用程序的主窗體。
問. Xaml文件與后臺代碼文件之間有什么不同?
答. XAML文件里面的內容是標記語言而后臺代碼文件是與XAML文件想關聯的里面包涵的是代碼(例如C#代碼或者VB代碼)
問. 當你在VS中重命名XAML文件的時候與之關聯的后臺代碼文件受影響了么?
答. 是的,后臺代碼文件也同時重命名了,但是類名并沒有改變因此如果你想保持類名與文件名同步的話你必須手動的更改類名。
從Word里轉過來就成了這種效果了,大家多多包涵,有錯誤的地方也請多多指正。
本站采用創作共用許可 署名,非商業 歡迎轉載,轉載請注明出處,并包括此段聲明 。 Cat_Lee @ cnblogs
本系列文章的翻譯并沒有經過原著者的同意,僅做學習交流使用,如果您要使用本系列文章于其它用途請慎重,本人概不負任何法律責任。
Finish Whatever U've Started !!!


浙公網安備 33010602011771號