免責聲明:本文章由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