【WP8.1】类似“IT之家” 自定义消息 的实现

曾经在WP7、WP8下的消息 使用的都是Coding4Fun.Phone.Toolkit里面的ToastPrompt类来实现的。

现在我们来自己做个类似IT之家的这种效果:从右边弹出,经过几秒后会自动消失。

首先明确几个需求:

1.在任何界面都能够弹出此消息

2.可以自定义消息的格式内容以及消息的消失时间

(包括是否含有标题、字体大小、排列...)

3.消息的提示与消失都有动画效果

一、取得当前页面上的某个Panel, 用于在此上面呈现消息:

ContentPresenter、Panel都是继承于 FrameWorkElement的

ContentPresenter: 只能容纳一个元素

继承于Panel 的控件是可以容纳多个子控件的,所以将消息显示在这个上面

        Panel popUpParentPanel; //消息在此Panel上弹出
        Frame RootVisualFrame;  //当前页面的可视根

        public Panel PopUpParentPanel
        {
            get
            {
                if (popUpParentPanel == null)
                {
                    IEnumerable<ContentPresenter> source = CommonHelper.GetVisualDescendants(this.RootVisualFrame).OfType<ContentPresenter>();  //获取所有ContentPresenter类型的子对象
                    for (int i = 0; i < source.Count<ContentPresenter>(); i++)
                    {
                        IEnumerable<Panel> enumerable2 = CommonHelper.GetVisualDescendants(source.ElementAt<ContentPresenter>(i)).OfType<Panel>();  //获取所有Panel类型的子对象
                        if (enumerable2.Count<Panel>() > 0)
                        {
                            this.popUpParentPanel = enumerable2.First<Panel>();  //选出第一个Panel
                            break;
                        }
                    }
                }
                return this.popUpParentPanel;
            }
        }

二、展示Show方法:

        bool bLocked;    //默认为false
        
        public void Show()
        {
            if (bLocked)
            {
                return;
            }
            InitControl();    //有关消息界面的代码略,详细请看后文给出的Demo
if (PopUpParentPanel != null) { //添加消息至Panel if (PopUpParentPanel is StackPanel) { PopUpParentPanel.Children.Insert(0, toastGrid); } else { PopUpParentPanel.Children.Add(toastGrid); } ShowStoryboard(); //开启动画 bLocked = true; } }

获取子元素相关静态类:

    public class CommonHelper
    {
        public static IEnumerable<DependencyObject> GetVisualChildren(DependencyObject element)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }
            return GetVisualChildrenAndSelfIterator(element).Skip<DependencyObject>(1);
        }

        public static IEnumerable<DependencyObject> GetVisualDescendants(DependencyObject element)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }
            return GetVisualDescendantsAndSelfIterator(element).Skip<DependencyObject>(1);  //去除元素本身
        }

        private static IEnumerable<DependencyObject> GetVisualDescendantsAndSelfIterator(DependencyObject element)
        {
            Queue<DependencyObject> iteratorVariable0 = new Queue<DependencyObject>();
            iteratorVariable0.Enqueue(element);
            while (true)
            {
                if (iteratorVariable0.Count <= 0)
                {
                    yield break;
                }
                DependencyObject iteratorVariable1 = iteratorVariable0.Dequeue();
                yield return iteratorVariable1;
                foreach (DependencyObject obj2 in GetVisualChildren(iteratorVariable1))
                {
                    iteratorVariable0.Enqueue(obj2);
                }
            }
        }

        private static IEnumerable<DependencyObject> GetVisualChildrenAndSelfIterator(DependencyObject element)
        {
            yield return element;
            int childrenCount = VisualTreeHelper.GetChildrenCount(element);
            int childIndex = 0;
            while (true)
            {
                if (childIndex >= childrenCount)
                {
                    yield break;
                }
                yield return VisualTreeHelper.GetChild(element, childIndex);
                childIndex++;
            }
        }
    }
View Code

三、显示消息动画效果以及添加消息显示完成事件:

 1 public event EventHandler<object> ToastShowComplated;  //消息显示完成事件   
 2 
 3 public void ShowStoryboard()
 4         {
 5             Storyboard sbShow = new Storyboard();
 6             sbShow.Completed += sbShow_Completed;  //动画完成后开始计时,时间到后消息消失
 7 
 8             //X轴方,向从消息界面一半处开始
 9             DoubleAnimation da = new DoubleAnimation() { From = toastGrid.Width / 2, To = 0, Duration = dua }; 
10             da.EasingFunction = new CircleEase() { EasingMode = EasingMode.EaseOut };
11             Storyboard.SetTarget(da, toastTransform);
12             Storyboard.SetTargetProperty(da, "TranslateTransform.X");   //绑定目标属性和以前有些区别
13             sbShow.Children.Add(da);
14 
15             //设置透明度从0变为1
16             DoubleAnimation da1 = new DoubleAnimation() { From = 0, To = 1, Duration = dua }; 
17             Storyboard.SetTarget(da1, toastGrid);
18             Storyboard.SetTargetProperty(da1, "FrameworkElement.Opacity");
19             sbShow.Children.Add(da1);
20 
21             sbShow.Begin(); //开始动画
22         }
23 void sbShow_Completed(object sender, object e)
24         {
25             IsShow = true;
26        //计时器开始
27             timer = new Timer(new TimerCallback(Time_Completed), null, this.TotalHiddenSeconds * 1000, 0);
28             if (this.ToastShowComplated != null)
29             {
30                 ToastShowComplated(this, e);
31             }
32         }
33 
34         async void Time_Completed(object e)
35         {
36             timer.Dispose();
37             await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
38             {
39                 HideStoryboard();
40             });
41         }

隐藏消息动画以及添加消息隐藏完成事件一样的。

四、使用该自定义消息:

private void btnToast_Click(object sender, RoutedEventArgs e)
        {
            CustomToast toast = new CustomToast() { Message = "这是展示的内容!" };
            toast.Show();
        }

右边是本篇随笔的Demo: CustomToastSample.rar

原文地址:https://www.cnblogs.com/yffswyf/p/4744830.html