使用VS2010為Windows7編寫一個殺手級WPF應用
當你使用最新的操作系統,在最新的框架上構建應用程序,并且使用最新版本的Visual Studio的時候,你可以使用許多令人興奮的新特性。你可以學習一下怎樣使用Visual Studio 2010, WPF 4 和 the Windows API Code Pack給你的應用程序添加Windows 7 UI。
Windows 7 UI有很多令人興奮的元素,例如:全新的任務欄,或者跳轉列表,視覺體驗本身并不屬于應用程序的范疇,但是它是應用程序體驗的重要組成部分。作為一個WPF開發者,你可以把那些元素添加到你的Windows7應用程序中,隨心所欲地定制它們在主窗口內部和外部的行為。
使用WPF4,你幾乎可以訪問所有的Windows 7 UI特性。WPF4內置了對Windows7任務欄的支持,其中包括可以自定義的縮略圖預覽,通過進度條和“圖標覆蓋”(icon overlay)從任務欄獲得視覺反饋,以及可以自定義的跳轉列表。雖然這些特性最終是通過Windows 7的原生API來提供的,但是WPF用托管的代碼對它們進行了封裝,通過WPF類的形式把它們暴露出來。這意味著你可以在XAML中創建跳轉列表對象和其他的UI對象,并且可以通過許多依賴屬性(dependency property)來綁定它們。
Visual Studio 2010本身就包含許多和WPF有關的新特性,其中包括一個全新的可視化設計器,拖放式的數據綁定,以及在XAML中的標記擴展的智能感知。這些特性已經和WPF的任務欄類整合到一起了,它們可以讓你充分地利用Visual Studio的最新版本的全部功能,來構建時尚的Windows7應用程序。
雖然WPF4對任務欄有很好的支持,但是,還有一些其他方面的Windows 7 API它并沒有封裝。例如:Windows7樣式的通用對話框。你只能使用Windows API Code Pack和一個外部的托管封裝庫在WPF中訪問這些API。Windows API Code Pack有它自己的一套shell和任務欄類,在WPF 3.5 SP1中也可以使用它們。
(Windows API Code Pack的下載地址:http://code.msdn.microsoft.com/WindowsAPICodePack)
數據綁定和Visual Studio 2010的WPF設計器
在接觸Windows7的新特性以前,讓我們先來看一看在全新的Visual Studio 2010的WPF設計器中的一個基礎的數據驅動的WPF應用程序。在Visual Studio 2010中,你可以在設計的時候通過把數據源拖放到可視化的設計器中的方式來創建數據綁定。
如果你把一個數據源項拖放到一個現有的控件上(例如,把一個文本字段拖放到一個文本框中),那么設計器會為那個數據源創建一個窗口資源,然后把這個字段綁定到那個控件上。如果你把一個數據源項拖放到一個容器上,那么設計器會創建一個相應的綁定控件,然后把這個控件添加到那個容器中。如果默認的類型并不合適,你可以自己設置這個綁定控件的類型。在截圖1中,我把一個來自于AdventureWorks 2008樣例數據庫的數據表拖放到一個窗口中,設計器自動地創建了一個數據網格控件。當我們開發在Windows7任務欄上顯示進度的功能的時候,我們將會用到這個數據網格。
(截圖1:把一個表數據源拖放到主窗口上,會生成了一個數據網格控件)
除了基礎的創建之外,我們還做了一點額外的工作,我們使用漸變式的畫刷來設置窗口的背景。Visual Studio 2010內置了一個可視化的畫刷編輯器,這讓創建和使用漸變式的畫刷,圖像畫刷,以及純色的畫刷變得更加容易了。在一個畫刷屬性的屬性編輯器上下拉可以直接在編輯器中看到反饋,這可以讓你以可視化的方式創建漸變式的畫刷,或者為一個圖像畫刷選擇一個圖像。
(截圖2:使用可視化的畫刷編輯器創建一個背景畫刷。)
和Windows7的任務欄進行交互
在Windows7中,你可以通過一個橫跨任務項背景的進度條,在任務欄上顯示需要長時間才能完成的操作的進度。Internet Explorer使用任務欄進度條來跟蹤文件的下載情況就是一個很好的例子。
你可以通過TaskbarItemInfo類和Windows7的任務欄進行交互,在主窗口上,這個類是通過一個依賴屬性暴露出來的。你可以在XAML中創建一個TaskbarItemInfo對象:
2. <TaskbarItemInfo x:Name="TaskbarItemInfo1"
Description="Customer Browser: Using WPF 4 on Windows 7”>
3. </TaskbarItemInfo>
4. </Window.TaskbarItemInfo>
你可以直接在XAML中編輯TaskbarItemInfo的屬性,也可以通過Visual Studio的屬性編輯器來編輯TaskbarItemInfo的屬性。這個XAML代碼片段只展示了名字和Description屬性,這個屬性用來指定在任務欄上顯示的提示文本。大多數的任務欄特性都可以通過這個類來訪問。
為了顯示進度條,你只需設置其中兩個屬性就可以了,這兩個屬性分別是:ProgressValue 和 ProgressState。ProgressState的默認值是None;你可以把它設置成Indeterminate來顯示一個滾動樣式的進度條,或者也可以把它設置成Normal,實際上我們就是這樣設置的,這樣可以顯示一個標準的進度條:
2. TaskBarItemInfo1.ProgressState = TaskbarItemProgressState.Normal;
把ProgressValue設置成1.0會顯示一個處于完成狀態的進度條。為了跟蹤數據表的填充情況,我們首先會執行一個計數查詢,計算出這個數據表的總行數,把這個數值作為完成狀態的進度值。然后,我們可以訂閱這個數據表的RowChanged,添加下面這兩行代碼來更新任務欄上的進度條:
this.rowsUpdated++;
TaskbarItemInfo1.ProgressValue =((double)this.rowsUpdated)/this.rowCount; //將this.rowsUpdated顯式轉換為double類型,防止計算的過程中發生精度丟失。
除了進度條,你還可以使用“圖標覆蓋”(icon overlay)來提供和應用程序狀態有關的反饋。一個“圖標覆蓋”是一個小的圖像,在任務欄中,它位于主應用程序圖標的前面。我們將會使用一個“圖標覆蓋”來顯示我們的客戶列表的過濾器設置。
截圖3展示了一個在任務欄上使用“圖標覆蓋”的樣例應用程序。在主應用程序中,你可以通過在一個組合框中選擇一個國家的方式,按照國家來查看客戶。如果對過濾器進行了設置,任務欄圖標會顯示一個小的圖像,這個小圖像是在過濾器中選擇的那個國家的國旗,它就是一個“圖標覆蓋”。
(截圖3:通過一個“圖標覆蓋”來顯示過濾器設置的Customer Browser應用程序。)
你可以通過給TaskbarItemInfo的Overlay屬性指定圖像源的方式來設置一個“圖標覆蓋”。對于這個例子來說,我針對每個國旗圖像創建了一個位圖資源。然后,當對過濾器進行設置的時候,我們可以從窗口資源載入圖像,設置一個“圖標覆蓋”:
2. TaskbarItemInfo1.Overlay =(ImageSource)this.TryFindResource(resourceKey);
自定義縮略圖
當你的應用程序運行在Windows7上的時候,應用程序縮略圖預覽是你可以免費獲得的UI perk之一。Windows 7可以通過在任務欄上彈出一個小窗口的方式來顯示主應用程序窗口的縮略圖。用戶可以使用縮略圖預覽來激活或關閉這個應用程序,或者在應用程序實例之間進行選擇。
通過TaskbarItemInfo的ThumbnailClipMargin屬性,你可以很容易地對你的應用程序的縮略圖進行定制。使用這個屬性,你可以在主窗口內指定一個矩形(這個矩形的內容會顯示在縮略圖中),而不是顯示整個主窗口。
ThumbnailClipMargin是一個依賴屬性(dependency property),所以,除了指定一個靜態的邊框之外,你還可以把它綁定到另外一個控件的邊框上,使用那個控件作為應用程序預覽。通過這種方法,我把縮略圖預覽設置成只顯示客戶的數據網格。與其看另外一個代碼片段,到不如看一看Visual Studio中的情況。
(截圖4:設置ThumbnailClipMargin綁定。)
截圖4展示了在XAML中設置綁定,它還展示了Visual Studio提供的全新的標記擴展的智能感知。我們必須把綁定Path設置成“Margin”,我們可以在選項列表中選擇Path。
縮略圖預覽還可以包含一組工具欄按鈕,讓用戶通過預覽窗口直接給應用程序發送命令。有時這些特性會比較有用,例如,發送媒體命令(例如:播放或暫停)的時候。對于這個例子來說,我創建了一個“Copy”工具欄按鈕,從一個TextBox拷貝客戶的電子郵件地址。
TaskbarItemInfo包含一個叫作“ThumbButonInfos”的集合屬性,通過這個屬性,你可以創建一個縮略圖工具欄。Visual Studio 2010也完全支持這個特性,你可以在集合編輯器中編輯每個按鈕項,或者,你也可以直接在XAML中完成這個工作。
一個ThumbButonInfo的XAML通常會指定要發送的命令,命令的目標,這個按鈕要使用的圖像,以及工具提示文本。這是我們的“Copy”按鈕的XAML代碼:
2. Description="Copy E-Mail Address"
3. ImageSource="/wpf4example;component/Images/copy.png"
4. CommandTarget="{Binding ElementName=textBox1}" />
通過WPF命令的“魔力”,這個按鈕會根據是否在文本框中選擇了文本而自動地啟用或禁用。
(截圖5:自定義縮略圖圖像(只顯示DataGrid)和“Copy”工具欄按鈕)
跳轉列表
跳轉列表是常用的任務或與一個應用程序相關的文件的列表,右鍵單擊任務欄圖標,它就會彈出來,或者,在開始菜單的應用程序項上,它也會彈出來。你可以通過添加文件,任務,或者你自己的任務分類的方式來對你的應用程序的跳轉列表進行定制。
跳轉列表是和應用程序本身相關聯的,而不是和具體的應用程序實例相關聯。你可以使用程序代碼,在你的應用程序中添加一個自定義的跳轉列表,或者,你也可以在XAML中(在app.xaml文件中)把一個跳轉列表掛載到一個應用程序對象上。
2. <JumpList ShowRecentCategory="True”
3. ShowFrequentCategory="True">
4.
5. <JumpTask Title="Notepad”
6. Description="Run Notepad"
7. ApplicationPath="c:\windows\notepad.exe"
8. IconResourcePath="c:\windows\notepad.exe"/>
9. </JumpList>
10. </JumpList.JumpList>
如果你在XAML中創建了一個跳轉列表,在這個應用程序初始化以后,這會自動地應用到Windows Shell中。
跳轉列表可以包含跳轉任務(就像在這個XAML代碼片段中展示的那樣),來啟動其他的程序,或者,它們也可以包含跳轉路徑,直接鏈接到文件。如果你的應用程序注冊為某種文件類型的處理程序,那么這些跳轉路徑只能顯示在你的跳轉列表上。
Windows Shell為每個應用程序維護了一個最近頻繁使用的文件的列表。你可以設置ShowRecentCategory 和 ShowFrequentCategory屬性,在應用程序的跳轉列表中顯示這些列表。
除了這些標準的分類外,你還可以創建自定義的分類。下面這段代碼添加了一個鏈接到calc.exe的跳轉任務,然后把它放到一個自定義的分類中。
2. jumpTask1.ApplicationPath =
3. "C:\\windows\\system32\\calc.exe";
4. jumpTask1.IconResourcePath =
5. "C:\\windows\\system32\\calc.exe";
6. jumpTask1.Title = "Calculator";
7. jumpTask1.CustomCategory = "Calculation";
8.
9. JumpList jumpList1 = JumpList.GetJumpList(App.Current);
10. jumpList1.JumpItems.Add(jumpTask1);
11. jumpList1.Apply();
(截圖6:一個帶有標準分類和一個自定義分類的跳轉列表)
Windows7的對話框和控件
WPF并沒有封裝Windows7的通用文件對話框API。要使用這些API,你可以求助于Windows API Code Pack。這個代碼包可以讓你從WPF應用程序中啟動一些“了解”Windows 7的Shell特性(例如已知的文件夾和庫)的,通用的對話框。
要使用這個代碼包,需要創建一個代碼包解決方案,然后把代碼包程序集的引用添加到你的應用程序中。這樣的話,你就可以使用代碼包命名空間中的類了,包括CommonDialog。
Windows7有一系列已知的文件夾(例如:Desktop, Pictures Library),在CommonDialog中,你可以直接指定這些文件夾,無需指定具體的文件路徑。這段代碼把打開文件對話框的初始路徑設置成了Pictures Library。
2. dlg.InitialDirectoryShellContainer = (ShellContainer)KnownFolders.PicturesLibrary;
你可以使用已知的文件夾(或者,更普遍點來說,你可以使用Shell對象)來指定通用的打開文件對話框或保存文件對話框的一些設置。例如,這行代碼給這個打開文件對話框添加了一個新的打開路徑:Video Library
FileDialog.AddPlaceLocation.Bottom);
(截圖7:一個帶有自定義的打開路徑的Windows7打開文件對話框)
Windows API Code Pack還提供了一個用WPF封裝的ExplorerBrowser控件,通過它,你可以在一個Windows7樣式的資源管理器界面中顯示文件和其他的Shell對象。要使用這個控件,你需要做的所有事情就是在XAML中聲明它:
然后,在這個基礎控件上調用Navigate方法,在你的窗口中顯示選定的文件夾:
(插圖8:Windows API code pack中的ExplorerBrowser控件,它運行在一個樣例應用程序窗口中。)
新的工具支持新的UI
在WPF4,Windows API code pack,和完整的Visual Studio 2010 UI的幫助下,你可以把最酷的,原生的Windows7特性發揮得淋漓盡致,而且根本不用離開托管代碼。對于開發者來說,這是一次重大的勝利,希望這可以提升他們的應用程序的Windows7用戶體驗。
原文標題:Using Visual Studio 2010 to Write Killer WPF Apps for Windows 7