干掉MessageBox,自定義彈出框JMessbox (WindowsPhone)


先上效果圖

 

                                               

 

              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、修改彈出框漸變動畫效果

 

 

        


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM