天天看點

WP8 軟體首次啟動時使用者引導頁面的實作

一、首先判斷應用程式是否首次啟動。

/// <summary>
        /// 判斷是否為第一次啟動應用程式
        /// </summary>
        /// <param name="e"></param>
        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)  
        {
            if (isAppFirstIn)
            {
                isAppFirstIn = false;
                SQLiteHelper.openDB();
                SQLiteHelper.CreateVersionTable();
                VersionInfo infoVersion = SQLiteHelper.seleceVersion();
                if (infoVersion != null)//判斷VersionInfo中是否為空
                {
                    //将該應用版本與VersionInfo表中的資料相比較,應用更新時也進入引導頁
                    if (infoVersion.version != info.WinPhoneVersion)
                    {
                        //将版本号存入
                        SQLiteHelper.insertVersionData(info.WinPhoneVersion);
                        SQLiteHelper.closeDB();
                        NavigationService.Navigate(new Uri("/firstIn.xaml", UriKind.Relative));
                    }
                    else
                    {
                        SQLiteHelper.closeDB();
                    }
                }
                else
                {
                    //将版本号存入
                    SQLiteHelper.insertVersionData(info.WinPhoneVersion);
                    SQLiteHelper.closeDB();
                    NavigationService.Navigate(new Uri("/firstIn.xaml", UriKind.Relative));
                }
            }
        }           

将應用版本存入資料庫中,資料庫操作如下(使用SQLite資料庫存儲手機資料)

  public static void openDB()
        {
            if (db == null)
            {
                db = new SQLiteConnection(fileName);
                db.Open();
            }
        }


        public static void closeDB()
        {
            if (db != null)
            {
                db.Dispose();
                db = null;
            }
        }           
#region version

        public static void CreateVersionTable()
        {
            if (db != null)
            {
                try
                {
                    if (!isExistTable("VersionTable"))
                    {
                        SQLiteCommand cmd = db.CreateCommand("Create table VersionTable(id INTEGER primary key,version text)");
                        int i = cmd.ExecuteNonQuery();
                    }
                }
                catch (SQLiteException ex)
                {

                }
            }
        }

        public static VersionInfo seleceVersion()
        {
            if (db != null)
            {
                try
                {
                    SQLiteCommand cmd = db.CreateCommand("SELECT id,version FROM VersionTable ");
                    var lst = cmd.ExecuteQuery<VersionInfo>();
                    if (lst.Count() == 0)
                    {
                        return null;
                    }
                    else
                    {
                        VersionInfo tt = lst.ToList()[0];
                        return tt;
                    }
                }
                catch (SQLiteException ex)
                {
                    return null;
                }
            }
            else
            {
                return null;
            }
        }

        public static void insertVersionData(string version)
        {
            if (db != null)
            {
                try
                {
                    deleteVersionData();//先删除後添加
                    SQLiteCommand cmd = db.CreateCommand("");
                    cmd.CommandText = " Insert into VersionTable (version) values ('" + version + "')";
                    int rec = cmd.ExecuteNonQuery();
                }
                catch (SQLiteException ex)
                {

                }
            }
        }

        public static void deleteVersionData()
        {
            if (db != null)
            {
                try
                {
                    SQLiteCommand cmd = db.CreateCommand("");
                    cmd.CommandText = " delete from VersionTable ";
                    int rec = cmd.ExecuteNonQuery();
                }
                catch (SQLiteException ex)
                {

                }
            }
        }
        #endregion           

//表結構如下,其實隻需一個字段記錄目前應用程式的版本号,當表資料無此條記錄可以判斷為程式第一次啟動

    public class VersionInfo
    {
        public VersionInfo()
        {
        }
        public VersionInfo(int Id, string Version)
        {
            id = Id;
            version = Version;
        }


        int _id;
        string _version;

        public int id
        {
            get { return _id; }
            set { _id = value; }
        }

        public string version
        {
            get { return _version; }
            set { _version = value; }
        }
    }           

二、引導頁面設計

1、firstIn.xaml頁面

