zoukankan      html  css  js  c++  java
  • 【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

  • 相关阅读:
    POJ2182Lost Cows
    BZOJ4003: [JLOI2015]城池攻占
    POJ1635Subway tree systems
    BZOJ1005: [HNOI2008]明明的烦恼
    POJ1182 NOI2001 食物链
    栈的链式实现
    栈的数组实现
    链表ADT的实现
    #ifndef的用法
    using namespace std
  • 原文地址:https://www.cnblogs.com/yffswyf/p/4744830.html
Copyright © 2011-2022 走看看