// MainWindow.xaml.cs (codebehind) using System.Windows; public partial class MainWindow : Window { ... } 在添加窗體定義之后,Visual Studio 2005自動地把標記文件的"構建類型"設置為Page(頁面)。在構建的時候,該標記被轉換為一種特定的資源類型,可以被統一的資源標識符(URI)唯一地識別出來。從本質上說,這使得Windows Presentation Foundation可以使用URI宣告式地載入一個窗體,你可以使用這種能力來指定一個應用程序啟動時自動打開的窗體。要達到這個目的,只需要設置標記中的Application.StartupUri屬性,如下所示:
sealed class NavigationService : IContentContainer { // 導航 public bool Navigate(Uri source); // 導航到URI public void Refresh(); // 重新導航到當前內容 public void StopLoading(); // 停止當前的導航 // 導航歷史 public bool CanGoBack { get; } // Content in back nav. history? public bool CanGoForward { get; } // Content in forward nav. history? public void GoBack(); // Go to previous content in nav. history public void GoForward(); // Go to next content in nav. history
// 導航的生命周期 // 導航請求 public event NavigatingCancelEventHandler Navigating; // 導航到內容 public event NavigatedEventHandler Navigated; // 內容載入了 public event LoadCompletedEventHandler LoadCompleted; // 導航錯誤 public event NavigationFailedEventHandler NavigationFailed; // 下載的字節數 public event NavigationProgressEventHandler NavigationProgress; // 導航停止了 public event NavigationStoppedEventHandler NavigationStopped;
// 內容 public object Content { get; set; } // 當前載入的內容 public Uri CurrentSource { get; } // 當前內容的URI public Uri Source { get; set; } // 當前內容的URI,或者將導航到的內容的URI
// 查找導航服務 public static NavigationService GetNavigationService(DependencyObject dependencyObject); } 當你知道這些內容之后,就能使用GetNavigationService來獲取寄宿頁面的NavigationWindow的NavigationService引用了:
// HomePage.xaml.cs (codebehind) public partial class HomePage : Page { void viewHyperlink_Click(object sender, RoutedEventArgs e) { // 查看訂單 ViewOrderPage page = new ViewOrderPage(GetSelectedOrder()); NavigationService ns = NavigationService.GetNavigationService(this); ns.Navigate(page); } Order GetSelectedOrder() { ... } ... } 這就使得頁面可以執行導航而無需知道宿主的特定信息了。這種需求是如此的普遍,以至于頁面提供了一個特定的輔助屬性NavigationService,它提供的功能相同:
// HomePage.xaml.cs (code-behind) public partial class HomePage : Page { void viewHyperlink_Click(object sender, RoutedEventArgs e)
{ // 查看訂單 ViewOrderPage page = new ViewOrderPage(GetSelectedOrder()); this.NavigationService.Navigate(page); }
Order GetSelectedOrder () { ... } ... } 圖9演示了NavigationWindow、NavigationService和頁面(Page)之間的關系。你可以看到,NavigationWindow重新實現了自己的NavigationService的Content屬性。NavigationWindow不但用這種方法實現了NavigationService的大多數成員,甚至于還增加了一些。例如,你可以通過BackStack和ForwardStack屬性,枚舉"向前"和"向后"導航歷史的內容。
圖9:關系
不幸的是,你無法建立自定義的、聚合了NavigationService的類型(盡管它是一個公共類型,但是它有內部的構造函數,從而阻止了實例化)。作為代替,你必須依靠三種NavigationService聚合器(aggregator)來寄宿內容。這就是我們所知道的導航器(navigator),包括NavigationWindow、Frame和瀏覽器(僅包括用于Windows Presentation Foundation 1.0的Internet EXPlorer 6 和 7)。當編寫代碼讓頁面使用自己的NavigationService屬性的時候,它就可以寄宿在上面的三種導航器中,而不需要做任何更改,如圖10所示。
NavigationWindow、頁面和超鏈接為用戶在獨立的應用程序中獲得瀏覽器樣式的用戶體驗提供了一條很好的途徑。總而言之,NavigationWindow是一個瀏覽器,雖然它沒有目前的瀏覽器所帶有的所有功能(例如收藏夾、分頁瀏覽等等)。由于大多數用戶都有瀏覽器的知識,他們對提供同等能力、甚至集成瀏覽器的應用程序的感覺會更好。假如你的應用程序從瀏覽器寄宿和超鏈接驅動的環境中受益,那么Windows Presentation Foundation XAML瀏覽器應用程序(XBAP)是我們應該努力的方向。
為了建立一個XBAP示例應用程序,需要在Visual Studio 2005中建立一個新的.NET框架組件3.0 Web瀏覽器應用程序,并復制示例NavigationWindow文件,就完成工作了。作為結果生成的應用程序將寄宿在Internet Explorer中運行,如圖11所示。
Windows Presentation Foundation應用程序模型是非常靈活的。它支持標準的和瀏覽器寄宿的應用程序--它們兩者都支持菜單驅動和超鏈接驅動的導航。此外,應用程序的內容可以被封裝到應用程序的部件、被引用的部件或某些位置的松散文件中。總而言之,在Windows Presentation Foundation應用程序模型中建立的用戶體驗類型僅受個人選擇的限制。