免責聲明:本文章由fengyun1989創作,采用知識共享署名-非商業性使用-相同方式共享 2.5 中國大陸許可協議進行許可。
下面,我們添加Appbar,AppBar大家應該都很熟悉了,wp7里面運用多了去了,不過,這里的AppBar和WP7里面的用法不太一樣,有WP7開發經驗的從下面的教程就能夠看出差別,大同小異。
在MainPage頁面的Grid后面添加如下代碼:
<Page.BottomAppBar> <AppBar> <Grid> <Button x:Name="Save" Style="{StaticResource SaveAppBarButtonStyle}" AutomationProperties.Name="保存課表" HorizontalAlignment="Center" Click="Save_Click"/> </Grid> </AppBar> </Page.BottomAppBar> <Page.TopAppBar> <AppBar> <Grid> <Button x:Name="About" Style="{StaticResource HelpAppBarButtonStyle}" AutomationProperties.Name="關於我們" HorizontalAlignment="Center" Click="AboutClick"/> </Grid> </AppBar> </Page.TopAppBar> </Page>
上面我們添加了ButtonAppBar(底部AppBar)和TopAppBar(頂部AppBar),這里的AppBar支持隨意布局,什么ColumnDefinition都是可以實現的。不過win8和wp7不一樣的是底部Appbar沒有了下拉菜單。
另外,里面的Button的樣式也有區別,在wp7里面我們都是從SDK內部獲取Icon圖片來實現button的樣式,在win8,這些樣式是用style來實現,這些Style都定義在了Common/StandardStyles.xaml里面,我們可以根據文件名來獲取相應樣式,AutomationProperties.Name是用來按鈕顯示的文字。當然,Button的style也可以自己定義。
推薦關於AppBar的文章:http://www.devdiv.com/_DevDiv原創_Windows_8_Metro_App開發之應用程序欄_AppBar_的使用-thread-130752-1-1.html
接下來實現按鈕的click事件,先來實現AboutClick方法。
private void AboutClick(object sender, RoutedEventArgs e) { this.Frame.Navigate(typeof(AboutPage)); }
click方法就實現了一個導航,導航至AboutPage。我們要往Pages里面添加一個空白頁AboutPage來實現“關於我們”的實現。
AboutPage.xaml前台:
<Grid Background="{StaticResource AppBackgroundColor}"> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="300"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TextBlock FontSize="42" TextWrapping="Wrap" Grid.RowSpan="2" Grid.Column="0" Grid.Row="0"> 此教程由fengyun1989創作,僅供學習交流使用請勿用於商業用途。 </TextBlock> <Image Source="/Assets/120.jpg" Grid.Column="1" Grid.RowSpan="2" Grid.Row="0" Height="200" Width="200"/> <Button Content="確定" Width="200" Height="60" HorizontalAlignment="Center" Grid.Row="2" Grid.ColumnSpan="2" Grid.Column="0" Click="Button_Click_1"/> </Grid> </StackPanel> </Grid>
后台就只實現了確定按鈕的click方法,也就是實現了一個導航,導航回MainPge頁面。
private void Button_Click_1(object sender, RoutedEventArgs e) { this.Frame.Navigate(typeof(MainPage)); }
接下來實現Save按鈕,我打算把課表保存為XML數據,並且用FIlePicker來實現路徑的選擇。
private async void Save_Click(object sender, RoutedEventArgs e) { FileSavePicker openPicker = new FileSavePicker(); openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary; openPicker.FileTypeChoices.Add("XML", new List<string>() { ".xml" }); openPicker.FileTypeChoices.Add("TEXT", new List<string>() { ".txt" }); openPicker.DefaultFileExtension = ".xml"; openPicker.SuggestedFileName = "kebiao"; openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary; StorageFile file = await openPicker.PickSaveFileAsync(); if (file != null) { // Application now has read/write access to the picked file // Prevent updates to the remote version of the file until we finish making changes and call CompleteUpdatesAsync. CachedFileManager.DeferUpdates(file); // write to file await FileIO.WriteTextAsync(file, ConvertViewModel()); // Let Windows know that we're finished changing the file so the other app can update the remote version of the file. // Completing updates may require Windows to ask for user input. FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file); if (status == FileUpdateStatus.Complete) { MessageDialog msgDlg = new MessageDialog("保存成功!"); await msgDlg.ShowAsync(); } } } /// <summary> /// Convert ViewModel to XML string /// </summary> /// <returns></returns> string ConvertViewModel() { XDocument xml = new XDocument(); XElement root = new XElement("root"); foreach (var item in viewModel.WeekdayList) { XElement weekday = new XElement(item.Weekday); foreach (var scheduleItem in item.ScheduleList) { XElement lessonName = new XElement(scheduleItem.LessonName); lessonName.SetAttributeValue("classroom", scheduleItem.ClassRoom); lessonName.SetAttributeValue("starttime", scheduleItem.StartTime); lessonName.SetAttributeValue("endtime", scheduleItem.EndTime); weekday.Add(lessonName); } root.Add(weekday); } xml.Add(root); return xml.ToString(); }
我添加了一個方法ConvertViewModel來實現viewModel轉換成XML。在Save_Click中,我們實現了FilePicker。大家如果有window開發經驗,應該對上面的代碼很熟悉,和window上文件保存的Dialog差不多,都是設定好拓展名,初始命名等,和window上的編程是不是一樣?如果路徑選擇好了,就把數據保存到文件。文件保存成功后就顯示一個彈窗,這個彈窗和以前WP7,window的彈窗用法。都不太一樣,雖然都是message彈窗。可以添加一些按鈕命令等。詳細請看:http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.popups.messagedialog.aspx
另外,FilePicker還有其他的用法,比如FileOpenPicker,不過用法也大同小異。詳細請看微軟官方例子:http://code.msdn.microsoft.com/windowsapps/File-picker-sample-9f294cba
而且,記得修改方法為異步方法。因為FilePicker和MessageDialog的展示的時候都是異步的,要用await關鍵字來修飾,那么整個方法也要修改成異步方法。不要使用編譯器智能生成代碼習慣了。到頭來調試半天都沒發現哪里錯了。我有時候就是這樣。。。
編譯后我們運行,就可以得到預想的結果。
注意,在模擬器里面,要用手勢才能啟動AppBar.
動態啟動畫面
還記得設置靜態的啟動畫面么,是在Package.appxmanifest里面設置的,圖片大小為620*300.下面就是我們設置過的靜態啟動頁面。
不過,我們需要動態啟動畫面,就要用一個頁面來實現了,另外,我們要動態,就要制作動畫,好像現在都沒有在win8制作動畫的例子,不過,到現在了,大家有沒有發現win8開發和Wp7開發方式大同小異,那么,我可以大膽的猜測,Wp7中制作動畫的方法在win8也是適用的。那么添加這么一個SplashPage頁面到Pages文件夾吧。
修改前台代碼如下:
<Grid Background="{StaticResource AppBackgroundColor}"> <TextBlock Text="fengyun1989歡迎您!" FontSize="72" HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="welcomeText"> <TextBlock.RenderTransform> <RotateTransform /> </TextBlock.RenderTransform> </TextBlock> </Grid>
然后在后台代碼的構造函數修改如下:
public SplashPage() { this.InitializeComponent(); RotateTransform rotateTransform = welcomeText.RenderTransform as RotateTransform; DoubleAnimation anima = new DoubleAnimation(); anima.From = 0; anima.To = 1080; anima.Duration = new Duration(TimeSpan.FromSeconds(2)); Storyboard.SetTarget(anima, rotateTransform); Storyboard.SetTargetProperty(anima, "Angle"); Storyboard storyboard = new Storyboard(); storyboard.Children.Add(anima); storyboard.Completed += storyboard_Completed; storyboard.Begin(); } void storyboard_Completed(object sender, object e) { this.Frame.Navigate(typeof(MainPage)); }
我們添加了一個旋轉動畫,使TextBlock旋轉,然后等旋轉結束后,導航到MainPage頁面。如果大家對動畫不太熟悉,建議去學習下Silverlight或者Wp7的動畫制作。
不過,現在我們還不能實現啟動畫面,那么我們要修改入口類App,打開App.XAML.cs文件。找到OnLaunched方法,修改代碼如下:
// Create a Frame to act navigation context and navigate to the first page //var rootFrame = new Frame(); //if (!rootFrame.Navigate(typeof(MainPage))) //{ // throw new Exception("Failed to create initial page"); //} //// Place the frame in the current Window and ensure that it is active //Window.Current.Content = rootFrame; if (Window.Current.Content == null) { Frame frame = new Frame(); frame.Navigate(typeof(Pages.SplashPage), args.SplashScreen); Window.Current.Content = frame; } Window.Current.Activate();
我們主要在啟動的時候判斷一下是否已經啟動了。如果已經啟動了(是從后台啟動),那么Window.Curent.Content就不為空。如果為空,就先導航到啟動動畫頁面。這樣我們就能看到啟動動畫了。一般情況下,修改注釋掉的那行有MainPage的那行,修改那里就能改變啟動頁面了。
現在編譯運行,就能看到靜態啟動頁面后就有動態的動畫了。
微軟啟動畫面例子:http://code.msdn.microsoft.com/windowsapps/Splash-screen-sample-89c1dc78
墓碑機制
win8程序的生命周期:http://msdn.microsoft.com/en-us/library/windows/apps/hh464925.aspx
從我們的Wp7經驗,我們可以在App.xaml.cs文件里面實現墓碑機制。但是,由於我們這個程序過小,並且我覺得不需要墓碑機制,所以沒有做。從微軟提供的程序的生命周期來看,的確是需要墓碑機制的,但是,我嘗試多次,多個程序,沒有試出我這個程序是否進入后台休眠了。感覺還是在后台運行中,可能是由於占用內存過小,所以沒有必要休眠吧。如果有朋友有研究或者有相關資料希望能夠共享下。
寫在最后
到這里,我們這個系列教程到這里就結束了,雖然這個程序很小,但是基本的功能還是具有的,雖然我想把大部分特點都集結進來,但是細想這個程序的功能,那些實在是沒有必要,所以就到這了。那么那些比較有趣,並且win8獨有的,可能在以后在寫些實例教程吧。
我想,通過這么一個教程,大家都基本能夠了解到win8程序開發了,雖然win8開發的資料很少,不過我想,大家可以充分發揮想象,找尋與Wp7編程與之的微小差異之處,並且可以充滿想象力的大膽猜測,多多參照微軟提供的例子,我想,開發一個有趣的程序沒有太大的問題。
快速找到不同之處,熟悉相同之處,我想,這樣就是一通百通了。那么,接下來,Wp8不久就要發布了。一通百通的方法,肯定是適用的。其實我感覺,微軟的東西就是如此,編程的東西就是如此。本教程的主要目的就是希望能夠拋磚引玉,希望大家在win8,wp8的開發能夠迅速上手,開發出的好程序越多,市場越大,我們才越有活頭嘛。
本次工程並且是最終工程下載:http://dl.dbank.com/c0yssdb7kf