<phone:PhoneApplicationPage xmlns:Controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls" 
    x:Class="HTClient.firstIn"
    xmlns:local="clr-namespace:HTClient"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit" 
    xmlns:sltoolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit" 
    sltoolkit:TiltEffect.IsTiltEnabled="True"
    xmlns:c4fToolkit="clr-namespace:Coding4Fun.Phone.Controls;assembly=Coding4Fun.Phone.Controls" 
    xmlns:c4fToolkitBinding="clr-namespace:Coding4Fun.Phone.Controls.Binding;assembly=Coding4Fun.Phone.Controls" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800" 
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait"  Orientation="Portrait"
    shell:SystemTray.IsVisible="true">

    <!--LayoutRoot is the root grid where all page content is placed Background={StaticResource firstImage1}-->
    <Grid x:Name="LayoutRoot" >
        <Controls:Pivot  Name="pivotNews" ManipulationDelta="pivotNews_ManipulationDelta" ManipulationCompleted="pivotNews_ManipulationCompleted" ManipulationStarted="pivotNews_ManipulationStarted">
            <Controls:PivotItem  x:Name="pivote1"  ManipulationDelta="pivote1_ManipulationDelta" ManipulationCompleted="pivote1_ManipulationCompleted" ManipulationStarted="pivote1_ManipulationStarted"  Foreground="{StaticResource PhoneAccentBrush}" Margin="0,-32,0,0">
                <Grid  Background="{StaticResource firstImage1}">
                    <Image  Width="auto" Source="images/dian01.png" RenderTransformOrigin="0.356,0.644" Margin="66,678,288,72"  />
                    <Image  Width="auto" Source="images/dian.png" RenderTransformOrigin="0.356,0.644" Margin="150,678,210,72"  />
                    <Image  Width="auto" Source="images/dian.png" RenderTransformOrigin="0.356,0.644" Margin="250,678,135,72"  />
                    <Image  Width="auto" Source="images/dian.png" RenderTransformOrigin="0.356,0.644" Margin="350,678,61,72"  />
                </Grid>
            </Controls:PivotItem>
            <Controls:PivotItem   Foreground="{StaticResource PhoneAccentBrush}" Margin="0,0,0,-32">
                <Grid  Background="{StaticResource firstImage2}">
                    <Image  Width="auto" Source="images/dian.png" RenderTransformOrigin="0.356,0.644" Margin="66,678,288,72"  />
                    <Image  Width="auto" Source="images/dian01.png" RenderTransformOrigin="0.356,0.644" Margin="150,678,210,72"  />
                    <Image  Width="auto" Source="images/dian.png" RenderTransformOrigin="0.356,0.644" Margin="250,678,135,72"  />
                    <Image  Width="auto" Source="images/dian.png" RenderTransformOrigin="0.356,0.644" Margin="350,678,61,72"  />
                </Grid>
            </Controls:PivotItem>
            <Controls:PivotItem   Foreground="{StaticResource PhoneAccentBrush}" Margin="0,-22,0,-10">
                <Grid  Background="{StaticResource firstImage3}">
                    <Image  Width="auto" Source="images/dian.png" RenderTransformOrigin="0.356,0.644" Margin="66,678,288,72"  />
                    <Image  Width="auto" Source="images/dian.png" RenderTransformOrigin="0.356,0.644" Margin="150,678,210,72"  />
                    <Image  Width="auto" Source="images/dian01.png" RenderTransformOrigin="0.356,0.644" Margin="250,678,135,72"  />
                    <Image  Width="auto" Source="images/dian.png" RenderTransformOrigin="0.356,0.644" Margin="350,678,61,72"  />
                </Grid>
            </Controls:PivotItem>
            <Controls:PivotItem  x:Name="pivote4"  ManipulationDelta="pivote4_ManipulationDelta" ManipulationCompleted="pivote4_ManipulationCompleted" ManipulationStarted="pivote4_ManipulationStarted"   Foreground="{StaticResource PhoneAccentBrush}" Margin="0,-32,0,0">
                <c4fToolkit:Tile Click="firstIn_Click" >
                    <Grid Background="{StaticResource firstImage4}" >
                        <Image  Width="auto" Source="images/dian.png" RenderTransformOrigin="0.356,0.644" Margin="66,678,288,72"  />
                        <Image  Width="auto" Source="images/dian.png" RenderTransformOrigin="0.356,0.644" Margin="150,678,210,72"  />
                        <Image  Width="auto" Source="images/dian.png" RenderTransformOrigin="0.356,0.644" Margin="250,678,135,72"  />
                        <Image  Width="auto" Source="images/dian01.png" RenderTransformOrigin="0.356,0.644" Margin="350,678,61,72"  />
                    </Grid>
                </c4fToolkit:Tile>
            </Controls:PivotItem>
        </Controls:Pivot>
    </Grid>
