(五)實例講解win8(XAML+C#)開發--------課程表:Appbar,FilePicker,啓動頁面(動畫)

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章