先上效果圖
QQ退出效果 小弟控件效果圖
首先分析一下頁面結構,QQ圖中彈出框的組成:透明背景,文字背景,文字顏色
在wp上,小弟分別采用Popup控件,用戶控件(透明背景,文字背景用Border,顯示文字用BlockText)
不想賣關子,直接上代碼解析
哦,這里要說一下,這個類庫結構,Resource只要放資源文件,系統編譯時候會自動編譯進去dll里頭
1、用戶控件UI代碼,很簡單吧,主要注意一下Border設置一下CornerRadius圓角屬性
<UserControl x:Class="JM.Phone.Control.JMessboxControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" d:DesignHeight="480" d:DesignWidth="480"> <Grid x:Name="LayoutRoot" Width="480" Height="800"> <Grid.Background> <ImageBrush x:Name="layoutRootImage" ImageSource="/JM.Control;component/Resource/bg_transparent.png"></ImageBrush> </Grid.Background> <Border Height="65" Width="200" CornerRadius="2"> <Border.Background> <ImageBrush x:Name="textImage" ImageSource="/JM.Control;component/Resource/bg_tips.png"></ImageBrush> </Border.Background> <TextBlock Text="再按一次離開" FontSize="24" Height="35" TextAlignment="Center" Foreground="White"></TextBlock> </Border> </Grid> </UserControl>
2、用戶控件后台代碼也很簡單,定義2個屬性,方便以后擴展。。這里只能設置本地圖片。。當然你也可以拿到源代碼后,自己修改為網絡路徑圖片
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Navigation; using Microsoft.Phone.Controls; using Microsoft.Phone.Shell; using System.Windows.Media; using System.Windows.Media.Imaging; namespace JM.Phone.Control { public partial class JMessboxControl : UserControl { /// <summary> /// popup背景圖片 /// </summary> private string _layoutRootImage = "/JM.Phone.Control;component/Resource/bg_transparent.png"; public string LayoutRootImage { get { return _layoutRootImage; } set { _layoutRootImage = value; } } /// <summary> /// 文本背景 /// </summary> private string _textImage = "/JM.Phone.Control;component/Resource/bg_tips.png"; public string TextImage { get { return _textImage; } set { _textImage = value; } } public JMessboxControl() { InitializeComponent(); this.Loaded += JTipsControl_Loaded; } void JTipsControl_Loaded(object sender, RoutedEventArgs e) { layoutRootImage.ImageSource = SetSource(LayoutRootImage); textImage.ImageSource = SetSource(TextImage); } /// <summary> /// 設置圖片路徑 (針對相對路徑uri) /// </summary> /// <param name="uri"></param> /// <returns></returns> public ImageSource SetSource(string uri, UriKind rk = UriKind.Relative) { BitmapImage bit = new BitmapImage(); bit.UriSource = new Uri(uri, rk); return bit; } } }
3、調用方式在頁面重寫OnBackKeyPress方法,注意要引用這個控件dll
int clickCount = 0; protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e) { e.Cancel = true; //2s之內連續按2次,退出 if (clickCount > 0) { //WP7退出代碼(一般采用拋出異常退出) //throw new Exception(); //WP8退出代碼,用此行代碼,請將項目升級8.0項目
//Application.Current.Terminate()
} clickCount++; var tips = new JMessboxControl(); popup.Height = 800; popup.Width = 480; popup.IsOpen = false; popup.Child = tips; Storyboard story = new Storyboard(); DoubleAnimation topAnimation = new DoubleAnimation(); topAnimation.From = 0; topAnimation.To = 1; Storyboard.SetTarget(topAnimation, tips); Storyboard.SetTargetProperty(topAnimation, new PropertyPath("(UIElement.Opacity)")); popup.IsOpen = true; story.Begin(); story.Duration = new Duration(new TimeSpan(0, 0, 2)); story.Completed += (s1, e1) => { //2s后執行此方法 clickCount = 0; popup.IsOpen = false; story.Stop(); }; base.OnBackKeyPress(e); }
里面大概原理:
1、如果用戶在2s之內點擊后退按鈕2次,就當做是退出。。。
2、用一個動畫顯示此控件出來,動畫2s運行完后,執行Completed ,清除計數器並關閉Popup(這里也可以制作一個漸變隱藏動畫,小弟偷懶,就不貼代碼)
用着這個控件,頓時感覺我程序高端大氣上檔次啦
頓時想法,改進之后代碼
4、定義一個類,這個類主要作用給頁面調用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls.Primitives; using System.Windows.Media.Animation; namespace JM.Phone.Control { public class JMessBox { public Action<bool> Completed; Popup popup = new Popup(); //這里定義個靜態變量,避免每次初始化都變為0 //靜態變量,個人理解,只會初始化一次 static int clickCount = 0; public void Show() { //2s之內連續按2次,退出 if (clickCount > 0) { if (Completed != null) { Completed(true); } } else { clickCount++; if (Completed != null) { Completed(false); } var tips = new JMessboxControl(); popup.Height = 65; popup.Width = 200; popup.Margin = new Thickness(140, 380, 0, 0); popup.IsOpen = false; popup.Child = tips; //漸變效果:透明度200毫秒內從0->1 Storyboard story = new Storyboard(); DoubleAnimation topAnimation = new DoubleAnimation(); topAnimation.From = 0; topAnimation.To = 1; topAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(200)); Storyboard.SetTarget(topAnimation, tips); Storyboard.SetTargetProperty(topAnimation, new PropertyPath("(UIElement.Opacity)")); story.Children.Add(topAnimation); popup.IsOpen = true; story.Begin(); //動畫延遲2秒 story.Duration = new Duration(new TimeSpan(0, 0, 2)); //story.BeginTime = new TimeSpan(0, 0, 0, 0, 1); story.Completed += (s1, e1) => { //2s后執行此方法 clickCount = 0; popup.IsOpen = false; story.Stop(); }; } } } }
那么以上第三點改為這樣子調用
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e) { e.Cancel = true; JMessBox jb = new JMessBox(); jb.Completed += (b) => { if (b) { //WP7退出代碼 throw new Exception(); //WP8退出代碼 } }; jb.Show(); }
大牛請嘴下留情。。。。
要源代碼,猛擼這里。注意:項目是vs2012
2013-11-10修改
1、增加文字透明背景
2、修復彈出框,無法點擊頁面問題
2013-11-11修改
1、修改彈出框漸變動畫效果