天天看点

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();
            }
        }           

这样就直接离开了系统