zoukankan      html  css  js  c++  java
  • 干掉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、修改弹出框渐变动画效果

            

  • 相关阅读:
    Python 基于Python实现的ssh兼sftp客户端(上)
    lintcode: 最长连续序列
    lintcode:颜色分类
    lintcode: 堆化
    lintcode: 旋转图像
    lintcode: 寻找旋转排序数组中的最小值
    lintcode: 跳跃游戏 II
    lintcode:最小差
    华为:数独填充
    华为:字符集合
  • 原文地址:https://www.cnblogs.com/walleyekneel/p/3415010.html
Copyright © 2011-2022 走看看