</phone:PhoneApplicationPage>           

在App.xaml 中将四張引導圖檔直接刷為背景,将dian.png與dian01.png差別目前圖檔所在位置

    <Application.Resources>
        <ImageBrush x:Key="khsqImage" ImageSource="/images/appAccount.png" />
        <ImageBrush x:Key="firstImage1" ImageSource="/images/firstIn/1.jpg" />
        <ImageBrush x:Key="firstImage2" ImageSource="/images/firstIn/2.jpg" />
        <ImageBrush x:Key="firstImage3" ImageSource="/images/firstIn/3.jpg" />
        <ImageBrush x:Key="firstImage4" ImageSource="/images/firstIn/4.png" />
        <ImageBrush x:Key="ImageNavigate" ImageSource="/images/navigate.png" />
        <ImageBrush x:Key="MainNavigate" ImageSource="/images/MainNavigate.png" />
        <ImageBrush x:Key="GridImageBrush" ImageSource="/images/hds/backgroundBrown.jpg" />
        <ImageBrush x:Key="GridImageBrushWhite" ImageSource="/images/hds/backgroundWhite.jpg" />
    </Application.Resources>           

2、firstIn.xaml.cs中

其實就需在第一張圖檔和最後一張圖檔的ManipulationCompleted事件上進行操作。當第一張圖像左滑動時讓它重新加載這個頁面(要加一個參數,使其系統緩存無效)使其達到禁止向左滑動的效果;在最後一張圖向右滑動時就進入系統主界面。這樣就讓Pivot控件實作定向滑動不循環(這樣寫的有點偷巧)。

其實過程中想到了将this.pivotNews.IsHitTestVisible = false;通過TouchFrameEventHandler事件讓第一張圖向左滑動無效(IsHitTestVisible 為false),向右滑動啟動(值為true,但這樣需要滑動2次,使用者體驗不好);同理在操縱最後一張圖。過程坎坷啊!

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;

namespace HTClient
{
    public partial class firstIn : PhoneApplicationPage
    {
        public firstIn()
        {
            InitializeComponent();
            //觸控過程中位置變更時發生
            this.pivotNews.IsHitTestVisible = true;
           // Touch.FrameReported += new TouchFrameEventHandler(TouchFrameEventHandler);
        }


        //double firstX = 0.0;
        //double endX = 0.0;


        //public void TouchFrameEventHandler(object sender, TouchFrameEventArgs e)
        //{
        //    //Dispatcher.BeginInvoke(() =>
        //    //{
        //        try
        //        {
        //             //傳入null表明擷取到的觸控點資訊是以螢幕左上角為原點的。
        //            var primaryPoint = e.GetPrimaryTouchPoint(null);

        //            if (primaryPoint != null)
        //            {
        //                if (primaryPoint.Action == TouchAction.Down)
        //                {
        //                    firstX = primaryPoint.Position.X;
        //                }
        //                if (primaryPoint.Action == TouchAction.Up)
        //                {
        //                    endX = primaryPoint.Position.X;
        //                    double result = endX - firstX;
        //                    if (pivotNews.SelectedIndex == 0)
        //                    {
        //                        if (result > 0)
        //                        {
        //                            NavigationService.Navigate(new Uri("/firstIn.xaml", UriKind.Relative));
        //                            //pivotNews.IsHitTestVisible = false;
        //                        }
        //                        else
        //                        {
        //                            pivotNews.IsHitTestVisible = true;
        //                            
        //                        }
        //                    }
        //                    else if (pivotNews.SelectedIndex == 3)
        //                    {
        //                        if (result > 0)
        //                        {
        //                            pivotNews.IsHitTestVisible = true;
        //                        }
        //                    }
        //                    else
        //                    {
        //                            pivotNews.IsHitTestVisible = true;
        //                    }
        //                }

        //            }
        //        }
        //        catch
        //        {
        //            Touch.FrameReported -= new TouchFrameEventHandler(TouchFrameEventHandler);
        //        }
        //    //});
        //}

        private void firstIn_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
        }


        protected void pivotNews_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
        {
        }

        private void pivotNews_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
        }

        private void pivotNews_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
        }


        private void pivote1_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
        }

        private void pivote1_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
        {
        }

        private void pivote1_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            if (e.TotalManipulation.Translation.X > 0)
            {
                NavigationService.Navigate(new Uri("/firstIn.xaml?id=" + DateTime.Now.ToLongTimeString(), UriKind.Relative));
            }
        }



        private void pivote4_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
        }

        private void pivote4_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
        {
        }

        private void pivote4_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            if(e.TotalManipulation.Translation.X < 0)
            {
                NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
            }
        }
    }
}           

在網上看到一篇文章  Windows Phone 8 中Pivot和Panorama控件手勢監聽的變化  回答有人說可以将UseOptimizedManipulationRouting賦false,這樣就可以在pivotNews_ManipulationDelta上 操作了(在大多數情況下,您應該将保持将此屬性設定為 true。 通常您無需使用此屬性。 當您期望收到特定元素的 ManipulationDelta 事件但沒有收到時,您可能需要将此屬性設定為 false。)但我也會報錯 Can't set UseOptimizedManipulationRouting to false on the control。還有一種方法 pivotNews.AddHandler(Pivot.ManipulationDeltaEvent, new EventHandler<ManipulationDeltaEventArgs>(pivotNews_ManipulationDelta), true);試了以下也可以實作單向滑動的目的。

public firstIn()
        {
            InitializeComponent();
            //觸控過程中位置變更時發生
            pivotNews.AddHandler(Pivot.ManipulationDeltaEvent, new EventHandler<ManipulationDeltaEventArgs>(pivotNews_ManipulationDelta), true);
            //pivotNews.AddHandler(Pivot.ManipulationCompletedEvent, new EventHandler<ManipulationCompletedEventArgs>(pivotNews_ManipulationCompleted), true);
        }


        private void firstIn_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
        }


        protected void pivotNews_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
        {
            if (this.pivotNews.SelectedIndex == 0)
            {
                if (e.DeltaManipulation.Translation.X > 0)
                {
                    NavigationService.Navigate(new Uri("/firstIn.xaml?id=" + DateTime.Now.ToLongTimeString(), UriKind.Relative));            
                }                
            }
            if (this.pivotNews.SelectedIndex == 3)
            {
                if (e.DeltaManipulation.Translation.X < 0)
                {
                    NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));                
                }                
            }
        }

           

三、注意

由于系統首頁是從firstIn頁面過來的,關閉系統時也會經過firstIn,是以需要在離開MainPage時直接關閉系統

在App.xaml中

#region 退出程式
        private class QuitException : Exception { }
        public static void Quit()
        {
            throw new QuitException();
        }

        #endregion
        // Code to execute on Unhandled Exceptions
        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {

           if (e.ExceptionObject is QuitException)
                return;

            if (System.Diagnostics.Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
                System.Diagnostics.Debugger.Break();
            }


        }           

在MainPage.xaml中

protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
        {
            base.OnBackKeyPress(e);
            MessageBoxResult mbr = MessageBox.Show("是否确認要退出" + info.AppName + "?", "提示", MessageBoxButton.OKCancel);
            if (mbr == MessageBoxResult.Cancel)
            {
                e.Cancel = true;
            }
            else
            {
                App.Quit();
            }
        }           

這樣就直接離開了系統