干掉MessageBox,自定义弹出框JMessbox (WindowsPhone)

先上效果图

 

                                               

 

              QQ退出效果                                                                                  小弟控件效果图

 

首先分析一下页面结构,QQ图中弹出框的组成:透明背景,文字背景,文字颜色

在wp上,小弟分别采用Popup控件,用户控件(透明背景,文字背景用Border,显示文字用BlockText)

 

不想卖关子,直接上代码解析

哦,这里要说一下,这个类库结构,Resource只要放资源文件,系统编译时候会自动编译进去dll里头

 

1、用户控件UI代码,很简单吧,主要注意一下Border设置一下CornerRadius圆角属性

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<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个属性,方便以后扩展。。这里只能设置本地图片。。当然你也可以拿到源代码后,自己修改为网络路径图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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、修改弹出框渐变动画效果

 

 

        

posted @   walleyekneel  阅读(2067)  评论(7编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示